Account Keys
Account keys
An account key is an API key that belongs to the account, not to a person. It starts with nak_. Use one for CI and other automation: it keeps working when the person who created it leaves the account.
- One account. The key works only in the account it was created in. It never switches accounts.
- One role. It can do exactly what the role picked at creation allows (see Roles).
- Shown once. You see the key when you create it, and never again.
Manage them under Account → Account keys (/account/keys). The page needs your role's Members read permission.
Account key or API key?
| Account key | API key | |
|---|---|---|
| Starts with | nak_ | ngk_ |
| Belongs to | The account | You |
| Acts in | Its own account only | Your active account, in any of your accounts |
| Can do | What its role allows | What your role allows |
| When its creator leaves the account | Keeps working | No longer reaches that account |
| Created under | Account → Account keys | User settings → API keys |
Account keys
API keys that belong to this account, not to a person, for CI and other automation. Each one works only in this account, with the role it was given, and keeps working when people leave. Learn more →
| Name | Role | Key | Created by | Status | Actions |
|---|---|---|---|---|---|
|
GitHub Actions deploy
CI deploy · nak_…7Qx2
Expires Jan 31, 2027 · Used 2h ago
|
CI deploy | nak_…7Qx2 | Maria Example | Active | |
|
Status page sync
Read only · nak_…f3A9
No expiry · Never used
|
Read only | nak_…f3A9 | sam@example.com | Active | |
|
Nightly export
Admin · nak_…c41d
Expires Oct 12, 2026 · Used 3w ago
|
Admin | nak_…c41d | A former member | Expired |
Creating a key
The account owner can create keys, and so can members whose role has the Members write permission. A member can give a key only a role within their own permissions; the owner can give any role.
- Open Account → Account keys and click New account key, or pick Create → Account key in the top bar.
- Name it after what uses it, for example GitHub Actions deploy (up to 100 characters).
- Pick its Role. No suitable role? Create one under Account → Roles first.
- Choose when it Expires and, if you want, the Allowed IPs (see Expiry and allowed IPs).
- Click Create key, then Copy the key and store it, for example as a CI secret. The dialog stays open until you click Done; after that the key can't be shown again.
With the API, call POST /v1/account/keys from a dashboard session or with your own API key (ngk_). An account key can't create keys, and neither can an OAuth session such as the MCP server's browser sign-in.
curl -X POST "https://api.ngris.com/v1/account/keys" \
-H "X-API-KEY: $NGRIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "GitHub Actions deploy",
"role_uuid": "019a3f4c-77ab-7e10-b2d4-6c1e9f0a8d23",
"expires_in_days": 90
}'
{
"account_key": {
"uuid": "019a4e2f-6c1d-7b3a-9e52-3f8d1c7a2b40",
"name": "GitHub Actions deploy",
"role": {
"uuid": "019a3f4c-77ab-7e10-b2d4-6c1e9f0a8d23",
"name": "CI deploy"
},
"hint": "nak_…7Qx2",
"created_at": "2026-11-02T14:58:40Z",
"created_by": {
"uuid": "019a52c2-ca1e-78ba-ab5c-50362cc29134",
"name": "Maria Example"
},
"last_used_at": null,
"expires_at": "2027-01-31T14:58:40Z",
"allowed_ips": "",
"status": "active"
},
"key": "nak_XmCJcYSSlOAdprvxObx4WpVthF2O6Ov1h0oL7Qx2",
"notice": "Copy this key now. It won't be shown again."
}
Roles
A key does what its role allows, and nothing more. It uses the account's roles, the same ones members hold (see Named-role RBAC).
- Deploying from CI (the GitHub Action,
ngris deploy) needs a role with Endpoints read and write: apps and their deploys use the Endpoints permission. - Editing the role changes what the key can do from its next request.
- A role a key uses can't be deleted. Revoke the key first.
- A key keeps its role. To give it another one, create a new key with that role, then revoke the old key.
- Custom roles follow the plan: a key gets a custom role only while the plan includes custom roles, and a key on a custom role has no permissions while it doesn't. Keys on the built-in Admin role aren't affected.
Expiry and allowed IPs
Expiry. In the dashboard a new key expires in 90 days unless you pick Never, In 30 days, In 1 year or On a date… (up to 10 years ahead). With the API, send expires_in_days (1–3650) or expires_at; a key created without either never expires.
An expired key stops working: every request with it answers 401. It stays in the list as Expired until you revoke it, and it no longer counts toward the account's keys.
Allowed IPs. Optional: IPv4 or IPv6 addresses and CIDR ranges, separated by commas or new lines. A request from any other address answers 401. Leave it empty to allow any address.
Both are set when the key is created. To change them, create a new key, then revoke the old one.
curl -X POST "https://api.ngris.com/v1/account/keys" \
-H "X-API-KEY: $NGRIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Release pipeline",
"role_uuid": "019a3f4c-77ab-7e10-b2d4-6c1e9f0a8d23",
"expires_in_days": 365,
"allowed_ips": "203.0.113.10, 198.51.100.0/24"
}'
$ curl "https://api.ngris.com/v1/endpoints" -H "X-API-KEY: $NGRIS_API_KEY"
Invalid API Key
Using a key
Every request made with an account key acts in the key's account.
- REST API: send the key in the
X-API-KEYheader. - GitHub Actions: store it as the
NGRIS_API_KEYrepository secret for ngris-edge/deploy-action. - CLI: the app commands (
ngris deploy,ngris apps,ngris env) take it with--tokenor theAPI_TOKENenvironment variable (see Application hosting commands). - MCP server: send it as the bearer token (see Authentication: OAuth or API key).
- Tunnels (
ngris http,tcp,udp) log in with an agent token, not with an account key.
curl "https://api.ngris.com/v1/applications" \
-H "X-API-KEY: $NGRIS_API_KEY"
- uses: ngris-edge/deploy-action@v1
with:
# the account key (nak_…), a repository secret
api-key: ${{ secrets.NGRIS_API_KEY }}
build-command: npm ci && npm run build
dir: dist
# The account key from the CI secret store
export API_TOKEN="$NGRIS_API_KEY"
ngris deploy ./dist --app <app_uuid>
What stays with people
Whatever its role allows, an account key can't:
- use anything personal: a user's profile, email settings, sessions, two-factor sign-in, invitations, the accounts list or switching accounts;
- open billing: the subscription, invoices, payment methods and coupons, reads included;
- create, list or revoke credentials: API keys, agent tokens, agent keys or account keys, itself included (endpoint API keys are endpoint settings and follow the key's role);
- manage who has access: invite, remove or re-role members, revoke invitations, create, edit or delete roles, view or change single sign-on (SSO), upload KYC documents or change Iris autonomy settings;
- delete or leave the account, or transfer its ownership;
- link or unlink a GitHub identity or a GitHub App installation;
- sign in to the dashboard or open support tickets.
These requests answer 403 with the code account_key_not_allowed. Reading the members, invitations and roles works when the key's role allows it.
With the matching role, a key can request, attach and release dedicated IPs, and it can read the account's verification status and the list of requested KYC documents.
curl "https://api.ngris.com/v1/billing/subscription" \
-H "X-API-KEY: $NGRIS_API_KEY"
{
"code": "account_key_not_allowed",
"error": "Account keys can't use this endpoint."
}
Revoking a key
On Account → Account keys, open the key's … menu, choose Revoke and type REVOKE to confirm. Anything using the key stops working at once: its next request answers 401.
Anyone whose role has the Members delete permission can revoke any key, whoever created it. A revoked key leaves the list and can't be restored; the audit log keeps its name.
With the API: DELETE /v1/account/keys/{uuid}.
curl -X DELETE "https://api.ngris.com/v1/account/keys/019a4e2f-6c1d-7b3a-9e52-3f8d1c7a2b40" \
-H "X-API-KEY: $NGRIS_API_KEY"
How many keys
The account's plan sets whether it can have account keys and how many can be active at once. Revoked and expired keys don't count. When the account has as many as the plan allows, New account key is turned off until you revoke a key or upgrade.
If the plan later allows fewer keys than the account has, the newest keys over the count are paused once the grace period ends; if the plan no longer includes account keys, all of them are. A paused key answers 403 with the code account_key_paused. It works again on its own as soon as the account has room: revoke another key, or upgrade. The account owner gets an email when keys are paused and when they resume.
| Name | Role | Key | Status | Actions |
|---|---|---|---|---|
|
Release pipeline
CI deploy · nak_…9bK1
|
CI deploy | nak_…9bK1 | — | |
{
"code": "account_key_paused",
"error": "This account key is paused: the account has more account keys than its plan allows. Revoke a key or upgrade the plan."
}
In the audit log
What a key changes is recorded in the account's audit log under the key's name, with the member who created it: account key GitHub Actions deploy · created by maria@example.com. Once that member's user is deleted, the row reads created by a former member.
Creating and revoking a key are recorded under the person who did it, with the type Account key.
| When | Event | Type | User |
|---|---|---|---|
| 11/2/2026, 3:14:07 PM | Application deploy created | Application | account key GitHub Actions deploy · created by maria@example.com |
| 11/2/2026, 2:58:40 PM | Account key GitHub Actions deploy created with role CI deploy | Account key | maria |