nic-6443 commented on PR #13792:
URL: https://github.com/apache/apisix/pull/13792#issuecomment-5215562406

   I went looking at how other OIDC-capable gateways and proxies handle 
revocation of a session-held token, since it seemed worth knowing what the 
prior art looks like. Sharing the survey — the short version is that none of 
the browser-session implementations introspect the session token per request. 
They either wait for a back-channel logout notification, or re-validate 
periodically through the refresh grant.
   
   | Project | Session storage | Per-request introspection of session token | 
Back-channel logout | Actual revocation mechanism |
   |---|---|---|---|---|
   | mod_auth_openidc | server-cache (default) / cookie | No — introspection 
lives entirely under `OIDCOAuth*`, the RS path | Yes, with `jti` replay cache | 
back-channel logout + `OIDCRefreshAccessTokenBeforeExpiry` |
   | Traefik Hub | cookie / Redis | No | Yes (`backchannelLogoutUrl`) | 
back-channel logout |
   | traefikoidc (community plugin) | cookie / Redis | No — introspection is 
bearer-only by design | Yes (`enableBackchannelLogout`) | back-channel logout, 
Redis required for multi-replica |
   | Spring Security | HttpSession | No | Yes, since 6.2 
(`OidcBackChannelLogoutHandler` in 6.4) | back-channel logout |
   | Kong OIDC | cookie / Redis / memcache | No — `reverify` is local JWT 
verification only | No | server-side session + revoke on logout |
   | oauth2-proxy | cookie / Redis | No | No, requested since 2021 | 
`--cookie-refresh` periodic refresh grant |
   | Envoy OAuth2 filter | HMAC cookie | No | No, open issue | RP-initiated 
logout only |
   | NGINX Plus nginx-openid-connect | keyval (server-side) | No | No | keyval 
+ `/logout` deletes the key |
   | Pomerium | databroker (fully server-side) | No | No | log out when refresh 
fails + admin revocation |
   | Gloo Gateway | cookie / Redis | No — `introspectionUrl` applies to header 
tokens | No | Redis session + `logoutPath` |
   | Ory Oathkeeper | none | Yes, per request by default | N/A | introspection |
   
   Oathkeeper is the only per-request introspector, and it has no session 
concept at all — it handles pure bearer traffic, which is the path 
`introspect()` already covers here.
   
   The mod_auth_openidc row is probably the most relevant one, being the same 
author as lua-resty-openidc and a much older codebase. Every introspection 
directive there is namespaced `OIDCOAuth*`, i.e. the OAuth 2.0 Resource Server 
path, and the session path has no introspection option at all. What it offers 
for the session path instead is `OIDCRefreshAccessTokenBeforeExpiry <seconds> 
[logout_on_error | authenticate_on_error | 502_on_error]`: refresh the token 
ahead of expiry and treat a failed refresh, meaning the OP revoked the refresh 
token, as a logout. `--cookie-refresh` in oauth2-proxy and Pomerium's "log out 
when refresh fails" are the same idea. That's a third option neither this PR 
nor #13750 mentions, and it's the most widely adopted one in the survey — it 
needs no introspection support from the OP, and the detection delay is bounded 
by the refresh interval instead of costing an IdP round trip per request.
   
   One correction to the PR description while I'm here: back-channel logout may 
be closer than "out of scope" suggests. `session.storage = "redis"` landed in 
#12986, so the server-side storage prerequisite already exists. What's missing 
is narrower — a `sid` to session-key reverse index written at login from the ID 
token's `sid` claim, plus the logout endpoint and logout token validation. 
lua-resty-openidc has no back-channel logout support, so that part would have 
to live in the plugin.
   
   Separately, the cache key here including the endpoint, `client_id` and 
`cache_segment` is worth keeping regardless of direction. Oathkeeper shipped a 
CVE (GHSA-qvp4-rpmr-xwrr) precisely because its introspection cache didn't 
distinguish introspection URLs, so a token primed against one server could be 
replayed against rules pointing at another.
   
   The one thing I'd reconsider is the default. `introspection_interval = 0` 
means an IdP round trip on every request, while every comparable mechanism 
above operates on a minutes timescale. Framing this as bounded-delay periodic 
revalidation rather than per-request real-time verification would make the cost 
a lot easier to justify.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to