-
Notifications
You must be signed in to change notification settings - Fork 106
feat(mint): cross-org authorization and e2e WIF auth (#2155) #2277
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
33 commits
Select commit
Hold shift + click to select a range
0986623
feat(mint): cross-org authorization and e2e WIF auth (#2155)
ifireball 5ecaf94
Merge branch 'main' into cursor/b69a09e5
ifireball 0c8c454
Merge branch 'main' into cursor/b69a09e5
ifireball 6e4a2e4
docs: renumber cross-org mint ADR from 0046 to 0051
ifireball dbb1e03
fix(cli): use org-wide visibility for FOREIGN allowlist variables
ifireball d658530
refactor(e2e): reuse mintclient for cross-org tokens and fix mint rep…
ifireball 6e0bfed
feat(mint): grant e2e app org variables permission for FOREIGN reads
ifireball ea97fef
feat(mint): allow installation-wide mint tokens when repos are omitted
ifireball 9d7d415
chore: fix gofmt alignment in AppPermissions struct
ifireball 4b1123a
fix(cli): detect installation tokens before OAuth scope preflight
ifireball a4afead
Merge upstream/main into cursor/b69a09e5.
ifireball 40edec6
fix(forge): resolve installation token identity via GraphQL viewer
ifireball a10b6e6
feat(mint): grant e2e role repository variables write permission
ifireball 93e5c4d
feat(mint): grant e2e role organization variables write permission
ifireball 8472786
Merge upstream/main and address PR #2277 review feedback
ifireball 1704870
fix(mint): allow installation-wide tokens on same-org path
ifireball 8bd58ff
test: improve patch coverage for foreign mint and CLI paths
ifireball c5e38d6
chore: gofmt foreign_test.go
ifireball cfa6ec8
test: raise patch coverage for foreign mint paths
ifireball 270af39
Merge upstream/main and address post-approval review feedback
ifireball dc589e6
docs: renumber cross-org mint ADR to 0055
ifireball 838e2bf
fix(e2e): open triage test issues with user token for ADR 0054
ifireball d92663a
fix(e2e): fall back to E2E_GITHUB_PASSWORD for issue author in CI
ifireball 33aac55
docs(e2e): keep E2E_GITHUB_PASSWORD as interim issue-author secret
ifireball aa01014
refactor(e2e): use FULLSEND_MINT_URL / hosted default instead of E2E_…
ifireball f4ad9cc
docs(make): update e2e-test help for hosted mint default
ifireball b324850
docs: document interim E2E_GITHUB_PASSWORD PAT in AGENTS.md
ifireball cf9e747
Merge branch 'main' of https://github.com/fullsend-ai/fullsend into c…
ifireball d2f03fc
fix(e2e): trigger triage via ready-for-triage label dispatch
ifireball eef4612
fix(mint,cli): address review feedback and renumber cross-org ADR to …
ifireball 8f18dae
fix(ci,e2e): gofmt token test and clean stale .fullsend forks
ifireball 7e411e6
fix(e2e): use --direct scaffold delivery for mint tokens in CI
ifireball 3e1fd5f
Merge branch 'main' of https://github.com/fullsend-ai/fullsend
ifireball File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
85 changes: 85 additions & 0 deletions
85
docs/ADRs/0060-cross-org-mint-authorization-via-org-variables.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| --- | ||
|
ifireball marked this conversation as resolved.
|
||
| title: "60. Cross-org mint authorization via org variables" | ||
| status: Accepted | ||
| relates_to: | ||
| - agent-infrastructure | ||
| - security-threat-model | ||
| topics: | ||
| - identity | ||
| - oidc | ||
| - github-apps | ||
| - cross-org | ||
| --- | ||
|
|
||
| # 60. Cross-org mint authorization via org variables | ||
|
|
||
| Date: 2026-06-07 | ||
|
|
||
| ## Status | ||
|
|
||
| Accepted | ||
|
|
||
| ## Context | ||
|
|
||
| The central token mint ([ADR 0029](0029-central-token-mint-secretless-fullsend.md)) issues | ||
| short-lived GitHub App installation tokens to OIDC-authenticated workflows. Today the mint | ||
| scopes tokens to the caller's `repository_owner`: the App installation lookup and PEM | ||
| lookup both use the org from the OIDC `repository` claim. | ||
|
|
||
| Some workloads need to act on a **different** org than the workflow's owner. The e2e | ||
| test pool ([ADR 0040](0040-org-pool-for-parallel-e2e-tests.md)) runs CI from | ||
| `fullsend-ai/fullsend` but mutates dedicated pool orgs (`halfsend-01`, …). Future | ||
| cross-org agent flows ([#672](https://github.com/fullsend-ai/fullsend/issues/672), | ||
| [#1916](https://github.com/fullsend-ai/fullsend/issues/1916)) have the same shape. | ||
|
|
||
| The target org must explicitly authorize which foreign repos or orgs may request tokens | ||
| for a given role. A mint-operator central allowlist does not scale and does not give target | ||
| orgs control over their own policy. | ||
|
|
||
| ## Decision | ||
|
|
||
| 1. **Optional `target_org` on mint requests.** When omitted, or when equal to the caller's | ||
| `repository_owner` (case-insensitive), behavior uses the same `mintToken` path with no | ||
| FOREIGN check. When `repos` is omitted, the mint issues an installation-wide token via | ||
| org-level installation lookup (same as the cross-org path). Callers are authenticated via | ||
| WIF/OIDC; only enrolled workflows that pass mint enrollment checks can reach the handler. | ||
|
|
||
| 2. **Cross-org path** applies only when `target_org` is set and differs from the caller org: | ||
| - Resolve the requested role's App installation on `target_org` via org-level installation lookup. | ||
| - Read `FULLSEND_FOREIGN_<role>_REPOS` on the target org using that role's App installation | ||
| token (`organization_actions_variables: read`). | ||
| - Deny if installation lookup fails, the variable is missing/empty, or the OIDC caller | ||
| (`repository` or bare `repository_owner`) is not on the allowlist. | ||
|
ifireball marked this conversation as resolved.
|
||
| - Mint an installation token for the requested repos on the target org, or installation-wide | ||
| when `repos` is omitted. The `e2e` role acting on pool orgs from CI is the first consumer | ||
| ([#2155](https://github.com/fullsend-ai/fullsend/issues/2155)). | ||
|
|
||
| 3. **Variable format.** Org-level GitHub Actions variable on the **target** org: | ||
| - Name: `FULLSEND_FOREIGN_<ROLE>_REPOS` (uppercase role suffix, per [ADR 0014](0014-admin-install-github-apps-secrets-v1.md)) | ||
| - Value: comma-separated list of `org/repo` (exact `repository` match) and/or bare `org` | ||
| (`repository_owner` match) | ||
|
|
||
| 4. **Role-agnostic mechanism.** Any allowed role may use the cross-org path when the target | ||
| org has installed that role's App and configured the FOREIGN variable. The `e2e` role | ||
| ([#2155](https://github.com/fullsend-ai/fullsend/issues/2155)) is the first consumer. | ||
|
|
||
| 5. **CLI.** `fullsend admin foreign allow|list|revoke` manages FOREIGN variables on a target org. | ||
|
|
||
| ## Consequences | ||
|
|
||
| - Cross-org mint requests add GitHub API calls. FOREIGN allowlist lookups are cached in-memory | ||
| per mint instance (key: `target_org/role`, TTL 60s). Cache entries include empty/missing | ||
| allowlists (negative cache) so revoked or unset variables may take up to one TTL window to | ||
| take effect. Cardinality is bounded by enrolled orgs × roles; no explicit eviction beyond TTL. | ||
| - Roles used on the cross-org path need `organization_actions_variables: read` on their App permissions. | ||
| - The `e2e` role additionally needs `actions_variables: write` and | ||
| `organization_actions_variables: write` so pool tests can set repo/org variables during | ||
| install flows; these writes are scoped to pool orgs that explicitly authorize CI via | ||
| `FULLSEND_FOREIGN_E2E_REPOS`. | ||
| - Installation-wide tokens (empty `repos`) are permitted on both same-org and cross-org | ||
| paths. Cross-org requests additionally require FOREIGN authorization on the target org. | ||
| Same-org elevation relies on WIF/OIDC enrollment: only trusted workflows can call the mint. | ||
| - Target orgs opt in by installing the role App and setting the FOREIGN allowlist (cross-org). | ||
| - Same-org mint for enrolled orgs adds zero FOREIGN API calls; optional `repos` omission uses | ||
| org-level installation lookup when callers need installation-wide scope. | ||
| - Pool org provisioning must install the e2e App and set `FULLSEND_FOREIGN_E2E_REPOS` for CI callers. | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.