# Service tokens

Service tokens are credentials for machines — CI jobs, Docker builds, Kubernetes workloads, and
agent sandboxes. Each is an independent principal **bound to one application environment**: that
binding selects the org, app, and environment it resolves at runtime, plus the group slices
composed into it. A token can be revoked on its own.

## How they work

A service token is self-contained: the token string carries its own private key. The server
stores only a **SHA-256 hash** of the token (to authenticate it) and its **public key** (to wrap
environment keys to it). This means a machine holding the token can unwrap any environment DEK
granted to it entirely offline — the server never had the token's private key.

Because tokens are generated on the client, the full token is shown **once** at creation. Copy it
then; it cannot be retrieved later.

## Creating a token

**In the web dashboard:** Organization → **Service tokens** → **Mint token**. Copy the `skt_…`
value from the one-time dialog.

**With the CLI**, bind the token to an application environment. Creation auto-grants that
environment's key **and** every group composed into it (at the matching slug):

```bash
seekrit token create --name ci-deploy --app storefront --env production
# prints:  skt_XXXXXXXX_...    (save it now)
```

To also authorize an alternate group slice for `run --with` overrides, add `--allow`:

```bash
seekrit token create --name dev --app storefront --env dev --allow auth-providers=staging
```

Pass `--no-grant` to mint the token without any grants, then grant environments explicitly:

```bash
seekrit token create --name ci-deploy --app storefront --env production --no-grant
seekrit grant --token skt_XXXXXXXX --app storefront --env production
```

## Admin tokens

By default a token holds **member**-level API access — its real power is the environment keys
wrapped to it. Pass `--admin` to mint an **org-scoped admin token** that also passes admin-gated
routes: creating apps, groups, and environments, composing groups, granting keys, and minting
further tokens. This is what lets automation and AI agents provision structure headlessly, with no
browser session.

```bash
seekrit token create --name agent-admin --admin
# org-scoped: no --app/--env needed
```

An admin token needs no environment binding to provision, but you can still bind one
(`--admin --app storefront --env production`) so it can both manage structure and decrypt that
environment. Only an admin caller (an admin user, or another admin token) may create an admin
token — capability never escalates itself. Scope admin tokens tightly and prefer a short lifetime.

## Using a token

Set it as `SEEKRIT_TOKEN`; it selects the org, app, and environment on its own:

```bash
export SEEKRIT_TOKEN=skt_XXXXXXXX_...
export SEEKRIT_API_URL=https://api.your-seekrit.example

seekrit export --format dotenv
seekrit run -- ./deploy.sh
```

Service tokens never need a passphrase — their private key is in the token string. A token can
only read or write the environments it was granted (its bound env + composed groups); it cannot
reach other environments in the org.

## Granting and revoking

Grants are per-environment. Grant a token from any environment's **Key access** panel, or with
`seekrit grant --token <id> --app <app> --env <env>`. When a token is retired:

```bash
seekrit token revoke skt_XXXXXXXX
```

Revocation stops the token from authenticating immediately. As with any principal, revoking the
grant doesn't rotate the key — see [Access & key grants](/docs/concepts/access-control#revocation-vs-rotation).

> **Warning:** Treat a service token like a password with decryption power. Scope it to only the environments it needs, store it in your platform's secret store (not in the repo), and rotate the environment key if a token leaks.

## Listing tokens

```bash
seekrit token list
```

Shows each token's id, name, status (active / expired / revoked), and last-used time.
