Skip to content

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 login
Opening 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
FlagTypeDefaultDescription
--no-browserbooleanfalseSign 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>stringautoOverride the auth UI base URL (browser flow)
--api <url>stringautoOverride 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.at

auth logout ​

Disconnect the CLI by removing the stored session token.

bash
nkapp auth logout

auth status ​

Show the connected account. The stored token is validated against the API.

bash
nkapp auth status
Connected as jane.doe@example.com (plan: early)
  API: https://gateway.api.kama.nkapp.at
  Source: persisted in /home/jane/.nanokit/settings.json

Every 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_URL or from $NANOKIT_URL_API
  • persisted in <home>/.nanokit/settings.json
  • built-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 value
Account 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.json

After setting it, reload the Hub bridge so it picks the value up immediately:

bash
nkapp bridge --restart
InvocationDescription
auth apiRead-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 --clearRemove 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 ​

#SourceNotes
1NANOKIT_ACCOUNT_API_URLEnvironment variable; highest precedence
2NANOKIT_URL_APIEnvironment variable; the long-standing override (collides with a project service literally named api, which is why #1 exists)
3accountApiUrl in ~/.nanokit/settings.jsonThe persisted user setting (nkapp auth api, nkapp auth login --api)
4https://gateway.api.nanokit.devBuilt-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 -y

NANOKIT_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>
CommandDescription
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 login and auth logout replace 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-token result then carries persisted: 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, .env is 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), both 0600 and 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.