Relationships
#1379 swamp serve --auth-mode oauth: crash during first-run admin resolution discards the OAuth token, forcing full device-flow re-registration
Opened by dmc · 7/24/2026· Shipped 7/24/2026
Summary
This affects swamp serve's OAuth admission bootstrap (the device-flow client
registration and --admins/--allowed-collectives resolution that run on
swamp serve --auth-mode oauth).
On first run, serve does a device-flow client registration against the OAuth
provider (default swamp-club.com), then uses the token from that flow to
resolve --admins/--allowed-collectives values into concrete accounts. If
that resolution fails — e.g. an --admins value doesn't match a real
account — the process exits fatally, and the access token obtained during the
device flow is never persisted anywhere. Every subsequent run reuses the
already-stored client credentials but has no access token, and fails
differently: "Cannot resolve usernames — no access token and no cached
resolutions." The only way forward is to delete the stored client credentials
(swamp vault delete local-secrets oauth-client-id) and redo the entire
device-flow browser confirmation from scratch, even though the client itself
had already registered successfully.
A compounding factor: the --admins flag's help text example
(user:oauth|user-123) doesn't match actual resolver behavior. The resolver
strips the user: prefix and looks up the remainder as a literal swamp-club
username via the directory API — so user:oauth|<subject-id> fails with
"Username 'oauth|' not found," while the working form appears to
be user:<username> (e.g. user:dmc). That makes it easy to supply an
invalid value on the very first attempt, which is exactly when the
token-loss bug above bites hardest.
Consequence observed: repeated invalid-value attempts under this flow drove
three full device-flow registrations in about six minutes, which then
triggered a 400 Bad Request from the device-authorization endpoint itself
(apparent rate limiting). A confusing flag format can cascade into a "can't
test this at all for a while" state.
Expected fix approach
Persist the access token (or at least the resolved admin/collective set) as
soon as it's obtained during the device flow, before attempting to resolve
--admins/--allowed-collectives — so a resolution failure doesn't discard
already-valid credentials and force full re-registration. Separately, fix the
--admins help text example to match actual behavior, or support the
documented user:oauth|<subject-id> form if that was the original intent.
Steps to reproduce
swamp serve --auth-mode oauth --allowed-collectives <collective> --admins "user:oauth|<a-real-account-id>"- Complete the printed device-flow URL/code in a browser.
- Observe: client registers successfully, then the process exits with
Failed to resolve admin 'user:oauth|<id>': Username 'oauth|<id>' not found on <provider>. - Re-run the same command (client credentials are now cached from step 2).
- Observe: immediately fails with
Cannot resolve usernames — no access token and no cached resolutions. Clear stored credentials to re-register: swamp vault delete local-secrets oauth-client-id— even though a client was already registered and a token was briefly held during step 2/3. - Run
swamp vault delete local-secrets oauth-client-id, retry with a corrected--admins "user:<username>"value — this requires a full new device-flow browser confirmation rather than reusing anything from the first attempt.
Environment
- swamp
20260718.233837.0-sha.f5bb6b99— bug reproduced on this build (three times, with different--adminsvalues, across a fresh laptop session). - Not re-verified against the current
20260720.234931.0-sha.4770b0fd— the device-authorization rate limit encountered mid-testing made another live device-flow round-trip impractical at the time of filing. - OAuth provider: default (
https://swamp-club.com). --auth-mode oauth,--allowed-collectives,--adminsall involved.
Shipped
Click a lifecycle step above to view its details.