Authentication

Sign in to a control plane, check your session, and create API tokens.

A device signs in to one control plane at a time, and the CLI calls that control plane an origin. Signing in again to the same control plane refreshes the session. Signing in to a different one is refused until you run rl auth logout. The auth commands sign you in and out, report your session, and create bearer tokens for the HTTP API.

rl auth status

Show who you are, the control plane you are signed in to, and whether the daemon is running. It still answers when the control plane cannot be reached. When the daemon has found a newer client, it adds a line saying so.

rl auth status
rl auth status -o json        # adds daemon health + per-origin details
rl auth status --show-access  # what you're allowed to do at each origin
FlagDescription
--home <dir>Data directory.
-o, --output <format>text (default) or json (adds daemon health + per-origin user/version/token-expiry/reachability).
--show-accessFor each logged-in origin, also report your effective access: cluster-wide grants plus per-namespace permissions.
--no-probeAnswer from local state only, with no reachability, backend version or session-expiry check. In -o json, reachable and needsReauth then read false, because they are unknown.

When a session expires

A session started with the interactive rl auth login lasts 90 days from the time you sign in, however often it renews. Until then it renews itself in the background, so you stay signed in without noticing. Occasionally it cannot renew, usually after a laptop has been asleep for a long stretch, and the session ends early. Either way, signing in again is the only fix.

To see when your session ends, read sessionExpiresAt on the origin in rl auth status -o json. The accessExpiresAt beside it is the current access token, which renews on its own. The Ringleader desktop app starts warning you seven days before the session ends.

Once a session has ended, rl auth status says so, and names the command to run:

Origins:
  cp1                https://cp.example.com                  logged in  alice@example.com
             warning: session expired: sign in again: rl auth login https://cp.example.com

In -o json, the origin carries "needsReauth": true.

Every other command that reads from that origin reports the same thing rather than a generic failure:

warning: origin "cp1": session expired or not authenticated; run `rl auth login https://cp.example.com`

The macOS app and the Windows tray show a Session expired notice with a Sign in again button that reruns the login against that origin.

An unreachable origin is a different, transient thing and never prompts you to sign in again; nor does a permission denial, which re-authenticating would not fix.

rl auth login [url]

Register a control plane as a federated origin. By default this runs an interactive device-code flow and stores access + refresh tokens. With no URL, it signs in to https://app.ringleader.dev.

# Interactive device-code login to Ringleader's own control plane.
rl auth login

# The same, against another control plane.
rl auth login https://your-control-plane.example.com

# CI, with no stored secret: become a service account by exchanging
# the job's own workload identity.
rl auth login https://cp.example.com \
    --service-account dev/ci --provider acmecorp-github

# Non-interactive with a static bearer token.
rl auth login https://cp.example.com --token "$RL_TOKEN" --name ci

# Loopback / unauthenticated control plane.
rl auth login http://127.0.0.1:8080 --anonymous
FlagDescription
--name <name>Local name for this origin (default: an existing origin already bound to this URL, else the name the control plane advertises, else derived from the URL host).
--token <token>Static bearer token, used instead of the interactive login. It needs an explicit URL, so a token is never sent to the default control plane.
--anonymousRegister with no credential.
--service-account <ns>/<name>Log in as a service account by exchanging this job’s own workload identity, with no stored secret. Requires --provider.
--provider <name>The identity provider to exchange against. Required with --service-account.
--audience <value>The audience to request the workload identity token for. Defaults to the audience the control plane advertises for itself, so you normally never set this.
--register-nodeOn a service-account login, through --service-account or --token, also register this device’s node identity. Off by default.
-o, --output <format>text (default) or json (streams newline-delimited events).
--home <dir>Data directory.

--service-account works only where something can prove who the process is. That means one of these:

  • A GitHub Actions job with permissions: {id-token: write}.
  • A host running a SPIRE agent that has a registration entry for the process.
  • A Ringleader workstation that holds the sa:assume capability.

On a laptop there is nothing to exchange. See ServiceAccount for the objects it needs.

rl auth logout [origin-name]

Remove a federated control plane by its local name. With no name, it logs out of your only origin, and asks you to name one when you have several.

Before it removes the origin, logout copies the WorkstationConfigs and Grants you own there back to this device. Objects other people own stay on the control plane. A login made with --anonymous, or with a --token that names no user, has no known identity. Nothing is copied back then, and logout prints a warning.

When the control plane is down or refuses your login, logout cannot read your objects there. It copies none of them, prints a warning, and removes the origin anyway. When it can read only one of the two kinds, it copies that one. The warning then names the kind it could not read, for example logout: warning: could not read your grants from origin "ci", so none were copied to this device.

rl auth logout ci
FlagDescription
--home <dir>Data directory.

rl auth token

Create a bearer token for the HTTP API, signed with the data directory’s signing key. A daemon started from the same data directory with --addr accepts it. With no --as, the token is for the current user.

rl auth token                       # current user, 1h
rl auth token --as sa:dev/builder --ttl 24h
FlagDescription
--as <subject>Subject to issue for (e.g. user:alice, sa:dev/builder).
--ttl <duration>Token lifetime (default 1h; e.g. 15m, 24h).
--home <dir>Data directory.