Skip to main content

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:

  1. --token flag or SWAMP_SERVER_TOKEN environment variable — an inline <name>.<secret> credential.
  2. --token-file flag or SWAMP_SERVER_TOKEN_FILE environment variable — a path to a file containing the <name>.<secret> credential.
  3. 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 empty

mint 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> --yes

This 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 methods
Error: 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 it

A 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 list

swamp 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-db

JSON 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.