API KEY SCOPING
Swamp provides two types of API keys — personal keys and collective tokens — because personal identity and collective identity serve different purposes.
Why two types exist
A personal API key is tied to your user account. When you authenticate with one,
the system knows who you are — your username, your roles, your collective
memberships. This is how the CLI works: swamp auth login creates a personal
key, and every command you run executes as you.
A collective API token is tied to an organization, not a person. When you authenticate with one, the system knows which collective is acting — but not which person. The request is attributed to the collective itself.
The isolation boundary
This distinction is deliberate. The two key types are verified through entirely separate paths and grant different levels of access. A collective token cannot do anything a user can do — it can only do things the collective can do. And a personal key cannot impersonate a collective without the user actually being a member.
The boundary runs both ways, which is the point. Neither type can escalate into the other's scope.
When to use personal keys
Personal keys are the right choice for interactive work and personal automation:
- CLI usage —
swamp auth loginhandles this automatically - Personal scripts — a cron job that pushes your extensions, a bot that monitors your issues
- Development — local tooling that needs to call the Swamp API as you
The tradeoff is that personal keys carry your full permissions. If one leaks, the attacker operates as you across all your collectives.
When to use collective tokens
Collective tokens are the right choice for shared infrastructure:
- CI/CD pipelines — a GitHub Actions workflow that publishes extensions under the collective's namespace after tests pass
- Shared tooling — a deployment script that multiple team members run but that should authenticate as the team, not as whoever last logged in
- Service accounts — bots or integrations that act on behalf of the collective
The key advantage is personnel independence. If someone leaves the team and their personal key is revoked, the collective's CI pipeline keeps working. Collective tokens also make audit trails cleaner — actions show up as the collective, not as whichever team member happened to configure the pipeline.
The tradeoff is narrower scope. Collective tokens can only perform operations their granted scopes allow, and they are scoped to the single collective that created them.
Rotating service tokens without a person
A token that never expires and is never rotated is a long-lived secret. A
service can instead rotate its own credentials: an owner or admin creates one
token with tokens:mint, and the service uses it to mint short-lived tokens for
its workers, then revokes each one as it replaces it. With the minting token as
SWAMP_API_KEY, a worker token is
swamp auth token create --collective <slug> --scopes serve:* --ttl 7d, and
swamp auth token revoke retires the old one.
Minting is a separate scope because a token that can create tokens is more
powerful than the work it was given. Holding oauth:manage or serve:* grants
no minting; only tokens:mint, granted by name, does. The server keeps the
minted tokens weaker than their parent: they hold only scopes the parent holds,
they always expire, and they cannot mint. So a leaked worker key stops working
at its expiry and cannot widen its access. Its
signin token carries no expiry of its
own, though, so revoke a leaked worker token rather than wait it out. The
minting token is the secret to guard closely, and revoking it revokes every
token it minted. The rules are listed under
Minting.
Why team features need scopes
Every Swamp command needs a swamp-club.com account, including those that only touch the local machine — see Swamp Account Requirement. Being signed in answers who is running Swamp. Scopes answer a second question: what a collective token is allowed to do.
That second question matters most for features that cross from single-machine
use into shared team state. An external datastore, a non-local vault, or a
network-accessible serve instance affects resources that several team members
rely on. A personal key can configure them because it identifies the operative
doing it. A collective token can configure them only if it was created with the
matching scope (datastore:*, vault:*, serve:*).
Collective token scopes follow a two-tier model. Categories where operations
carry meaningfully different blast radii have fine-grained scopes — for
example, extensions:push, extensions:promote, extensions:read, and
extensions:lifecycle let a CI token follow least-privilege by granting only
what the pipeline actually needs. Categories where the capability is binary —
you either run a serve instance or you don't — use a single category-level
wildcard like serve:*, datastore:*, or vault:*.
Each fine-grained category also supports a wildcard (extensions:*, lab:*,
profile:*, etc.) that expands to all scopes within that category. This keeps
broad tokens simple while letting teams that care about least-privilege narrow
down to exactly the operations their workflow requires.
Personal keys carry all scopes implicitly because a personal key already represents a fully identified operative — the authentication is the accountability. Collective tokens require explicit scopes because they strip away the individual identity, so the scope declaration serves as an intentional statement of what the token is for.
Signin tokens and collective tokens
A collective token comes with a second value, the signin token. The API key is the credential; the signin token is a proof, signed by swamp-club, that the key was valid when it was issued. It names the collective and the token's scopes and is bound to the key's fingerprint, so it is worthless with any other key.
The two values are related in a few fixed ways:
- swamp-club issues the signin token only when the collective token is created, and shows it once. It cannot be issued again for an existing key.
- It does not expire on its own. Revoking the collective token invalidates it: Swamp checks the key at most once an hour and blocks a revoked one.
- Rotating the key means a new collective token, and with it a new signin token. An old signin token never matches a new key.
With the signin token set as SWAMP_SIGNIN_TOKEN, CI and containers run while
swamp-club.com is unreachable. Personal keys have no signin token.
Swamp Account Requirement
lists its properties.
Choosing between them
A useful rule of thumb: if the operation is something you are doing, use a
personal key. If the operation is something the team is doing, use a
collective token. When in doubt, start with your personal key via
swamp auth login — you can always move to a collective token later when the
workflow matures.