Appearance
nkapp auth
Connect this CLI to your Nanokit account (the SaaS identity, "who you are"). The session token is stored globally in ~/.nanokit/hub-token.json and shared by every project on the machine. It is the same token the Hub bridge uses.
bash
nkapp auth <subcommand> [options]Looking for cloud provider credentials (AWS, GCP, Azure, DigitalOcean, Cloudflare)? Those live on a separate axis, "where you deploy". See
nkapp provider auth.
Subcommands
auth login
Authenticate with your Nanokit account. By default this opens your browser to the Nanokit auth page and signs you in there (email/password, OAuth, passkey, MFA, all handled by the web flow). The CLI runs a temporary loopback listener on 127.0.0.1; after a successful sign-in the auth page redirects back to it, the browser shows a success (or error) page, and the session token is captured and stored. No credentials are typed into the terminal.
bash
nkapp auth loginOpening your browser to sign in to Nanokit...
If it doesn't open automatically, visit:
https://auth.nanokit.dev/login?redirect=http://127.0.0.1:54312/callback?state=...
✔ Connected as jane.doe@example.com (plan: pro).For headless environments (CI, a remote shell with no browser), use the terminal flow or a pre-issued token:
bash
nkapp auth login --no-browser # prompt for email + password (+ MFA)
nkapp auth login --token <jwt> # store a session token directly| Flag | Type | Default | Description |
|---|---|---|---|
--no-browser | boolean | false | Sign in with email/password in the terminal instead of the browser |
--token <jwt> | string | — | Store an existing session token, no sign-in |
--email <email> | string | — | Account email (terminal flow; skips the prompt) |
--password <password> | string | — | Account password (terminal flow; skips the prompt) |
--auth-url <url> | string | auto | Override the auth UI base URL (browser flow) |
--api <url> | string | auto | Override the API base URL (persisted on success) |
On success the token is written to ~/.nanokit/hub-token.json (mode 0600).
--api <url> applies to both the browser and the terminal flow. When the login succeeds, the URL is also persisted to ~/.nanokit/settings.json (see auth api), so the next command, and the Hub bridge, reach the same deployment without the flag. It is persisted only when you pass --api explicitly and only on success; an environment variable is never captured into the file.
bash
nkapp auth login --api https://gateway.api.kama.nkapp.atauth logout
Disconnect the CLI by removing the stored session token.
bash
nkapp auth logoutauth status
Show the connected account. The stored token is validated against the API.
bash
nkapp auth statusConnected as jane.doe@example.com (plan: early)
API: https://gateway.api.kama.nkapp.at
Source: persisted in /home/jane/.nanokit/settings.jsonEvery outcome (connected, invalid session, HTTP error, unreachable) prints the API base URL it used and where that value came from. The source line is one of:
from $NANOKIT_ACCOUNT_API_URLorfrom $NANOKIT_URL_APIpersisted in <home>/.nanokit/settings.jsonbuilt-in default (nothing configured)
When the resolved URL is still the built-in default, auth status also notes that the default does not resolve and points you at nkapp auth api <url>.
If no token is stored, the command tells you to run nkapp auth login.
auth api
Show, set or clear the account API base URL: the deployment your Nanokit account lives on. The value is persisted in ~/.nanokit/settings.json, which both the CLI and the Hub bridge read.
bash
nkapp auth api [url] [--clear]The built-in default, https://gateway.api.nanokit.dev, does not resolve today because Nanokit's hosted control plane is not published yet. Until it is, point the CLI at the deployment your account lives on once, and it is remembered.
bash
nkapp auth api # show (writes nothing)
nkapp auth api https://gateway.api.kama.nkapp.at # persist
nkapp auth api --clear # remove the persisted valueAccount API: https://gateway.api.kama.nkapp.at
Source: persisted in /home/jane/.nanokit/settings.json
Persisted: https://gateway.api.kama.nkapp.at
Settings: /home/jane/.nanokit/settings.jsonAfter setting it, reload the Hub bridge so it picks the value up immediately:
bash
nkapp bridge --restart| Invocation | Description |
|---|---|
auth api | Read-only. Prints the resolved URL, which precedence slot it came from, the persisted value and the settings file path |
auth api <url> | Validate and persist the URL. It must be an absolute http(s) URL; anything else is a hard error and nothing is written |
auth api --clear | Remove the persisted URL (resolution falls back to the built-in default). A no-op that says so when nothing is persisted |
If an environment variable is currently winning, auth api <url> says so: the value is persisted but will not take effect until that variable is unset.
Resolution order
| # | Source | Notes |
|---|---|---|
| 1 | NANOKIT_ACCOUNT_API_URL | Environment variable; highest precedence |
| 2 | NANOKIT_URL_API | Environment variable; the long-standing override (collides with a project service literally named api, which is why #1 exists) |
| 3 | accountApiUrl in ~/.nanokit/settings.json | The persisted user setting (nkapp auth api, nkapp auth login --api) |
| 4 | https://gateway.api.nanokit.dev | Built-in fallback; does not resolve today |
With nothing persisted and no environment variable set, behaviour is unchanged.
CI and headless environments
No browser and no interactive prompt? Provide the token through the environment instead of logging in. nkapp auth status, nkapp up, and nkapp deploy all read it:
bash
export NANOKIT_TOKEN="<session-or-api-token>"
nkapp deploy -e production -yNANOKIT_TOKEN (alias NANOKIT_HUB_TOKEN) takes precedence over the stored file and nothing is written to disk. For CI, generate a long-lived, revocable token from the dashboard (Account → API Keys) rather than reusing your interactive session token, then set it as NANOKIT_TOKEN. Cloud provider credentials follow the same pattern via their standard env vars (AWS_ACCESS_KEY_ID, DIGITALOCEAN_TOKEN, GOOGLE_APPLICATION_CREDENTIALS, AZURE_CLIENT_ID/AZURE_CLIENT_SECRET/AZURE_TENANT_ID, CLOUDFLARE_API_TOKEN), which take precedence over .nanokit/auth.json. See nkapp provider auth.
Managing API keys from the CLI
You can mint and manage API keys without leaving the terminal (the same keys shown under Account → API Keys). You must be logged in (nkapp auth login).
bash
nkapp auth token create "github-actions" --expires 90 # prints the secret once
nkapp auth token list # metadata only
nkapp auth token revoke <id>| Command | Description |
|---|---|
auth token create <name> [--expires <days>] [--api <url>] | Create a key; the secret is printed once |
auth token list [--api <url>] | List your keys (prefix, name, expiry, last used) |
auth token revoke <id> [--api <url>] | Revoke a key by id |
Put the created secret in CI as NANOKIT_TOKEN.
Settings file
The persisted account API URL lives in ~/.nanokit/settings.json (file mode 0600), next to hub-token.json:
json
{
"version": 1,
"accountApiUrl": "https://gateway.api.kama.nkapp.at"
}Unknown keys are preserved on write, and a single malformed field is treated as unset without discarding the rest of the file. accountApiUrl must be an absolute http(s) URL. Nothing secret is stored here: the account token stays in hub-token.json and provider credentials in .nanokit/auth.json.
The Hub bridge runs in a container that does not inherit your shell environment, but it mounts ~/.nanokit, so the persisted setting reaches it automatically and survives container recreates. This is what lets the Hub connect to remote environments without exporting a variable into the bridge.
Token Storage
The account credential is stored globally at ~/.nanokit/hub-token.json (file mode 0600), not per project. This is the same location the Hub bridge reads, so logging in via the CLI and via the Hub keep the operator's machine in a single, consistent session. Alongside the token, the file records what kind of credential it is and which write put it there:
json
{
"token": "<session jwt or nk_ api key>",
"kind": "api-key",
"source": "cli-login",
"updatedAt": "2026-10-14T10:30:53.664Z"
}A file written by an older CLI holds only token and keeps working unchanged.
A stored API key is never replaced by a background write
The file can hold either a session JWT (short-lived, from a login) or a long-lived API key (nk_… from nkapp auth token create, stored with nkapp auth login --token nk_… so that remote deploy needs no interactive login). Only the first is disposable, so:
auth loginandauth logoutreplace anything. An explicit command is an explicit instruction.- Signing in to the Hub UI replaces only a session. The Hub hands its session to your local bridge on every reconnect, not just at sign-in. If your CLI holds an API key, that sync is a logged no-op and your key stays — the Hub's
sync-auth-tokenresult then carriespersisted: false.
A credential whose shape Nanokit does not recognize is protected the same way: if you put it there by hand, it was deliberate.
NANOKIT_TOKEN (or NANOKIT_HUB_TOKEN) in the environment still wins over the file on every read and is never persisted — that remains the way to pin a credential for CI or for a single shell.
Important. Credentials are never written to
.env. In Nanokit,.envis injected into every remote host and container on deploy, so storing operator tokens or cloud keys there would ship them to production. They live only in~/.nanokit(account) and.nanokit/auth.json(providers), both0600and git-ignored, and neither is included in the deploy payload.
Important. This is your account identity, used to talk to the Nanokit backend (Hub, deployments registry). It is distinct from cloud provider credentials (
nkapp provider auth), which are project-scoped and used to provision infrastructure.