Authentication and profiles

Browser login with PKCE, headless login with a token, how the auth server is resolved, named profiles, environment variables for CI, and token lifecycle.

Browser login#

kelta auth login --url https://api.example.com --tenant acme --profile prod

The CLI starts a one-shot listener on 127.0.0.1, opens the browser for an OAuth authorization-code flow with PKCE against the tenant’s auth server (MFA and SSO work exactly as in the app), then uses the short-lived token once to mint a personal access token (--expires-in, default 90 days) and stores that. The JWT is discarded. --no-browser prints the URL for manual navigation.

Headless login#

kelta auth login --url https://api.example.com --tenant acme --token klt_...

Store a token you created in the app (Profile → API tokens) or one an administrator minted for a service user.

Finding the auth server#

The auth server is resolved as: the profile’s saved value → --auth-url → derive from the API host by replacing api. with auth.. On localhost the derivation does not apply, so pass --auth-url http://localhost:8081.

Profiles#

Connections are saved as named profiles: ~/.kelta/config.json (URL, tenant, auth URL) and ~/.kelta/credentials.json (tokens, mode 0600). KELTA_CONFIG_DIR relocates the directory.

kelta profile list
kelta profile use prod            # default profile
kelta profile show [name]
kelta profile rename old new
kelta profile remove name
kelta auth status --output json   # { "authenticated": true, "url": …, "tenant": … }

A sandbox is a separate tenant — log in to it as its own profile.

Which profile auth login writes#

kelta auth login writes the profile named by --profile (or KELTA_PROFILE); otherwise it writes the default profile. A login never silently replaces another tenant’s credential: without an explicit profile, a --tenant that differs from the default profile’s saved tenant is refused with exit 2 (PROFILE_TENANT_MISMATCH) before any browser flow starts, and nothing on disk changes.

kelta auth login --tenant other --token klt_...                    # refused: default is bound to acme
kelta auth login --tenant other --token klt_... --profile other    # writes a new "other" profile
kelta profile use other                                            # make it the default, if wanted

Re-logging in to the same tenant, a profile with no saved tenant yet, and any explicit --profile are written as asked. The output (and --output json → profile) names the profile that was written.

Precedence and CI#

Flags override environment variables, which override the profile file:

KELTA_URL=https://api.example.com KELTA_TENANT=acme KELTA_TOKEN=klt_... kelta collections list

No profile is needed in CI. KELTA_PROFILE selects a profile by name.

Tokens#

kelta token list
kelta token create --name ci --expires-in 30   # shown once
kelta token revoke <tokenId> --yes
kelta auth logout --revoke                     # revoke server-side, then forget locally
kelta users token-create <userId> --name feed  # administrator minting for a service user

A token has exactly its owner’s permissions — see Personal access tokens.

Errors#

Missing or expired credentials exit 3 with {"error":{"code":"AUTH_REQUIRED",…}}; a 403 from the API exits 1 with the JSON:API envelope.

Edit this page on GitHub