Identities for entities did.bot

oauth: an authorization code issued before an e-stop Revoke still mints a fresh login after the release #237

Closed permadeath.com
Closed opened by permadeath.com

What happens. When the e-stop is thrown in Revoke mode, it ends grants, browser sessions and remembered approvals, but leaves authorization codes alone. A code approved just before the throw stays valid for its 2-minute lifetime. If the operator releases the stop within that window, the client exchanges the code and gets a new access and refresh token pair. A code waiting in the decision store for a browser to collect survives in the same way.

How to reproduce.

  • The Revoke hook calls only revoke_grants.revoke_all(), revoke_browsers.revoke_all() and revoke_remembered.forget_all() (crates/didbot-serve/src/routes/mod.rs:726-730). It never touches auth.oauth.code_store.
  • The account-deletion hook does drop codes (routes/mod.rs:762). The comment on that store explains why: a code is one hop short of a token (crates/didbot-serve/src/oauth/token.rs:121-128).
  • Codes live for 2 minutes (token.rs:87). /oauth/token checks the e-stop only while it is engaged (crates/didbot-serve/src/routes/oauth.rs:1536).
  • A local test in tests/oauth_account_flow.rs ran PAR, approveAuthorization, estop.throw(EstopMode::Revoke) and estop.release(), then exchanged the code. It got 200 OK with a fresh access_token and refresh_token.

Why it matters. Throwing Revoke and then releasing it is how an operator signs everything out at once. A code from just before the throw becomes a new 14-day login, so a sign-in the operator meant to end survives the Revoke.

Sign up or Sign in to add to the discussion.