auth: Cross-App Access and the identity assertion authorization grant (ID-JAG) — the enterprise path for a plugin to act for a person without a consent screen, and the answer to where #1523's grant comes from
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 9
- Forks
- 0
- Avg merge
- 3h 3m
- Merged PRs (30d)
- 509
Description
Problem
#337 and #1523 design three-legged consent: a human delegates their authority to a plugin once, the refresh token is held as a secret reference, and runs use it under tenancy. That is the consumer OAuth shape and it is right for a personal deployment. It is the wrong shape for an enterprise, where the security team does not want forty employees each clicking "allow" on a GitHub consent page for an automation, and where the identity provider already knows which applications may reach which resources on whose behalf.
The IETF and the OpenID Foundation's enterprise work have converged on a different flow for exactly this: Cross-App Access, built on the identity assertion authorization grant (draft-ietf-oauth-identity-assertion-authz-grant, ID-JAG). The requesting application exchanges the user's ID token at the enterprise IdP (RFC 8693 token exchange, requested_token_type = the ID-JAG) and presents the resulting assertion to the resource application's authorization server as a JWT bearer grant (RFC 7523) to obtain an access token for that resource, scoped by what the IdP's policy allows for that user, that app, and that resource. No user interaction after SSO, one place for the enterprise to govern, and revocation at the IdP.
Nothing in the tree speaks it: grep -rn 'jwt-authz-grant\|id-jag\|identity-assertion' pkg cmd docs is empty. The pieces it needs are already here, which is why it is worth deciding now rather than after #1523 lands the consumer shape: auth/exchange_oauth.go is a complete RFC 8693 client with requested_token_type and RFC 8707 resource indicators; client_assertion (RFC 7523 client authentication) is implemented at exchange_oauth.go:756; the broker mints audience-bound assertions per target; and #557's PrincipalKind and on_behalf_of give the resulting credential a principal to be attributed to.
Desired outcome
A recorded decision, and if yes, one federation target kind:
targets:
- name: github-for-people
cross_app:
idp_token_url: https://acme.okta.com/oauth2/v1/token # exchanges the person's ID token for an ID-JAG
resource: https://api.github.com # the resource app
resource_token_url: https://github.com/login/oauth/access_token # where the ID-JAG is presented
audience: https://github.com
used by an http: step or a plugin task with credential: github-for-people, where the run's caller is a human principal (or an agent with on_behalf_of a human): the broker exchanges the caller's ID token for an ID-JAG, presents it, caches the access token per principal and target with the existing expiry margin, and the resulting credential is attributed to the person in the audit record. No grant store is needed for this path: the IdP is the store.
Acceptance criteria
- A conformance case with a fake IdP and a fake resource authorization server runs an
http:step as a human principal and asserts the two exchanges, the audience on each, and that a workload principal (no ID token) is refused by the target with a sentence naming the caller kind. - The ID token never enters history: it is read from the request's verified principal on the server and carried to the worker as the broker's own assertion per #560's rules, or the exchange happens server-side and only the resulting short-lived access token reaches the activity, whichever the decision records.
docs/WORKLOAD_IDENTITY_FEDERATION.mdgains a "for people" section beside the workload ladder.
Constraints and dependencies
- The draft is not final; the target kind should name the profile version it implements and refuse a response shape it does not recognise, as the plugin protocol's own versioning does.
- Adjacent: #337, #1523, #557, #560, #1522 (
credential_inputsfor plugins), #1524 (a gateway holding the resource credential is the other enterprise shape, and the two compose: the gateway performs the exchange).
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 by reading auth/exchange_oauth.go, especially the RFC 8693 flow and client_assertion at line 756, then review #557 and #560. Run the stated grep and inspect docs/WORKLOAD_IDENTITY_FEDERATION.md; done means a recorded decision, a versioned target profile if accepted, and the listed conformance and documentation outcomes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- github, go
- Domain
- authentication, authorization, backend-api-design, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 28/100