Auth
Sign-in, organizations, API keys, and the CLI loopback OAuth flow.
Kisenon has two ways to authenticate:
- Web sign-in — Google or GitHub OAuth via NextAuth on the console.
- API key — an
nsk_…token that any HTTP client (includingkeon) can present as aBearercredential.
The same key can drive the CLI, CI, and one-off curl calls.
Web sign-in
Open kisenon.com and click Sign in. Pick
Google or GitHub. NextAuth handles the OAuth dance, then exchanges the
provider's id token for a control-plane JWT via
POST /v1/auth/exchange. That cp-signed JWT is the credential every
subsequent console request carries.
The JWT is short-lived — it expires roughly 15 minutes after issue. While
you're active, NextAuth refreshes it in the background by re-presenting
the current JWT to POST /v1/auth/refresh, which mints a fresh one. The
refresh credential is the JWT itself, valid within a 12-hour window from
sign-in; once that window lapses, the next request redirects you to
sign-in.
Access
Sign in with Google or GitHub. When open signup is enabled, a new account is usable immediately: the first exchange creates your user and a personal organization, and you land straight in the console.
Access can be limited while we onboard — a kill-switch the operator can
flip per environment. When it is on, an account that has signed in but
isn't yet enabled lands in a pending state: the console redirects it
to /pending, and the control plane answers gated API calls with
403 alpha_pending until the account is enabled. A configured sign-in
allowlist can also reject a non-listed account with 403 email_not_allowed
before any session is issued.
Organizations and roles
Identity is organization-first. Every session carries an active
organization and your role in it (for example owner or
member); the cp JWT encodes both, and the control plane re-reads your
role on each refresh. Personal sign-ups get a personal organization
automatically; invited users land in the team organization on first
sign-in.
If you belong to more than one organization, the organization
switcher in the console (top of the signed-in layout) lists them with
a role badge. Picking one POSTs to /api/auth/switch-org, which proxies
to cp's /v1/auth/switch-org and splices a fresh JWT — scoped to the new
organization — into your session. All console requests after the switch
act in the selected organization.
See Organizations for how organizations and roles work, and Invitations for adding teammates.
API keys
API keys are nsk_-prefixed credentials. Each key:
- Carries the format
nsk_<random>and is shown once at creation — it is hashed at rest, so we cannot recover the plaintext later. Save it now or rotate it. - Acts with your identity inside its scope.
- Can be revoked at any time without affecting other keys.
Minting a key from the console
Mint keys at Settings → API keys. Each row shows the key's name, id, the creation date, and when it was last used. The create form has four fields:
- Name — a label, up to 64 characters.
- Capability — see below.
- Scope — see below.
- Expires (days) — leave blank for a key that never expires.
Submit, and the secret is revealed once. Copy it before you close the dialog.
Capability picks what the key may do:
read_write(default) — full read and write.read— read-only; refused on any mutating call.agent— can drive sandboxes but cannot fetch a writable-maincredential. Hand this capability to AI agents so they operate against branches without ever touching productionmain. See Agent-Safe Change Control.
Scope picks what the key can reach:
- Organization (default) — everything in the active organization.
- A specific project — restricted to that project; requests for any
other resource get
403 scope_insufficient. (Branch scope is also supported via the API.)
Creating a key requires a signed-in browser session — an nsk_ key
cannot mint another key. A key can revoke itself, but an nsk_
bearer can only self-revoke; it cannot delete other keys.
Via the API
The same operations are available on cp's /v1/api-keys/ endpoint: POST
a name, scope, and capability to create, and the response carries
the plaintext secret once.
IP allowlist
Each project can carry a network allowlist of CIDRs. When the list is set, only connections originating from a listed CIDR reach the project's endpoints; enforcement covers the wake path, so an unlisted client can't wake a suspended endpoint either. An empty allowlist means no IP restriction — all sources are allowed.
Manage the list from the CLI:
keon ip-allow add 203.0.113.0/24 --project prj_abc...
keon ip-allow list --project prj_abc...
keon ip-allow remove 203.0.113.0/24 --project prj_abc...Or over the API:
GET /v1/projects/{projectId}/ip-allow— list the current rules.POST /v1/projects/{projectId}/ip-allow— add a rule. Body is{cidr, label, ttl_seconds?};ttl_secondsis optional and makes the rule self-expiring. A malformed CIDR returns422.DELETE /v1/projects/{projectId}/ip-allow/{cidr}— remove one rule.DELETE /v1/projects/{projectId}/ip-allow— reset the whole list.
Enforcement is at the proxy, which refreshes its view about every 30 seconds, so a change propagates within seconds.
CLI loopback OAuth
keon login does not ask you to paste an API key. Instead it runs a
loopback OAuth flow:
- The CLI starts a local HTTP listener on a random high port.
- It opens your browser to
https://kisenon.com/cli/authorize?...with a one-shot state token and the loopback redirect URL. - You sign in (or are already signed in) and click Authorize.
- The console redirects to the loopback URL with a short-lived code.
- The CLI exchanges the code at
POST /v1/cli/exchangefor a freshly minted API key. - The key is persisted at
~/.config/keon/credentials.jsonwith mode0600.
After the flow, keon whoami confirms the key is wired:
keon login
keon whoamiThe CLI does not store the OAuth code, the state, or any provider-side token; only the resulting API key. Rotate or revoke that key from the console at any time.
Logout
keon logout revokes the local API key on the server and removes the
credentials file. After logout, the same keon login flow mints a
new key — old credentials cannot be reactivated.
keon logoutConsole sign-out clears the browser session and redirects to the landing page; it does not revoke API keys you minted via the CLI. Use Settings → API keys to revoke those individually.
Bearer auth from arbitrary clients
Any client that speaks HTTP can hit the control plane:
curl -H "Authorization: Bearer $KISENON_API_KEY" \
https://api.kisenon.com/v1/projectsThe bearer token is either an API key (nsk_…) or a cp-signed JWT
issued via /v1/auth/exchange. Both are equivalent for organization-scoped
endpoints.
Related
- Organizations — organizations, roles, and switching.
- Invitations — add teammates to an organization.
- CLI — install, login, common commands.
- Security — disclosure policy.
- FAQ — short answers to the most-asked questions.