Skip to main content
← Back to list
01Issue
BugClosedSwamp CLITeam
AssigneesNone

Relationships

#1386 auth token create advertises a 'collective:write' scope that does not exist, and following its advice hits 'collective tokens cannot create other collective tokens'

Opened by magistr · 7/24/2026

Summary

When swamp auth token create is run without credentials, the error tells the user to obtain a token carrying the collective:write scope. That scope does not exist anywhere in the codebase and is never checked by anything. Worse, a user who follows the instruction literally — obtains a collective token, sets SWAMP_API_KEY, retries — hits a hard refusal that collective tokens may not create collective tokens. The advertised recovery path is categorically impossible.

Where (source)

  • src/cli/commands/auth_token_create.ts:72-75
    requireAuthenticated(
      "Collective tokens are a team feature",
      "collective:write",
    );
  • src/cli/auth_context.ts:69-83requireAuthenticated interpolates that string into "Your token should include the ... scope."
  • src/libswamp/auth/token_create.ts:106-114 — the refusal the advice leads to.
  • Grep: collective:write appears only at auth_token_create.ts:74. There is no requireScope("collective:write") and no registry entry. The only scopes the CLI ever checks are vault:*, datastore:*, serve:*.

Deterministic repro

export SWAMP_HOME="$(mktemp -d)"; mkdir -p "$SWAMP_HOME/config"   # no credentials

swamp auth token create --collective myorg --scopes "serve:*"

Step 1 output:

Error: Collective tokens are a team feature that requires a free swamp-club.com account.

Sign in:

  swamp auth login

Or create a collective token at swamp-club.com/collectives and set
SWAMP_API_KEY. Your token should include the collective:write scope.

Now do exactly what the last sentence says — set SWAMP_API_KEY to a collective token and retry:

Error: Collective tokens cannot create other collective tokens. Sign in with a personal account using `swamp auth login`.

Impact

The user is told to obtain a scope that cannot be granted (it is not in the registry), in order to reach a code path that rejects collective tokens on principle. Someone hitting this in CI will go to the web UI, hunt for collective:write in the scope selector, not find it, and reasonably conclude the UI is out of date or their collective lacks a permission — when in fact the only valid answer is "this command requires a personal login, full stop."

This is a distinct defect from #1381: nothing here fails to resolve. The state is read correctly and the advice is wrong.

Expected

  • Drop the second paragraph from this particular call site. swamp auth token create cannot be satisfied by a collective token at all, so pointing at SWAMP_API_KEY is always wrong here — it should simply say to run swamp auth login with a personal account.
  • More generally, requireAuthenticated(feature, scope) should only advertise a scope that exists in the registry; a scope name with no enforcement anywhere is a good thing to assert against in tests.
  • If some future collective:write is intended, add it to the registry and check it; otherwise remove the string.

Environment

  • Verified against source main @ 10943ef. Gate shipped in a519305 (#1934), 2026-07-23; installed stable 20260722.210030.0-sha.7ff1e2f0 predates it.
  • macOS 14.
02Bog Flow
OPENTRIAGEDIN PROGRESSCLOSED

Closed

7/24/2026, 10:45:09 PM

No activity in this phase yet.

03Sludge Pulse
Editable. Press Enter to edit.

magistr commented 7/24/2026, 9:59:15 PM

Correction from the author — my central factual claim was wrong, and the bug is worse than I described.

I wrote that collective:write 'does not exist anywhere' and called it fictional. That is false. It is a real, documented, mintable scope. /manual/reference/api-key-authentication lists it in the Collective category alongside collective:read and collective:*, defined as:

collective:write | Update collective settings

What is true is narrower, and is what my grep actually showed: the string appears exactly once in the CLI source (auth_token_create.ts:74, inside the error text) and there is no requireScope('collective:write') anywhere. So it is unenforced by the CLI, not nonexistent.

Why this makes the report stronger rather than weaker.

Had the scope been imaginary, the user would fail fast — they would search the web UI scope selector, not find it, and conclude the advice was stale. Because it is real, the failure path is longer and more convincing:

  1. CLI says: 'create a collective token ... Your token should include the collective:write scope.'
  2. The user finds collective:write in the scope selector, because it genuinely exists.
  3. They mint the token, export SWAMP_API_KEY, retry.
  4. They get: 'Collective tokens cannot create other collective tokens.'

They have now been sent to obtain a real credential that governs an unrelated capability (collective settings), for an operation that no scope can unlock, because the operation is categorically closed to collective tokens.

The manual already says the right thing. /manual/reference/api-key-authentication, on swamp auth token create:

Requires personal authentication (swamp auth login) — collective tokens cannot create other tokens.

and /manual/how-to/authenticate-with-api-keys:

You must be logged in with a personal account that has the owner or admin role on the collective.

So the CLI's error message contradicts the documented behaviour of the very command that emits it. The fix is unchanged from what I originally proposed — drop the collective-token paragraph at this call site and say a personal login with owner/admin role is required — but the justification is 'the message contradicts the manual and names a scope that governs something else', not 'the scope is fake'.

stack72 commented 7/24/2026, 10:45:09 PM

@magistr Thanks for the detailed reports — we appreciate the work you're putting in to make the tool better. Fixes are in #1956 and will be released shortly.

Sign in to post a ripple.