ACCESS COMMANDS
swamp access
Manage authorization policies (grants), groups, and access checks.
Subcommands
| Command | Alias | Description |
|---|---|---|
token |
Manage server tokens for user authentication | |
grant |
policy |
Manage authorization grants |
group |
Manage local and IdP groups | |
can-i |
Check your own permissions against the server's grants | |
check |
Explain whether a subject can perform an action | |
reload |
Rebuild the policy snapshot from current grants and groups |
Token resolution
All --server subcommands resolve authentication credentials in this order:
--tokenflag orSWAMP_SERVER_TOKENenvironment variable — an inline<name>.<secret>credential.--token-fileflag orSWAMP_SERVER_TOKEN_FILEenvironment variable — a path to a file containing the<name>.<secret>credential.- Stored credential from a previous
swamp auth server-login.
The first source that provides a value wins. When using --token-file, the file
must contain the bare credential string with no surrounding whitespace or
newlines.
swamp access token
swamp access token mint
Mint a server token for user authentication. The token secret is always stored
in the _token-secrets control-plane vault and can be retrieved with
swamp access token reveal. With a datastore that provides a control plane, the
control-plane vault is kept in the datastore; otherwise it is kept in the
repository's local control plane.
swamp access token mint <name> --principal <principal>| Flag | Required | Default | Description |
|---|---|---|---|
--principal |
Yes | Principal the token authenticates as: user:<id> or worker:<id> (e.g., user:adam). Other kinds, a value without :, and an empty id are rejected |
|
--email |
No | Display email for the token holder | |
--duration |
No | 30d |
Token lifetime (e.g., 30m, 1h, 24h, 7d) |
--server |
No | Target a remote server (env: SWAMP_SERVE_URL) |
|
--token |
No | Server token (falls back to stored credential) | |
--token-file |
No | Token file path (env: SWAMP_SERVER_TOKEN_FILE) |
--principal is validated before minting, locally and through swamp serve:
Error: Invalid --principal value "agent:x": Invalid principal kind "agent": expected "user" or "worker"
Error: Invalid --principal value "adam": Invalid principal "adam": expected "user:<id>" or "worker:<id>"
Error: Invalid --principal value "user:": Invalid principal "user:": id cannot be emptymint has no --vault option; passing one fails with
Unknown option "--vault". To keep a copy of the credential in another vault,
see Shared-vault handoff.
swamp access token list
List server tokens: state, principal, expiry, and last use.
swamp access token list| Flag | Required | Default | Description |
|---|---|---|---|
--server |
No | Target a remote server (env: SWAMP_SERVE_URL) |
|
--token |
No | Server token (falls back to stored credential) | |
--token-file |
No | Token file path (env: SWAMP_SERVER_TOKEN_FILE) |
swamp access token revoke
Invalidate a server token before it expires.
swamp access token revoke <name>| Flag | Required | Default | Description |
|---|---|---|---|
--server |
No | Target a remote server (env: SWAMP_SERVE_URL) |
|
--token |
No | Server token (falls back to stored credential) | |
--token-file |
No | Token file path (env: SWAMP_SERVER_TOKEN_FILE) |
swamp access token rotate
Revoke an existing token and mint a replacement with the same name and
principal. The new token secret is always stored in the _token-secrets
control-plane vault. The output includes a swamp access token reveal command
to retrieve the new credential.
swamp access token rotate <name>| Flag | Required | Default | Description |
|---|---|---|---|
--duration |
No | 30d |
Lifetime for the new token (e.g., 30m, 1h, 24h, 7d) |
--server |
No | Target a remote server (env: SWAMP_SERVE_URL) |
|
--token |
No | Server token (falls back to stored credential) | |
--token-file |
No | Token file path (env: SWAMP_SERVER_TOKEN_FILE) |
Like mint, rotate has no --vault option.
swamp access token reveal
Show the full authentication credential for a server token. The secret is written directly to stdout (not through the logger) so it can be piped or captured.
swamp access token reveal <name>The command reads the token record, retrieves the plaintext secret from the
datastore or the control-plane vault, and displays the full <name>.<secret>
credential string.
| Flag | Required | Default | Description |
|---|---|---|---|
-y, --yes |
No | Skip confirmation prompt | |
-f, --force |
No | Skip confirmation prompt (alias for --yes) |
|
--repo-dir <dir> |
No | Repository directory (env: SWAMP_REPO_DIR) |
Error cases:
- Token not found:
Error: Server token '<name>' not found - Token revoked:
Error: Server token '<name>' has been revoked - Expired tokens are revealed with a warning
JSON output (--json):
{
"name": "my-token",
"token": "my-token.<secret>",
"expired": false
}The expired field is true when the token has passed its expiry date. Storage
details are excluded from JSON output.
Shared-vault handoff
Server-token secrets are always stored in the control-plane vault. To copy a
credential to a different vault without changing its control-plane storage, pipe
reveal into vault put:
$ swamp access token reveal <name> --repo-dir <repo> --yes --json \
| jq -re .token \
| swamp vault put <vault> server-token-<name> --yesThis writes the full <name>.<secret> credential to the destination vault. The
control-plane vault remains the authoritative store — the copy is a convenience
for systems that read credentials from a specific vault.
Control-plane vault failures
swamp access token mint, rotate, reveal, and swamp worker token create
initialize the _token-secrets control-plane vault before they read or write a
token. When it cannot initialize — invalid or expired datastore credentials, an
unreachable datastore, a damaged local control-plane store — the command fails
with the underlying cause and a hint. There is no fallback to a user vault.
Error: Failed to initialize the _token-secrets control-plane vault (remote datastore): <cause>
Check the datastore credentials and endpoint, then rerun.Error: Failed to initialize the _token-secrets control-plane vault (local control plane): <cause>
Check that the local control-plane store is readable and intact, then rerun.The fix is to restore access to the datastore or the local control-plane store.
A vault named _token-secrets cannot be created with swamp vault create:
names starting with _ are reserved.
A token minted before token secrets moved to the control-plane vault may still
have its secret in a user vault. reveal cannot read that secret while the
control-plane vault fails to initialize. Once the control plane is restored,
swamp access token rotate replaces the token with one whose secret is in the
control-plane vault.
Token secrets encryption key
_token-secrets is encrypted with an AES-256-GCM key. By default the key is
stored in the datastore beside the secrets, so read access to the datastore
decrypts every token secret. The
token-secrets: block
in serve.yaml keeps the key in a vault outside the datastore; see
Keep the token secrets key outside the datastore.
Run locally, mint, rotate, reveal and swamp worker token create read the
block from .swamp/serve.yaml. Once serve has moved the control plane to an
external key, they refuse to run without the block.
swamp access grant
swamp access policy is an alias for swamp access grant.
swamp access grant create
Create a new authorization grant.
swamp access grant create --subject <subject> --on <resource>| Flag | Required | Description |
|---|---|---|
--subject |
Yes | Grant subject (e.g., user:adam, group:release-managers, idp-group:platform-eng) |
--allow |
No | Actions to allow (comma-separated: run, read, write, approve, admin) |
--deny |
No | Actions to deny (comma-separated) |
--on |
Yes | Resource selector (e.g., workflow:@acme/*, behavior:hello) |
--methods |
No | Restrict to these behavior methods or vault verbs (comma-separated, e.g., read,list or put). Refused on a workflow or data grant. See Methods |
--when |
No | CEL condition (e.g., tags.env == "staging") |
--server |
No | Target a remote server (env: SWAMP_SERVE_URL) |
--token |
No | Server token (falls back to stored credential) |
--token-file |
No | Token file path (env: SWAMP_SERVER_TOKEN_FILE) |
Exactly one of --allow or --deny must be provided.
--methods is refused where no request can match it: on a workflow or data
grant, whose requests name no method, and on a vault grant with a method that is
not a vault verb:
Error: Invalid grant methods:
- methods has no effect on a workflow grant: workflow requests name no method, so a methods-scoped allow matches nothing and a deny applies to every request; remove methodsError: Invalid grant methods:
- 'fetch' is not a vault verb (one of get, describe, inspect, list-keys, read-secret, audit-trail, search, put, delete, annotate, create, edit, migrate), so no vault request matches itA grant file with the
same methods loads with a warning instead.
swamp access grant list
List authorization grants.
swamp access grant list| Flag | Required | Description |
|---|---|---|
--server |
No | Target a remote server (env: SWAMP_SERVE_URL) |
--token |
No | Server token (falls back to stored credential) |
--token-file |
No | Token file path (env: SWAMP_SERVER_TOKEN_FILE) |
swamp access grant revoke
Revoke an authorization grant.
swamp access grant revoke <grant_id>| Flag | Required | Description |
|---|---|---|
--server |
No | Target a remote server (env: SWAMP_SERVE_URL) |
--token |
No | Server token (falls back to stored credential) |
--token-file |
No | Token file path (env: SWAMP_SERVER_TOKEN_FILE) |
swamp access group
swamp access group create
Create a local group.
swamp access group create <name>swamp access group add-member
Add a principal to a group.
swamp access group add-member <group> <principal>swamp access group remove-member
Remove a principal from a group.
swamp access group remove-member <group> <principal>swamp access group list
List all groups.
swamp access group listswamp access group list-idp
List IdP groups observed from authenticated users on a server. Unlike the other
group subcommands (which manage local groups), list-idp queries a running
server to show groups aggregated from active server tokens' OAuth userinfo.
swamp access group list-idp --server <url>| Flag | Required | Default | Description |
|---|---|---|---|
--server |
Yes | Server to query (env: SWAMP_SERVE_URL) |
|
--token |
No | Server token (falls back to stored credential or env) | |
--token-file |
No | Token file path (env: SWAMP_SERVER_TOKEN_FILE) |
|
--json |
No | Output in JSON format |
Required permission: read on access:group
Output columns:
| Column | Description |
|---|---|
GROUP |
IdP group name (as received from the OAuth provider) |
ACTIVE TOKENS |
Number of active server tokens carrying this group |
LAST SEEN |
Timestamp of the most recent token carrying this group |
swamp access group members
List members of a group.
swamp access group members <name>swamp access can-i
Check your own permissions against the server's grants.
swamp access can-i| Flag | Required | Description |
|---|---|---|
--action |
No | Action to check (run, read, write, approve, admin) |
--on |
No | Resource to check (e.g., workflow:@acme/deploy) |
--method |
No | Behavior method name to check against method-scoped grants |
--server |
No | Target a remote server (env: SWAMP_SERVE_URL) |
--token |
No | Server token (falls back to stored credential) |
--token-file |
No | Token file path (env: SWAMP_SERVER_TOKEN_FILE) |
Without --action and --on, lists everything you can do. With both, checks a
specific permission. Use --method to test whether a method-scoped grant
permits a specific method. The check uses the IdP groups and collectives on your
own session, so idp-group: grants are reflected without simulating anything.
An approve decision that comes only from a run grant (see
Run implies approve)
is marked [implied by run]. Without --action, every run grant that implies
approve also produces an approve row carrying the marker. When the output
contains an implied approve that allows, a note follows it:
Note: approve rows marked [implied by run] come from run grants. Set auth.approve-requires-explicit-grant on the server to require a grant that names approve.On a server started with --approve-requires-explicit-grant, an allow run
grant produces no implied approve row; a deny run grant still does.
JSON output (--json) adds these fields:
| Field | Location | Description |
|---|---|---|
impliedBy |
Each decisions entry |
"run" when the decision covers approve only through a run grant; absent otherwise |
approveRequiresExplicitGrant |
Top level | The server's approval policy; absent when the server predates the setting |
swamp access check
Explain whether a subject can perform an action on a resource. Requires admin access.
swamp access check --subject <subject> --action <action> --on <resource>| Flag | Required | Description |
|---|---|---|
--subject |
Yes | Subject to check (e.g., user:adam) |
--action |
Yes | Action to check (run, read, write, approve, admin) |
--on |
Yes | Resource to check (e.g., workflow:@acme/deploy) |
--method |
No | Method to check against method-scoped grants: a behavior method, or a vault verb such as get or put |
--collectives |
No | Comma-separated collective memberships for CEL principal.collectives; not with --server |
--groups |
No | Comma-separated IdP group memberships to simulate for idp-group: grants; not with --server |
--field |
No | Resource field for condition evaluation (key=value, repeatable); not with --server |
--server |
No | Target a remote server (env: SWAMP_SERVE_URL) |
--token |
No | Server token (falls back to stored credential) |
--token-file |
No | Token file path (env: SWAMP_SERVER_TOKEN_FILE) |
--method works locally and with --server. Without it the check names no
method, so an allow with a methods list does not match. With it, the output
names the method:
$ swamp access check --subject user:ci --action write --on vault:prod-db --method put
ALLOW via grant 9965a355… (user:ci → write → vault:prod-db method put)
$ swamp access check --subject user:ci --action write --on vault:prod-db
DENY (implicit) — no matching grants for user:ci write vault:prod-dbJSON output carries the checked method in a top-level method field. A server
that predates --method checks the resource without a method, and the command
warns that it did.
A decision that allows or denies approve only through a run grant is marked
[implied by run]:
ALLOW via grant ecc35655… (user:adam → approve → workflow:deploy) [implied by run]
Note: approve is allowed only through a run grant. A server started with --approve-requires-explicit-grant requires a grant that names approve.With --server against a server started with
--approve-requires-explicit-grant, an approve check prints
Approval policy: this server requires a grant that names approve; run grants do not count.
JSON output (--json) carries impliedBy: "run" on each entry of
matchingGrants that covers approve only through a run grant. With
--server, the top-level approveRequiresExplicitGrant field reports the
server's approval policy; it is absent for a local check and for servers that
predate the setting.
Vault decisions in serve runs
With --server, swamp access check and swamp access can-i on a concrete
vault:<name> with read or write print a second decision: whether that
vault operation is allowed in the subject's serve runs, by the
run-time rule. A
request and a run can disagree, since a run is allowed until the principal is
vault-scoped:
ALLOW via grant 5d81fc18… (user:room-bot → read → vault:roomcontrol)
In serve runs: ALLOW read vault roomcontrol (vault-scoped)DENY (implicit) — no matching grants for user:room-bot read vault:erp
In serve runs: DENY read vault erp (vault-scoped)The tag in parentheses is vault-scoped, not vault-scoped, vault deny or
reserved vault. For service:scheduler or service:webhook a second line
follows:
In serve runs: ALLOW read vault erp (not vault-scoped)
This is a trigger principal: this applies to every scheduled or webhook run.JSON output adds a top-level runVaultAccess object; it is absent for a
wildcard vault, for other actions, for a local check, and from servers that
predate vault grants:
| Field | Type | Description |
|---|---|---|
vault |
string | The vault name |
action |
string | read or write |
allowed |
boolean | Whether the operation is allowed in the subject's runs |
restricted |
boolean | Whether the subject is vault-scoped |
rule |
string | The rule that decided, such as no-vault-grants, reserved, vault-deny, vault-allow, vault-scoped, access-admin or unscoped |
reason |
string | The decision in words |
grantId |
string | The deciding grant, when one decided |
triggerScope |
string | Set for a trigger principal |
"runVaultAccess": {
"vault": "erp",
"action": "read",
"allowed": false,
"restricted": true,
"rule": "vault-scoped",
"reason": "the principal holds vault grants and none allows read on vault:erp; add a vault:erp allow grant for read to this principal (IdP-group memberships are not included: the server knows them only for the caller's own session)"
}For your own session, the decision uses your session's memberships. For another
subject the server knows no IdP groups or collectives, and --groups and
--collectives are refused with --server, so an idp-group: grant is not
reflected and the reason says so. A local check (without --server) uses the
IdP groups and collectives passed with --groups and --collectives.
swamp access reload
Rebuild the policy snapshot from current grants and groups. Required after grant
or group changes when using the default --grant-reload manual mode.
swamp access reload| Flag | Required | Description |
|---|---|---|
--server |
No | Target a remote server (env: SWAMP_SERVE_URL) |
--token |
No | Server token (falls back to stored credential) |
--token-file |
No | Token file path (env: SWAMP_SERVER_TOKEN_FILE) |
When a grants/ directory exists, reload reads and validates all files in it
before rebuilding the snapshot. Accepted file extensions are .yaml and .yml.
Subdirectories are ignored — the directory is flat.
The reconciler compares file contents against existing file:* grants. New
entries are created, removed entries are revoked, and unchanged entries are
skipped. Grants with other sources (method, config, extension:*) are not
affected.
If any file fails validation, the entire reload is rejected — the current policy snapshot remains unchanged and no grants are created or revoked.
The response includes a reconciliation summary (created, revoked, unchanged counts) and the full list of active grants.
Related
- Authorization — the grant model and evaluation semantics
- Serve Flags —
swamp serveflags including--grant-reload