auth: an opaque access token from an external authorization server cannot be admitted — decide RFC 7662 introspection as an issuer kind, or record that Flowstate admits JWTs only
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 9
- Forks
- 0
- Avg merge
- 3h 3m
- Merged PRs (30d)
- 509
Description
Problem
auth.Verifier parses a bearer token as a JWT before anything else (pkg/flowstate/v1/auth/verifier.go), and TrustedIssuer has two kinds, oidc and mtls. Many enterprise authorization servers issue opaque access tokens by default and offer RFC 7662 token introspection as the way a resource learns who the token is for; some issue JWTs only on request per client. grep -rn -i introspect pkg/flowstate/v1/auth is empty. A deployment behind such an AS today has no supported way in: the operator either reconfigures the AS to mint JWTs for this client, which is not always theirs to do, or terminates auth in a proxy and forwards a header, which is the trust-the-transport shape the verifier exists to avoid.
#560 argues against building an introspection endpoint for Flowstate's own minted assertions, because their lifetime is shorter than any lookup's propagation delay. That is about tokens Flowstate mints. This is about tokens Flowstate receives, where the choice is the operator's AS, not ours.
Desired outcome
A recorded decision, and if yes, a third issuer kind:
issuers:
- name: corp-as
kind: introspection
issuer: https://as.corp.example.com
introspection_url: https://as.corp.example.com/oauth2/introspect
client_id: flowstate
client_secret: ${secret('env:AS_CLIENT_SECRET')} # or client_assertion via the deployment key, which the exchange path already supports
audiences: [https://flowstate.example.com/rpc]
namespace_claim: namespace
cache_ttl: 30s
verified through the same egress boundary the JWKS fetch uses, with the response's active, aud, exp, sub and claims projected to the same Principal a JWT produces, a bounded cache keyed by token hash so a hot path is one lookup per cache_ttl, and fail-closed on an unreachable AS.
The refused shape, if the answer is no: docs/DEPLOYMENT.md says "Flowstate admits JWT access tokens only; configure your authorization server to issue JWTs (RFC 9068) for this client", with the vendor recipes for the three common ones.
Acceptance criteria
- If yes: a test with a fake introspection endpoint admits an active token and refuses an inactive one, one for another audience, and one whose introspection call fails; the cache bound is pinned.
- If no: the deployment guide's sentence exists and
flow auth checkon an opaque token says so instead of "not a JWT".
Constraints and dependencies
- The introspection credential is a secret and goes through the secret store, never a flag;
client_assertion(RFC 7523) via the deployment's signing key is the preferred authentication and already exists inexchange_oauth.go:756. - Adjacent: #559, #560, #1694 (identity egress for the introspection call), #1695.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with pkg/flowstate/v1/auth/verifier.go and exchange_oauth.go:756, then review the adjacent identity-egress work in #1694. Decide whether opaque-token introspection should be supported or explicitly refused. Done means the decision is recorded, with the specified fake-endpoint and cache tests if supported, or the deployment-guide and flow auth check updates if refused.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- authentication, backend-api-design
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100