Skip to content
Browse the docs

Concepts

Service tokens

Service tokens give CI pipelines and short-lived environments exactly the environments they need. How they're created, limited, bound to CI and revoked.

Last updated

On this page

A service token gives a CI pipeline or another short-lived environment access to the environments you choose. It looks like crunu_svc_… and goes into your CI's secrets as CRUNU_TOKEN. With it, crunu run signs in, verifies and decrypts everything inside its own process, without state files on disk.

Example. Kiteline is a fictional company. The token github-actions-web-app has access only to web-app / staging and is bound to the kiteline/web-app repository and the main branch.

How a token is made

An owner or admin creates the token entirely in their browser. The token contains the secret that its keys are derived from and the fingerprint of the organization signing key. The server receives only the token's public keys and the certificate the admin signed for it. That's why the token is shown only once: the server can't recover it.

Creating a token

On Service tokens, choose New token:

SettingWhat it does
NameHow the token appears in lists and in the audit log, for example github-actions-web-app.
EnvironmentsWhat the token can read, with a delivery method for each.
Lease durationFrom 1 hour to 30 days. The token stops working if it isn't used for longer than this.
NetworksOptional addresses the token may connect from.
Usage limitOptional: how many times the token may sign in, from 1 to 1,000,000. Leave empty for no limit.
CI binding (OIDC)Tick Add a CI binding (OIDC) right after creating to bind the token to a CI repository and branch.

The dialog warns you if the token would get access to a production environment.

After Create token, the app shows the token and a CI setup block with tabs for Bitbucket Pipelines, GitHub Actions and GitLab CI. It lists the variables to add to your CI, CRUNU_TOKEN marked as secret, and a Pipeline step example to copy. Done stays disabled until you tick I've saved the token.

Lease and usage

  • The lease is a window of inactivity. It starts when the token is created, and every sign-in extends it. A token used more often than its lease never expires. Choose a lease with room for pauses between pipeline runs: with 24 hours, a token created on Friday won't sign in on Monday.
  • Resuming. An expired token stays in the environments' access lists. An owner or admin can resume it.
  • Usage limit. One use is one successful sign-in. Renewing a lease or requests within an open session don't count. When the limit is reached, the token is refused like a revoked one, but it stays active: raising or removing the limit lets it sign in again. The count isn't reset.
  • Hard upper bound. The token's certificate is valid for at most about two years. The agent checks it.

Binding to CI

A token on its own works wherever it's presented. With a CI binding, it works only together with a JWT that GitHub Actions, GitLab CI, Bitbucket Pipelines or another OIDC issuer gave to a job of the right repository, branch or deployment environment. Each JWT can be used once. A token copied out of a build log is useless without it. See Bind a service token to CI with OIDC.

Production

A token gets exactly what it's granted. The key of an environment it isn't granted never reaches it, so a token for development can't decrypt production, even if it leaks.

The recommended setup keeps production out of CI: the production server runs the agent and fetches its own secrets, and the pipeline only restarts the service. When CI really needs production, use a separate token with a CI binding to the main branch and the production deployment environment.

Changing a token

Owners and admins can change a token's lease, networks and usage limit. Changing the networks or adding a CI binding ends the token's current sessions, so the next sign-in follows the new conditions. Renaming a token also reissues its certificate, because the name is part of it.

Revoking a token

On Service tokens, choose the token, then Revoke…. The next sign-in is refused. A pipeline step that is already running finishes with what it already received. Environment keys the token held are marked for rotation.

If a token may have leaked:

  1. Revoke it.
  2. Rotate the keys of the environments it had, see Rotate environment keys.
  3. Reissue the values inside those environments at their providers.
  4. Create a new token with the smallest grant and, if you can, a CI binding.

The token's page shows which versions of which environments it received and when. Treat those values as exposed.

Where the token is visible in CI

crunu run never passes CRUNU_TOKEN to the program it starts, and on Linux it closes its own process environment to other processes of the same user. Set the token only on the step that runs crunu, and start crunu with exec. A malicious dependency with root on the runner could still read it, so the real protection is a small grant. See Any CI with a service token.