kisenon

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 (including keon) can present as a Bearer credential.

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-main credential. Hand this capability to AI agents so they operate against branches without ever touching production main. 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_seconds is optional and makes the rule self-expiring. A malformed CIDR returns 422.
  • 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:

  1. The CLI starts a local HTTP listener on a random high port.
  2. It opens your browser to https://kisenon.com/cli/authorize?... with a one-shot state token and the loopback redirect URL.
  3. You sign in (or are already signed in) and click Authorize.
  4. The console redirects to the loopback URL with a short-lived code.
  5. The CLI exchanges the code at POST /v1/cli/exchange for a freshly minted API key.
  6. The key is persisted at ~/.config/keon/credentials.json with mode 0600.

After the flow, keon whoami confirms the key is wired:

keon login
keon whoami

The 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 logout

Console 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/projects

The 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.

  • 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.