• Start
Sign In

Authentication

Choose between a login session and a personal access token, store credentials safely, and authenticate an unattended run.

surrealctl accepts two kinds of credential. This page explains what each one is good for, how to create and inspect them, and how to hand one to a CI job. It is for anyone setting up their own machine, and for engineers wiring surrealctl into a pipeline.

The two credentials differ in what they can write, not in what they can reach.

CredentialHow you get itUse it forCloud writes
Login sessionsurrealctl auth loginEveryday work at a terminalYes
Personal access tokensurrealctl token create, or SurrealDB StudioScripts, CI jobs, shared runnersNo

A login session is the credential that can do everything. A personal access token reads the control plane and cannot change it, which is what makes it safe to leave in a CI secret store.

surrealctl auth login signs in through your identity provider and stores a refresh token plus one access token per audience. See Install for the three sign-in flows and when each is used.

Four commands inspect and maintain the session.

surrealctl auth status          # which credential is in use, read from disk
surrealctl auth status --verify # the same, plus one request to check it
surrealctl auth refresh         # renew now, rather than at the next request
surrealctl auth logout          # remove this profile's stored credentials

auth status and auth scopes touch no network, so they work on a plane, in a container with no egress, and in a CI job that is about to fail for another reason. whoami is the command that asks the API who you are.

auth status also warns when this machine's clock is more than five minutes out of step with the API, because a wrong clock produces authentication failures that look like a rejected credential.

auth logout revokes the refresh token at the identity provider on a best-effort basis. A failed revocation prints a warning and still removes the credential from this machine. Logging out when nothing is signed in succeeds and still prints a document, so a teardown script does not fail on its second run.

Note

auth scopes returns an empty list for a login session. Identity scopes are not the authorisation model for a session — your role in the organisation is. Run surrealctl org permissions to see what you may do.

A personal access token is a long-lived string beginning sdbp_. Create one with a login session in place, then hand it to whatever needs it.

surrealctl token scopes
surrealctl token create "ci-nightly-report" --scope read:cloud --expires-in 90 | tail -1

token create

NameDefaultDescription
<LABEL>
required
NoneWhat this token is for. Shown in every listing. 1 to 120 characters.
--scope<SCOPE>
NoneA scope to grant. Repeat the flag to grant several, up to 32.
--expires-in<DAYS>
30Days until the token expires, from 1 to 365, or never.
--reveal
NonePrint the secret even when stdout is a terminal.

Four things about token create are worth knowing before you run it.

  • The secret is returned once. It is the last line on stdout, so | tail -1 is the whole capture recipe. Nothing can recover it later.

  • It refuses to print a secret to a terminal. Pipe the output, or pass --reveal if you meant to read it. The check happens before the token is minted, so a forgotten flag never costs you a credential nobody can use.

  • It is the one command with no --json form. The secret can neither go inside the document nor share stdout with it, so --json is a usage error here.

  • A token with no --scope is permitted nothing. Grant what the job needs and no more.

List and revoke tokens by id or label.

surrealctl token list
surrealctl token delete ci-nightly-report
Warning

Revocation is not instant. A revoked token can continue to work for several minutes while the platform's exchange cache expires. Rotate a leaked token and then confirm with surrealctl token list.

It cannot manage personal access tokens. All four token verbs — list, create, delete, and scopes — refuse a personal access token. The refusal is local, costs no requests, and exits 4. A leaked token must not be able to mint its own replacements, nor revoke the one you would use to clean up after it.

Managing personal access tokens needs an interactive login session, so nothing was sent.

Sign in with:  surrealctl auth login

It cannot write to the control plane. The API refuses a personal access token on every mutating route, whatever scopes the token carries. instance create, instance delete, org update, and team invite all need a login session. Reads work normally.

It cannot exceed its scopes. A missing scope produces a 403 naming the scope, and exits 4.

Everything else works: org list, instance list, instance logs, auth status, auth scopes, and auth logout.

  • At a terminal, sign in. A login session covers every command and renews itself.

  • In CI, use a token for anything that only reads: nightly usage reports, drift checks, dashboards, alerting on instance state.

  • For unattended writes, use a login session on a dedicated machine account, with the credential file mounted into the job. Scope the account's role in the organisation to what the pipeline needs.

Two flags, each with an environment variable, and none of them writes the token to disk.

Credential options

NameEnvironment variableDescription
--token<TOKEN>
SURREALCTL_TOKENPersonal access token to authenticate with. Conflicts with --token-file.
--token-file<PATH>
SURREALCTL_TOKEN_FILERead the personal access token from a file, or - for stdin.

SURREALCTL_TOKEN is the usual choice in CI, because the environment is where a secret store puts things.

export SURREALCTL_TOKEN="$(cat /run/secrets/surrealctl)"
surrealctl instance list --json

--token has no short form on purpose: -t reads as --type on the instance commands, and a credential in argv is visible through ps and lands in shell history.

A credential supplied this way lasts for the one invocation. The only command that stores a token is auth login --with-token, which reads it from stdin and remembers it for the profile.

surrealctl auth login --with-token --label laptop < ~/token.txt

Five scopes exist: read:cloud, write:cloud-instances, write:cloud-organization, write:cloud-billing, and write:cloud-spectron.

Two commands report on them, and they answer different questions.

  • surrealctl token scopes — the catalogue of scopes a token can be granted. This one is the menu.

  • surrealctl auth scopes — what the credential in your hand carries. This one is the receipt.

A profile bundles a credential, an API base URL, and configuration under one name. Use profiles to keep a work account and a personal account apart, or production and staging.

surrealctl context use staging          # switch the active profile
surrealctl --profile staging auth login # sign that profile in
surrealctl context list                 # every profile, and which is active
surrealctl context show                 # what this invocation resolved, and why

Each profile stores its own credential, so switching profiles switches identity. surrealctl org use works within a profile and remembers an organisation; neither command is expressible as the other.

Credentials live in credentials.json, mode 0600, beside config.toml in the configuration directory described in Install. config.toml holds no secrets and is safe to commit.

surrealctl uses a file rather than the operating system keyring, deliberately. macOS keychain access is bound to the requesting binary's code signature, so a CLI re-prompts for permission after every upgrade — unanswerable inside a CI job. Headless Linux and containers have no secret service at all. There is no keyring backend.

Credential writes take an exclusive advisory lock and re-read under it, so two surrealctl processes racing to renew the same session cannot invalidate each other's tokens. Readers take no lock. If a run reports that another surrealctl is updating credentials, retry in a moment.

SymptomCauseResolution
Exit 3 on any commandNo credential, or one that expired and could not be renewedsurrealctl auth login, or surrealctl auth refresh
Exit 4 on a token commandA personal access token is in useSign in with a login session
Exit 4 on a writeInsufficient scope, insufficient role, or a token where a session is neededCheck surrealctl org permissions; use a login session for writes
auth status warns about clock skewThis machine's clock is more than five minutes outFix time synchronisation on the host
Exit 30An interactive sign-in did not completeRun surrealctl auth login again; add --flow device when there is no browser
Exit 11The credential store could not be read or writtenCheck the permissions and free space on the configuration directory
A refusal to read credentials.jsonThe file is readable by group or otherchmod 600 on the path in the message

To see which requests are being made and which configuration layer won each value, add --debug. Credentials are logged as a digest, never in full.

Was this page helpful?