Skip to content

feat(mint): implement ADR 0059 public mint mode - #2773

Merged
ifireball merged 12 commits into
fullsend-ai:mainfrom
ifireball:cursor/a8e2e9b5
Jul 5, 2026
Merged

feat(mint): implement ADR 0059 public mint mode#2773
ifireball merged 12 commits into
fullsend-ai:mainfrom
ifireball:cursor/a8e2e9b5

Conversation

@ifireball

@ifireball ifireball commented Jun 30, 2026

Copy link
Copy Markdown
Member

Summary

  • Add public mint mode when ALLOWED_ORGS is *: any org may mint, but job_workflow_ref must come from fullsend-ai/fullsend/.github/workflows/ only
  • Keep tight mode unchanged (explicit org list, legacy .fullsend/per-repo provenance, basename allowlist)
  • Update provisioner enrollment (EnsureOrgInMint succeeds without config changes, per-repo WIF/unenroll errors) and CLI messaging for public mints
  • Add mint deploy --public to bootstrap GCF-hosted public mints with aligned ALLOWED_ORGS=* and permissive WIF CEL (assertion.repository_owner != ''); bidirectional mode guards block tight↔public conversion on redeploy
  • Sync embedded GCF mint sources and update infrastructure docs

Deploying a public GCF mint

fullsend mint deploy --project MY_PROJECT --pem-dir ./pems --public
  • First-time bootstrap still requires --pem-dir (shared role PEMs/app IDs)
  • Redeploy/upgrade must match mode: --public for public mints, omit for tight mints
  • Standalone JWKS mints (cmd/mint) are unchanged — no WIF provisioning needed

Test plan

  • go test ./internal/mintcore/... ./internal/dispatch/gcf/... ./internal/cli/...
  • hack/lint-mint-embed-sync
  • Manual: mint deploy --public provisions permissive WIF + ALLOWED_ORGS=*; STS accepts any org with upstream workflow provenance
  • Manual: redeploy guards reject mode mismatch (--public into tight / tight into public)

Made with Cursor

Allow ALLOWED_ORGS=* to accept any org while restricting workflow
provenance to fullsend-ai/fullsend upstream reusables, and align
enrollment tooling and docs with public vs tight mint behavior.

Signed-off-by: Barak Korren <bkorren@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

github-actions Bot commented Jun 30, 2026

Copy link
Copy Markdown

Site preview

Preview: https://1184ee02-site.fullsend-ai.workers.dev

Commit: 89675d765e8675061a6ed5c0434265e03013055e

@fullsend-ai-review

fullsend-ai-review Bot commented Jun 30, 2026

Copy link
Copy Markdown

🤖 Review · ❌ Terminated · Started 7:49 AM UTC · Ended 8:17 AM UTC
Commit: 104508d · View workflow run →

@codecov

codecov Bot commented Jun 30, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 78.61272% with 37 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/dispatch/gcf/provisioner.go 75.94% 13 Missing and 6 partials ⚠️
internal/cli/mint.go 82.60% 11 Missing and 5 partials ⚠️
internal/cli/admin.go 0.00% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@fullsend-ai-review

Copy link
Copy Markdown

🤖 Finished Review · ❌ Failure · Started 7:49 AM UTC · Completed 8:17 AM UTC
Commit: d9a7354 · View workflow run →

Comment thread docs/guides/infrastructure/infrastructure-reference.md Outdated
Comment thread docs/guides/infrastructure/mint-administration.md Outdated
Clarify public mint docs (ALLOWED_ORGS=* succeeds without config
changes), add CLI/provisioner tests for public mode paths, and extract
mintValidationStepDone for admin install messaging.

Signed-off-by: Barak Korren <bkorren@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Jun 30, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 9:44 AM UTC · Ended 9:48 AM UTC
Commit: 104508d · View workflow run →

@ifireball ifireball self-assigned this Jun 30, 2026
@ifireball
ifireball marked this pull request as ready for review June 30, 2026 09:47
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

feat(mint): implement ADR 0059 public mint mode (ALLOWED_ORGS=*)

✨ Enhancement 🧪 Tests 📝 Documentation 🕐 40+ Minutes

Grey Divider

AI Description

• Add public mint mode: when ALLOWED_ORGS=*, any GitHub org may mint tokens but job_workflow_ref
 is restricted to fullsend-ai/fullsend/.github/workflows/ only
• Update ValidateOrgAllowed and ValidateWorkflowRef (both canonical and embedded GCF sources) to
 branch on IsPublicMint(), skipping per-repo WIF and basename allowlist checks in public mode
• Make EnsureOrgInMint a no-op and RegisterPerRepoWIF/RemoveOrgFromMint return errors in
 public mode; skip per-repo WIF provisioning in provisionWithExistingMint and
 provisionSelfManaged
• Update CLI (mint enroll, mint enroll-repo, mint status) to detect public mode and emit
 appropriate messaging instead of attempting org/repo registration
• Expand docs (infrastructure-reference, mint-administration, standalone-mint) with tight vs. public
 mode comparison and ADR 0059 cross-references
Diagram

graph TD
    A["GitHub OIDC Token"] --> B["ValidateOrgAllowed"]
    B --> C{"IsPublicMint?"}
    C -- "ALLOWED_ORGS=*" --> D["Public Mode\nAny org accepted"]
    C -- "explicit org list" --> E["Tight Mode\nOrg allowlist check"]
    D --> F["ValidateWorkflowRef\n(public: upstream only)"]
    E --> G["ValidateWorkflowRef\n(tight: .fullsend / upstream / per-repo)"]
    F --> H["Token Issued"]
    G --> H
    I["Provisioner"] --> J{"isTrafficMintPublic?"}
    J -- "public" --> K["EnsureOrgInMint: no-op\nRegisterPerRepoWIF: error\nRemoveOrg: error"]
    J -- "tight" --> L["Normal provisioning"]
    M["CLI mint enroll/status"] --> N{"isPublicMintEnv?"}
    N -- "public" --> O["Short-circuit\nwith public mode msg"]
    N -- "tight" --> P["Normal enrollment flow"]
    subgraph Legend
      direction LR
      _in["Input"] ~~~ _dec{"Decision"} ~~~ _act["Action"]
    end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Dedicated MINT_MODE=public env var
  • ➕ Explicit intent, no ambiguity if * appears alongside other orgs
  • ➕ Easier to grep/audit in config
  • ➖ Two config knobs to keep in sync (ALLOWED_ORGS and MINT_MODE)
  • ➖ Breaking change for existing deployments
  • ➖ ADR 0059 explicitly rejected this approach
2. Separate public-mint Cloud Function deployment
  • ➕ Complete isolation between public and tight deployments
  • ➕ No branching logic in shared validation code
  • ➖ Doubles operational surface area
  • ➖ Requires separate deploy/upgrade lifecycle
  • ➖ Unnecessary for the use case

Recommendation: The PR's approach of inferring mode from ALLOWED_ORGS=* (no separate flag) is clean and backward-compatible. The main alternative worth noting is a dedicated trust-mode env var, but the PR correctly rejects this in ADR 0059 to avoid split-brain configuration. The dual-source maintenance (mintcore + mintsrc embed) is a pre-existing constraint, not introduced here.

Files changed (16) +615 / -50

Enhancement (9) +210 / -39
claims.goAdd IsPublicMint() and update ValidateOrgAllowed/ValidateWorkflowRef for public mode +44/-9

Add IsPublicMint() and update ValidateOrgAllowed/ValidateWorkflowRef for public mode

• Introduces 'IsPublicMint()' to detect '*' in 'ALLOWED_ORGS'. Updates 'ValidateOrgAllowed' to accept any non-empty org in public mode, and 'ValidateWorkflowRef' to require 'fullsend-ai/fullsend/.github/workflows/' provenance while skipping the basename allowlist. Adds 'allowedOrgs' as a new parameter to 'ValidateWorkflowRef'.

internal/mintcore/claims.go

jwks_verifier.goPass allowedOrgs to ValidateWorkflowRef in JWKSVerifier +1/-1

Pass allowedOrgs to ValidateWorkflowRef in JWKSVerifier

• Updates the 'ValidateWorkflowRef' call in 'JWKSVerifier.Verify' to forward 'v.allowedOrgs', enabling public-mode branch in workflow ref validation.

internal/mintcore/jwks_verifier.go

sts_verifier.goPass allowedOrgs to ValidateWorkflowRef in STSVerifier +1/-1

Pass allowedOrgs to ValidateWorkflowRef in STSVerifier

• Updates the 'ValidateWorkflowRef' call in 'STSVerifier.prevalidate' to forward 'v.allowedOrgs', mirroring the JWKS verifier change.

internal/mintcore/sts_verifier.go

claims.go.embedSync embedded GCF mint claims.go with public mode changes +44/-9

Sync embedded GCF mint claims.go with public mode changes

• Mirrors all changes from 'internal/mintcore/claims.go' into the embedded GCF source file, keeping the deployed Cloud Function in sync with the canonical implementation.

internal/dispatch/gcf/mintsrc/mintcore/claims.go.embed

jwks_verifier.go.embedSync embedded GCF jwks_verifier.go with allowedOrgs parameter change +1/-1

Sync embedded GCF jwks_verifier.go with allowedOrgs parameter change

• Updates the embedded GCF copy of 'JWKSVerifier.Verify' to pass 'allowedOrgs' to 'ValidateWorkflowRef'.

internal/dispatch/gcf/mintsrc/mintcore/jwks_verifier.go.embed

sts_verifier.go.embedSync embedded GCF sts_verifier.go with allowedOrgs parameter change +1/-1

Sync embedded GCF sts_verifier.go with allowedOrgs parameter change

• Updates the embedded GCF copy of 'STSVerifier.prevalidate' to pass 'allowedOrgs' to 'ValidateWorkflowRef'.

internal/dispatch/gcf/mintsrc/mintcore/sts_verifier.go.embed

provisioner.goMake EnsureOrgInMint a no-op and block per-repo WIF/unenroll in public mode +49/-5

Make EnsureOrgInMint a no-op and block per-repo WIF/unenroll in public mode

• Adds 'isTrafficMintPublic()' helper and 'parseAllowedOrgsEnv()'. 'EnsureOrgInMint' returns early without updating env vars when public mode is detected. 'RegisterPerRepoWIF' and 'RemoveOrgFromMint' return errors in public mode. 'provisionWithExistingMint' and 'provisionSelfManaged' skip per-repo WIF registration when public mode is active.

internal/dispatch/gcf/provisioner.go

mint.goAdd public mode detection and update enroll/status CLI messaging +67/-11

Add public mode detection and update enroll/status CLI messaging

• Adds 'isPublicMintEnv()' and 'mintValidationStepDone()' helpers. 'runMintEnrollOrg' and 'runMintEnrollRepo' short-circuit with a success message when public mode is detected. 'verifyEnrollment' treats '*' as org-present. 'runMintStatus' displays a 'Public Mode' header and shows '* (public mode — all orgs)' in the enrolled orgs list.

internal/cli/mint.go

admin.goUse mintValidationStepDone for context-aware mint validation messaging +2/-1

Use mintValidationStepDone for context-aware mint validation messaging

• Replaces the hardcoded 'Mint validated and org registered' step message with a call to 'mintValidationStepDone', which returns a public-mode-aware message based on the live traffic env vars.

internal/cli/admin.go

Tests (4) +364 / -1
claims_test.goAdd tests for IsPublicMint, public-mode org validation, and public-mode workflow ref validation +84/-1

Add tests for IsPublicMint, public-mode org validation, and public-mode workflow ref validation

• Adds 'TestIsPublicMint', 'TestValidateOrgAllowed_PublicMode', and 'TestValidateWorkflowRef_PublicMode' covering upstream workflow acceptance, legacy '.fullsend' rejection, per-repo self-workflow rejection, and basename allowlist bypass in public mode. Updates existing tests to pass the new 'allowedOrgs' parameter.

internal/mintcore/claims_test.go

handler_test.goAdd handler integration tests for public mint mode +116/-0

Add handler integration tests for public mint mode

• Adds 'TestHandler_PublicMintMode' (upstream workflow accepted), 'TestHandler_PublicMintRejectsLegacyFullsendRef', and 'TestHandler_PublicMintRejectsPerRepoSelfWorkflow' to verify end-to-end HTTP handler behavior under 'ALLOWED_ORGS=*'.

internal/mintcore/handler_test.go

provisioner_test.goAdd provisioner tests for public mode no-op and rejection behaviors +80/-0

Add provisioner tests for public mode no-op and rejection behaviors

• Adds 'TestParseAllowedOrgsEnv', 'TestEnsureOrgInMint_PublicModeNoOp', 'TestRegisterPerRepoWIF_PublicModeRejected', 'TestRemoveOrgFromMint_PublicModeRejected', and 'TestProvisioner_Provision_BundledMode_PublicMintSkipsPerRepoWIF' to verify provisioner behavior under 'ALLOWED_ORGS=*'.

internal/dispatch/gcf/provisioner_test.go

mint_test.goAdd CLI tests for public mode enroll, status, and validation messaging +84/-0

Add CLI tests for public mode enroll, status, and validation messaging

• Adds 'TestIsPublicMintEnv', 'TestMintValidationStepDone', 'TestVerifyEnrollment_PublicMode', 'TestRunMintEnrollOrg_PublicMode', 'TestRunMintEnrollRepo_PublicMode', and 'TestRunMintStatus_PublicMode' using a new 'mintPublicDiscoveryClient()' fake.

internal/cli/mint_test.go

Documentation (3) +41 / -10
infrastructure-reference.mdDocument tight vs. public mint mode security controls and multi-org behavior +26/-9

Document tight vs. public mint mode security controls and multi-org behavior

• Expands the Mint Security Controls section to describe both tight and public modes with their respective ALLOWED_ORGS, ALLOWED_WORKFLOW_FILES, and job_workflow_ref behaviors. Updates Multi-Org Support to distinguish EnsureOrgInMint behavior per mode.

docs/guides/infrastructure/infrastructure-reference.md

mint-administration.mdAdd public mint mode section to mint enrollment documentation +6/-0

Add public mint mode section to mint enrollment documentation

• Documents that 'mint enroll' and 'mint enroll owner/repo' succeed without modifying mint configuration in public mode, and that 'mint unenroll' cannot remove individual orgs from a public mint.

docs/guides/infrastructure/mint-administration.md

standalone-mint.mdDocument ALLOWED_ORGS=* option and public mint mode for standalone mint +9/-1

Document ALLOWED_ORGS=* option and public mint mode for standalone mint

• Updates the ALLOWED_ORGS variable description to mention '*' and adds a 'Public mint mode' subsection explaining the behavior and constraints when running a standalone mint in public mode.

docs/guides/infrastructure/standalone-mint.md

@fullsend-ai-review

fullsend-ai-review Bot commented Jun 30, 2026

Copy link
Copy Markdown

🤖 Finished Review · ❌ Failure · Started 9:51 AM UTC · Completed 10:20 AM UTC
Commit: 22c8375 · View workflow run →

@qodo-code-review

qodo-code-review Bot commented Jun 30, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (1) 📜 Skill insights (1)

Context used
✅ Compliance rules (platform): 51 rules

Grey Divider


Action required

1. Public mode blocked by WIF ✗ Dismissed 🐞 Bug ≡ Correctness
Description
ALLOWED_ORGS=* now makes ValidateOrgAllowed/ValidateWorkflowRef accept any repository_owner
(with upstream-only workflows), but GCF minting still exchanges via STS against a WIF provider whose
attributeCondition is built from an explicit org list, so non-listed org tokens will fail STS
exchange even though prevalidation passes. This makes public mode ineffective on the hosted mint and
can surface as confusing 401s during real mint calls.
Code

internal/mintcore/claims.go[R59-82]

+const upstreamRepoPrefix = "fullsend-ai/fullsend/"
+
+// IsPublicMint reports whether ALLOWED_ORGS contains *, enabling public mint mode.
+func IsPublicMint(allowedOrgs []string) bool {
+	for _, entry := range allowedOrgs {
+		if entry == "*" {
+			return true
+		}
+	}
+	return false
+}
+
// ValidateOrgAllowed checks that org is in the allowed list (case-insensitive).
+// When allowedOrgs contains *, any non-empty org is accepted (public mint mode).
func ValidateOrgAllowed(org string, allowedOrgs []string) error {
+	if org == "" {
+		return fmt.Errorf("missing repository_owner claim")
+	}
+	if IsPublicMint(allowedOrgs) {
+		return nil
+	}
	for _, entry := range allowedOrgs {
		if strings.EqualFold(entry, org) {
			return nil
Relevance

⭐⭐ Medium

Team fixes STS/WIF mismatch bugs (e.g., attributeCondition blocking tokens in PR #920), but no
precedent for public-mint wildcard case.

PR-#920

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Mintcore now accepts any repository_owner when ALLOWED_ORGS contains *, but the hosted mint’s
STSVerifier still performs STS exchange against a WIF provider, and the GCF provisioner constructs
that provider’s attributeCondition from an explicit org list (and deploys ALLOWED_ORGS as an
explicit list), which will cause STS exchange to reject tokens from other orgs before minting can
succeed.

internal/mintcore/claims.go[59-115]
internal/mintcore/sts_verifier.go[78-90]
internal/dispatch/gcf/mintsrc/main.go.embed[44-83]
internal/dispatch/gcf/provisioner.go[1073-1086]
internal/dispatch/gcf/provisioner.go[1173-1181]
internal/dispatch/gcf/provisioner.go[796-803]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
Public mint mode is inferred from `ALLOWED_ORGS` containing `*`, and mintcore now allows any `repository_owner` in that mode. However, the hosted GCF mint uses `STSVerifier`, which still performs an STS exchange against a Workload Identity Federation (WIF) provider that (as provisioned today) is scoped by an explicit-org `attributeCondition` (`assertion.repository_owner == ...` / `in [...]`). This causes tokens from orgs not present in that condition to fail during STS exchange, even though mintcore prevalidation accepts them.

### Issue Context
- `STSVerifier.Verify` runs prevalidation and then always performs STS exchange using the configured provider.
- The embedded GCF function wires `STSVerifier` with `WIF_PROVIDER_NAME` and `ALLOWED_ORGS`.
- The GCF provisioner currently constructs and writes the WIF provider condition from an explicit org list, and also sets the function env var `ALLOWED_ORGS` to an explicit comma-separated list.

### Fix Focus Areas
- internal/dispatch/gcf/provisioner.go[1073-1086]
- internal/dispatch/gcf/provisioner.go[1173-1181]
- internal/dispatch/gcf/provisioner.go[796-803]
- internal/dispatch/gcf/mintsrc/main.go.embed[44-83]
- internal/mintcore/sts_verifier.go[78-90]

### Expected fix direction
1. Introduce a first-class way for the GCF provisioning path to represent “public mint mode” and propagate it consistently to:
  - Function env var `ALLOWED_ORGS` (set to `*`).
  - WIF provider `AttributeCondition` (set to a permissive condition like `assertion.repository_owner != ''` or `true`, depending on your security posture).
2. Ensure `ensureWIFPoolAndProvider` does **not** clobber an already-permissive public condition back into an explicit-org list when running subsequent provisioning operations.
3. Add/adjust tests in `internal/dispatch/gcf/provisioner_test.go` to cover:
  - Creating/updating the WIF provider in public mode.
  - Preventing regressions where a public provider condition is overwritten during later installs.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

2. Guide not in admin/user 📜 Skill insight ⌂ Architecture
Description
The modified guide files are currently located under docs/guides/infrastructure/, but guides are
required to live under either docs/guides/admin/ or docs/guides/user/. This violates the
documentation placement requirement and makes the guides structure non-compliant.
Code

docs/guides/infrastructure/infrastructure-reference.md[R95-112]

+Mode is inferred from `ALLOWED_ORGS` — there is no separate trust-mode flag. See [ADR 0059](../../ADRs/0059-public-mint-mode-with-wildcard-allowlists.md) for the full decision.
+
+**Tight mint** (default): explicit comma-separated org list (no `*`).
+
+- **ALLOWED_ORGS**: Only listed orgs may mint tokens
+- **ALLOWED_WORKFLOW_FILES**: Fail-closed allowlist of workflow filenames (use `*` to allow any basename)
+- **job_workflow_ref validation**: `.fullsend` config repo, `fullsend-ai/fullsend` upstream reusables, or registered per-repo workflows (`PER_REPO_WIF_REPOS`)
- **PER_REPO_WIF_REPOS**: Repos using dedicated WIF providers (repo-scoped isolation)
-- **Minimum permissions**: Tokens are scoped to the role's minimum permission set, not the App's full permissions
+
+**Public mint**: `ALLOWED_ORGS` is `*`.
+
+- **ALLOWED_ORGS**: Any org may mint (cross-org isolation still enforced at installation lookup)
+- **job_workflow_ref validation**: Only `fullsend-ai/fullsend/.github/workflows/` (any ref — tag, branch, or SHA)
+- **PER_REPO_WIF_REPOS**: Leave unset or empty; all repos use `WIF_PROVIDER_NAME`
+- **ALLOWED_WORKFLOW_FILES**: Basename gate is not applied in public mode
+- **mint enroll**: Succeeds without changing mint configuration (org registration is unnecessary); **mint unenroll** for individual orgs is rejected
+
+- **Minimum permissions**: Tokens are scoped to the role's minimum permission set, not the App's full permissions (both modes)
Relevance

⭐ Low

Repo intentionally uses docs/guides/infrastructure/ (moved/renamed there in PRs #1708, #2698); not
restricted to admin/user.

PR-#1708
PR-#2698

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The compliance rule states that any guides under docs/guides/ must be placed within the admin/
or user/ subdirectories. The cited modified
files—docs/guides/infrastructure/infrastructure-reference.md,
docs/guides/infrastructure/mint-administration.md, and
docs/guides/infrastructure/standalone-mint.md—all sit in docs/guides/infrastructure/, which is
outside the allowed locations, directly demonstrating the policy violation.

docs/guides/infrastructure/infrastructure-reference.md[95-112]
docs/guides/infrastructure/mint-administration.md[265-270]
docs/guides/infrastructure/standalone-mint.md[121-128]
Skill: writing-user-docs

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The guide files under `docs/guides/infrastructure/` are not located under `docs/guides/admin/` or `docs/guides/user/`, which violates the guides directory policy; these modified guides need to be moved into an allowed subdirectory to bring the documentation structure back into compliance.

## Issue Context
This PR modifies these guide files, so their locations must be corrected as part of the change to satisfy the documentation placement requirement for guides under `docs/guides/`.

## Fix Focus Areas
- docs/guides/infrastructure/infrastructure-reference.md[95-112]
- docs/guides/infrastructure/mint-administration.md[265-270]
- docs/guides/infrastructure/standalone-mint.md[121-128]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. ghs_ token literal in test 📘 Rule violation ⛨ Security
Description
The test introduces a hardcoded token-like string ghs_public_mint_token, which can be flagged by
secret scanners and violates the rule against hardcoded secrets/token-like values. Even if intended
as a fake value, it should use a clearly non-secret placeholder format that does not resemble real
credentials.
Code

internal/mintcore/handler_test.go[R1714-1719]

+		case strings.HasPrefix(r.URL.Path, "/app/installations/66666/access_tokens"):
+			w.WriteHeader(http.StatusCreated)
+			json.NewEncoder(w).Encode(installationTokenResponse{
+				Token:     "ghs_public_mint_token",
+				ExpiresAt: "2026-06-02T12:00:00Z",
+			})
Relevance

⭐ Low

Repo previously added/accepted ghs_-prefixed token literals in tests for redaction coverage (PR
#736), so token-like test strings are tolerated.

PR-#736

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The compliance rule prohibits hardcoded secrets and token-like strings. The added test data includes
a literal beginning with ghs_, a GitHub token-like prefix, in internal/mintcore/handler_test.go.

Rule 1062040: Disallow hardcoded secrets and sensitive environment-specific identifiers in source code
internal/mintcore/handler_test.go[1714-1719]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A token-like literal (`ghs_public_mint_token`) was added to a test. This resembles a real GitHub token prefix and can trigger secret scanning or be mistaken for a real credential.

## Issue Context
The compliance rule disallows hardcoded secrets and token-like strings in source code; tests should use placeholders that cannot be confused with real tokens.

## Fix Focus Areas
- internal/mintcore/handler_test.go[1714-1719]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread internal/mintcore/claims.go
@fullsend-ai-review

fullsend-ai-review Bot commented Jun 30, 2026

Copy link
Copy Markdown

Review

Findings

Medium

  • [fail-open] internal/dispatch/gcf/provisioner.go:1104 — The publicAttributeCondition CEL expression (assertion.repository_owner != '') is intentionally permissive for public mint mode. Authorization relies entirely on mintcore prevalidation (ValidateOrgAllowed + ValidateWorkflowRef). There is no secondary defense at the WIF layer. This is consistent with ADR 0059's design.

  • [authorization] internal/mintcore/claims.go:100 — In public mint mode, ValidateWorkflowRef skips the basename allowlist (ALLOWED_WORKFLOW_FILES). The only provenance gate is the repo prefix (fullsend-ai/fullsend). Any workflow file added to the upstream repo is automatically trusted for token minting on all public mints. This is by design per ADR 0059.

  • [stale-feature-status] docs/guides/getting-started/README.md:19 — States "Public mint mode will remove the need for per-org/repo enrollment, but is still in progress" referencing PR docs(adr): add ADR 0059 for public mint mode with wildcard allowlists #1580. ADR 0059 is Accepted and this PR implements public mint mode. Update the note to reflect current status and reference ADR 0059.


Labels: existing labels (type/feature, requires-manual-review, component/mint) are appropriate

Previous run

Review

Findings

Medium

  • [fail-open] internal/dispatch/gcf/provisioner.go:1186EnsureOrgInWIFCondition does not check for public mint mode. If called on a public mint, parseConditionOrgs would extract zero orgs from the permissive CEL condition (assertion.repository_owner != ''), then buildAttributeCondition would overwrite it with a tight org-scoped condition containing only the newly-enrolled org, silently downgrading the WIF provider from permissive to restrictive. Callers (provisionSelfManaged, EnsureOrgInMint) already guard against invoking this in public mode, so this is a defense-in-depth gap rather than a runtime bug.

  • [fail-open] internal/dispatch/gcf/provisioner.go:1104 — The publicAttributeCondition CEL expression (assertion.repository_owner != '') is intentionally permissive for public mint mode. Authorization relies entirely on mintcore prevalidation (ValidateOrgAllowed + ValidateWorkflowRef). There is no secondary defense at the WIF layer. This is consistent with ADR 0059's design.

  • [authorization] internal/mintcore/claims.go:100 — In public mint mode, ValidateWorkflowRef skips the basename allowlist (ALLOWED_WORKFLOW_FILES). The only provenance gate is the repo prefix (fullsend-ai/fullsend). Any workflow file added to the upstream repo is automatically trusted for token minting on all public mints. This is by design per ADR 0059.

  • [stale-feature-status] docs/guides/getting-started/README.md:19 — States "Public mint mode will remove the need for per-org/repo enrollment, but is still in progress" referencing PR docs(adr): add ADR 0059 for public mint mode with wildcard allowlists #1580. ADR 0059 is Accepted and this PR implements public mint mode. Update the note to reflect current status and reference ADR 0059.


Labels: existing labels (type/feature, requires-manual-review, component/mint) are appropriate

Previous run (2)

Review

Findings

Medium

  • [missing guard for new enum value] internal/cli/mint.go:939runMintUnenrollRepo has no early check for public mint mode. Unlike its counterparts (runMintEnrollRepo, runMintUnenrollOrg, runMintEnrollOrg), there is no guard that returns early when ALLOWED_ORGS=*. On a public mint, the function proceeds through DiscoverMint, the dry-run message (which misleadingly says "Would remove from PER_REPO_WIF_REPOS"), and the interactive confirmation prompt before attempting to remove a per-repo WIF provider that does not exist. Provisioner.RemoveRepoFromMint also lacks a public-mode guard, unlike RemoveOrgFromMint. No test covers this scenario.

  • [fail-open] internal/dispatch/gcf/provisioner.go:1186EnsureOrgInWIFCondition does not check for public mint mode. If called on a public mint, parseConditionOrgs would extract zero orgs from the permissive CEL condition (assertion.repository_owner != '), then buildAttributeCondition would overwrite it with a tight org-scoped condition, silently downgrading the WIF provider from permissive to tight. The CLI enrollment path guards against this with an early return in runMintEnrollOrg, but direct callers would hit this bug.

  • [fail-open] internal/dispatch/gcf/provisioner.go:1115 — The publicAttributeCondition CEL expression (assertion.repository_owner != ') is intentionally permissive for public mint mode. mintcore prevalidation provides the primary authorization gate. The WIF layer alone would not prevent unauthorized STS exchanges if mintcore prevalidation is bypassed. Consider documenting in ADR 0059 that the WIF layer is intentionally permissive in public mode.

  • [stale-feature-status] docs/guides/getting-started/README.md:19 — States "Public mint mode will remove the need for per-org/repo enrollment, but is still in progress" referencing PR docs(adr): add ADR 0059 for public mint mode with wildcard allowlists #1580. ADR 0059 is Accepted and this PR implements public mint mode. Update the note to reflect current status and reference ADR 0059.


Labels: existing labels (type/feature, requires-manual-review, component/mint) are appropriate

Previous run (3)

Review

Findings

Medium

  • [missing guard for new enum value] internal/cli/mint.go:864runMintUnenrollOrg has no early check for public mint mode. The user proceeds through DiscoverMint, the dry-run message (which misleadingly says "Would remove from ALLOWED_ORGS"), and the interactive confirmation prompt before provisioner.RemoveOrgFromMint eventually returns an error. In contrast, runMintEnrollOrg and runMintEnrollRepo both return early with an informative message before any dry-run or confirmation logic. No test covers this scenario.

  • [stale-feature-status] docs/guides/getting-started/README.md:19 — States "Public mint mode will remove the need for per-org/repo enrollment, but is still in progress" referencing PR docs(adr): add ADR 0059 for public mint mode with wildcard allowlists #1580. ADR 0059 is Accepted and this PR implements public mint mode. Update the note to reflect current status and reference ADR 0059.


Labels: existing labels (type/feature, requires-manual-review, component/mint) are appropriate

Previous run (4)

Review

Findings

Medium

  • [missing guard for new enum value] internal/cli/mint.go:864runMintUnenrollOrg has no early check for public mint mode. It proceeds through mint discovery, the dry-run message (which misleadingly says "Would remove from ALLOWED_ORGS"), and the interactive confirmation prompt before calling provisioner.RemoveOrgFromMint, which then returns an error. In contrast, runMintEnrollOrg (line 664) and runMintEnrollRepo (line 756) both return early with an informative message before any dry-run or confirmation logic. Add a public-mode check after DiscoverMint succeeds and before the dry-run/confirmation logic, consistent with the pattern in the other two commands.

Labels: existing labels (type/feature, requires-manual-review, component/mint) are appropriate

Previous run (5)

Review

Findings

Medium

  • [missing guard for new enum value] internal/cli/mint.gorunMintUnenrollOrg has no early check for public mint mode. It proceeds through mint discovery, the dry-run check, and the interactive user confirmation prompt before calling provisioner.RemoveOrgFromMint, which then returns an error ("cannot remove individual orgs when mint is in public mode"). In contrast, runMintEnrollOrg and runMintEnrollRepo both return early before any side effects. Add a public-mode check after DiscoverMint succeeds and before the dry-run/confirmation logic.

  • [fail-open] internal/mintcore/claims.goALLOWED_ORGS=* bypasses org validation entirely via a single env var with no secondary confirmation mechanism. ADR 0059 Decision Point 1 explicitly chose not to add a separate mode flag, accepting this risk. However, an accidental * in a tight deployment converts a private mint into a public one. Consider a startup log warning when * is detected, or requiring a second env var for defense-in-depth.

  • [feature-availability-documentation] docs/guides/getting-started/README.md:20 — States "Public mint mode will remove the need for per-org/repo enrollment, but is still in progress" referencing PR docs(adr): add ADR 0059 for public mint mode with wildcard allowlists #1580. ADR 0059 is Accepted and this PR implements the core code, though WIF provisioning is deferred. Update the note to reflect current status and reference ADR 0059.

Previous run (6)

Review

Findings

Medium

  • [missing guard for new enum value] internal/cli/mint.gorunMintUnenrollOrg has no early check for public mint mode. It proceeds through mint discovery, the dry-run check, and the interactive user confirmation prompt before calling provisioner.RemoveOrgFromMint, which then returns an error ("cannot remove individual orgs when mint is in public mode"). In contrast, runMintEnrollOrg and runMintEnrollRepo both return early before any side effects. Add a public-mode check after DiscoverMint succeeds and before the dry-run/confirmation logic.

  • [fail-open] internal/mintcore/claims.goALLOWED_ORGS=* bypasses org validation entirely via a single env var with no secondary confirmation mechanism. ADR 0059 Decision Point 1 explicitly chose not to add a separate mode flag, accepting this risk. However, an accidental * in a tight deployment converts a private mint into a public one. Consider a startup log warning when * is detected, or requiring a second env var for defense-in-depth.

  • [feature-availability-documentation] docs/guides/getting-started/README.md:20 — States "Public mint mode will remove the need for per-org/repo enrollment, but is still in progress" referencing PR docs(adr): add ADR 0059 for public mint mode with wildcard allowlists #1580. ADR 0059 is Accepted and this PR implements the core code, though WIF provisioning is deferred. Update the note to reflect current status and reference ADR 0059.


Labels: PR modifies token mint validation, provisioner enrollment, and CLI mint commands implementing public mint mode

Previous run (7)

Review

Findings

Medium

  • [missing guard for new enum value] internal/cli/mint.gorunMintUnenrollOrg has no early check for public mint mode. It proceeds through user confirmation prompts before calling provisioner.RemoveOrgFromMint, which then returns an error ("cannot remove individual orgs when mint is in public mode"). In contrast, runMintEnrollOrg and runMintEnrollRepo both return early before any side effects. Add a public mode check after discovering the mint, before the dry-run and confirmation logic.

  • [scope-ambiguity] docs/ADRs/0059-public-mint-mode-with-wildcard-allowlists.md — ADR 0059 decision point 2 explicitly defers WIF_PROVIDER_NAME provisioning, CEL text, Cloud Function deployment, and IAM bindings to a future ADR. The docs updates describe public mint configuration but do not clarify that operators must manually provision the permissive WIF provider. Add a callout in docs/guides/infrastructure/standalone-mint.md and mint-administration.md noting this prerequisite.

Low

  • [error suppression in CLI enrollment path] internal/cli/mint.go:664 — In runMintEnrollOrg and runMintEnrollRepo, the error from provisioner.GetServiceTrafficEnvVars(ctx) is silently discarded (trafficEnv, _ := ...). Falls through to tight-mode enrollment (fail-closed), so not a security issue, but masks operational errors.

  • [helper-function-placement] internal/dispatch/gcf/provisioner.go:513parseAllowedOrgsEnv duplicates the parse-and-trim pattern from parseAllowedOrgs in cli/mint.go. Consider extracting to mintcore.ParseAllowedOrgs.

  • [edge case] internal/mintcore/claims.go:100 — In ValidateWorkflowRef public-mode branch, a ref like fullsend-ai/fullsend/.github/workflows/@refs/heads/main would pass with an empty workflow filename. GitHub Actions never produces such a ref, so unexploitable.

  • [documentation-precision] docs/guides/infrastructure/mint-administration.md:70 — "Scripts can call enroll in both public and tight modes without branching" is ambiguous. Clarify: the command succeeds (exit 0) in both modes, but only modifies ALLOWED_ORGS in tight mode.

  • [function-naming-consistency] internal/cli/mint.go:127isPublicMintEnv takes a raw ALLOWED_ORGS string, not an env var lookup. Consider isPublicMintAllowedOrgs for clarity.

  • [naming-consistency] internal/cli/mint.go:131mintValidationStepDone returns a message string but is named like an action; consider mintValidationMessage.

  • [function-signature-consistency] internal/mintcore/claims.go:90ValidateWorkflowRef adds allowedOrgs at position 3. The parameter ordering (claims then config) is actually consistent with existing patterns despite the shift.

  • [test-naming-consistency] internal/cli/mint_test.go:299mintPublicDiscoveryClient could be publicMintDiscoveryClient to better match naming conventions.


Labels: PR modifies token mint validation, provisioner enrollment, and CLI mint commands to implement public mint mode per ADR 0059.

Document that ALLOWED_ORGS=* must pair with a permissive WIF provider
and that tight-mode provisioner paths do not provision public WIF yet.

Signed-off-by: Barak Korren <bkorren@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Jul 1, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 6:02 AM UTC · Completed 6:14 AM UTC
Commit: ba080a7 · View workflow run →

@fullsend-ai-review fullsend-ai-review Bot added requires-manual-review Review requires human judgment component/mint Token mint and cross-boundary credentials type/feature New capability request labels Jul 1, 2026
Clarify that permissive WIF provisioning applies only to the hosted
GCF mint (STSVerifier), not standalone JWKS verification.

Signed-off-by: Barak Korren <bkorren@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Jul 2, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 6:47 AM UTC · Ended 6:59 AM UTC
Commit: 9f4f2b6 · View workflow run →

@fullsend-ai-review

fullsend-ai-review Bot commented Jul 2, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 7:00 AM UTC · Ended 7:08 AM UTC
Commit: 9f4f2b6 · View workflow run →

Stale FULLSEND_PER_REPO_INSTALL on test-repo caused enroll-all to skip
the repo, so repo-maintenance never opened an enrollment PR.

Signed-off-by: Barak Korren <bkorren@redhat.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Jul 2, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 7:09 AM UTC · Completed 7:24 AM UTC
Commit: 89675d7 · View workflow run →

@fullsend-ai-review fullsend-ai-review Bot added requires-manual-review Review requires human judgment and removed requires-manual-review Review requires human judgment labels Jul 2, 2026
@ifireball
ifireball added this pull request to the merge queue Jul 5, 2026
Merged via the queue into fullsend-ai:main with commit c1517ca Jul 5, 2026
19 checks passed
@ifireball
ifireball deleted the cursor/a8e2e9b5 branch July 5, 2026 07:13
@fullsend-ai-retro

fullsend-ai-retro Bot commented Jul 5, 2026

Copy link
Copy Markdown

🤖 Finished Retro · ✅ Success · Started 7:15 AM UTC · Completed 7:23 AM UTC
Commit: 89675d7 · View workflow run →

@fullsend-ai-retro

Copy link
Copy Markdown

PR #2773 (feat: implement ADR 0059 public mint mode) was a substantial 19-file, +1068/-95 feature PR by ifireball, merged after 5 days with 12 commits. The review agent ran 13 times across 3 days (4 failed/terminated, 4 cancelled, 5 successful). The agent produced genuinely valuable findings: it caught missing public-mode guards in runMintUnenrollOrg and runMintUnenrollRepo that the human reviewer did not catch, leading to fix commits. The human reviewer (rh-hemartin) approved on the first commit with only two documentation wording nits. Three other requested reviewers never reviewed. The agent's medium-severity stale-feature-status finding about docs/guides/getting-started/README.md was raised in all 7 review iterations but was never addressed before merge. Most improvement patterns (review deduplication, excessive runs, coverage enforcement) are already tracked in existing issues (#1418, #1331, #2399, #2816, #2810). Two novel proposals below.

Proposals filed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/mint Token mint and cross-boundary credentials requires-manual-review Review requires human judgment type/feature New capability request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants