Relationships
#1213 Grant *revoke* is never applied to the running server — under `--grant-reload auto` and `manual` alike, a revoked grant stays in force until an explicit `access reload`
Opened by ehazlett · 7/17/2026· Shipped 7/17/2026
Summary
On swamp serve --auth-mode token, a grant revoke does not update the running
server's policy snapshot. The revoke persists to the store (access grant list shows
it gone), but the live server keeps enforcing the revoked grant until someone runs
swamp access reload. This holds under --grant-reload auto as well as manual.
Under --grant-reload auto a grant create does auto-apply, but a revoke does
not — so auto watches the create path but not the revoke path, and revocation, the
security-critical direction, is reload-gated in every mode.
Environment
- swamp
20260717.005557.0-sha.75fb2767 --auth-mode token,--grant-reload auto, filesystem datastore, Linux- Reproduced through the server (
--server, admin token) — not only local CLI
Steps to reproduce
Placeholders below: $SERVER is the serve WebSocket URL; $ADMIN and $TEST are the
minted tokens for user:atlas-admin and user:test.
- Start the server with auto reload:
Log confirms:swamp serve --port 9099 --host [IP-1] --auth-mode token --grant-reload auto --admins user:atlas-adminPolicy snapshot loaded (reload mode: "auto"). - Mint two tokens:
$TESTforuser:test,$ADMINforuser:atlas-admin. - Create a grant through the server (as admin), then check as the subject — no
manual reload:
→swamp access grant create --server $SERVER --token $ADMIN --subject user:test --allow read --on model:reload-test swamp access can-i --server $SERVER --token $TEST --action read --on model:reload-testALLOW. Server log reloaded on its own:Loaded policy snapshot: 2 active grant(s). (Create path works — good.) - Revoke that grant (as admin), then re-check as the subject — no manual reload:
swamp access grant revoke GRANT_ID --server $SERVER --token $ADMIN swamp access grant list --server $SERVER --token $ADMIN swamp access can-i --server $SERVER --token $TEST --action read --on model:reload-testgrant listshows the grant gone, butcan-istill returnsALLOW, and the server log shows no new snapshot reload. - Run an explicit reload, then re-check:
→ nowswamp access reload --server $SERVER --token $ADMIN swamp access can-i --server $SERVER --token $TEST --action read --on model:reload-testDENY. Server log:Loaded policy snapshot: 1 active grant(s).
Expected vs. actual
- Expected: after
access grant revoke, the running server stops enforcing the grant — immediately underauto, and ideally regardless of reload mode, since this is revocation. - Actual: the revoke is written to the store but the live policy snapshot is not
reloaded, so the revoked grant keeps being enforced until a manual
access reload.
Likely cause
Create and revoke appear to take different internal paths: the create path triggers
the auto snapshot reload (observed in the log), the revoke path does not. grant create produced no method report and reloaded the snapshot; grant revoke ran as a
@swamp/grant revoke model method and did not reload. So auto's trigger fires
for create but is missing on revoke.
Impact (security)
Revocation is the security-critical direction. An operator who revokes a grant during
an incident sees access grant list confirm the removal and reasonably believes it
took effect — but the server continues to honor the revoked permission. Because a
create auto-applies while a revoke does not, the inconsistency is easy to trust
wrongly. Contrast: token revocation is immediate (connection refused, no reload
needed); grant revocation is not.
Suggested fix (any one, in order of preference)
- Fire the same snapshot reload on the revoke path under
--grant-reload autothat already fires on create. - Make grant revocation take effect immediately regardless of reload mode.
- At minimum, emit a loud warning at
grant revoketime thataccess reloadis required for it to take effect on a running server.
Shipped
Click a lifecycle step above to view its details.