Evaluate Forgejo 16 Authorized Integrations as a replacement for the cross-repository PAT writers #806
Labels
No labels
burndown-2026-06
burndown-2026-08
autonomy
async-consult
autonomy
epic
autonomy
headless
autonomy
live-collab
coherence-core
priority
P0
priority
P1
priority
P2
priority
P3
priority
P4
qa-fixture
role/advocate
role/director
role/exec
role/frontend
role/gamedev
role/human
role/platform
role/qa
role/science
role/sysadmin
state
ambient
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
coilyco-flight-deck/infrastructure#806
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Outcome
Decide whether Forgejo 16's Authorized Integrations should replace part of the
coilyco-opsPAT family, starting with the six cross-repository release writers.This is an evaluation with a real tradeoff, not a straightforward win. It needs a decision before implementation.
How this surfaced
After the 16.0.2 upgrade (
6b1bc59, merged10fc64d), Forgejo Actions runs began showing a per-job banner:The banner renders above the log view rather than in the log bytes, which is why it does not appear in
aosguard ops actions logsoutput.Nothing regressed.
permissions:was never honoured by Forgejo; 16.0.2 only started saying so. A separate sweep of all 29 repositories and 84 workflows found 31 workflows declaringpermissions, of which 26 are.forgejo-lane and inert. That cleanup is cosmetic and deliberately out of scope here.The banner's own remedy is what makes this issue worth opening.
What Authorized Integrations provide
A job sets
enable-openid-connect: true, requests a JWT from Forgejo with the Integration's audience, and authenticates with HTTP Bearer. Per the documentation, the JWT can be used to "Interact with Forgejo's APIs, package registry, and Git operations", so this is not REST-only.The rules bind a JWT to source repository, workflow filename, git ref, and trigger event. Capabilities use the same scopes as access tokens.
Why the cross-repository writers are the pilot
Six family members exist only so one repository's release job can write to another:
Each is a static
write:repositoryPAT. Anything holding one can write to the tap or bucket, from anywhere, until rotation. An Integration-issued token for the same job would be valid only from a named workflow, in a named repository, on a named ref, for a named event.That is a real blast-radius reduction, and these six are the cleanest case because their consumer is unambiguously an Actions job.
Candidacy across the family
The discriminator is whether the consumer is an Actions job. No job means no OIDC context, so no Integration.
Candidates
registry-token(REGISTRY_TOKEN) - agentic-osrelease,dev-base-publish, wardpromoteeco-mod-package-token(ECO_MOD_PACKAGE_TOKEN)ci-release-token(CI_RELEASE_TOKEN) - agentic-os and cli-guardpromote, wardpromote/releaseFORGEJO_PUSH_TOKEN- agentic-os-kaibuild-catalog-graph,sync-repo-digests,sync-repo-registryNot candidates - no Actions job in the path
mcp-read-token- the Ward MCP podregistry-read-token- KubernetesimagePullSecretsflux-deploy-token- the Flux controllerdeploy-read-token- runner registration, outside any jobsirens-echo-issue-token- the in-namespace MCP podpassword- the minting root itselfRoughly ten of fifteen are candidates. The remainder are pods and controllers that will always need a PAT, so this reduces the family rather than retiring it.
The blocker
Authorized Integrations appear to be UI-only. The live instance's OpenAPI document carries 326 endpoints and none match
integration,oidc,openid, orauthorized:They are also configured per user, so they would live in the
coilyco-opsbot account's settings.That collides with how this fleet manages credentials.
ward exec coilyco-ops-provisionmints, verifies, rotates, and revokes the whole family as one attended scripted operation, and the inventory is reviewable in git. Click-configured Integrations would be invisible to that script and to review.The tradeoff is therefore narrow-but-unauditable against broad-but-auditable, which is why this is a decision rather than a task.
Open questions
docker login, or only for REST package calls? The docs mention the registry but show only REST examples.registry-tokencandidacy depends on this.coilyco-opswith capability targetinghomebrew-tap, restricted to source repositorycli-guardand workflowrelease.yml?Suggested first step
Configure exactly one Integration by hand, for one of the six writers, and prove or disprove questions 3 and 4 before touching the provisioning script. A single working example settles most of this; the current uncertainty is not resolvable from documentation alone.
Out of scope
.forgejo-lanepermissions:blocks. Cosmetic, and unrelated to credentials..github-lanepermissions:blocks. GitHub honours those -cli-guard'scodeql.yml(security-events: write) anddependabot-auto-merge.yml(pull-requests: write) need theirs, so a blanket sweep would break them.Related maintenance
The
token-mintingskill is dated 2026-07-05 and predates this upgrade. Its trap 6, "No headless release re-run (Forgejo 15.0.2)", is now stale -aosguard ops actions rerunexists. The skill wants a pass against 16.0.2 regardless of the outcome here.Next owner
Ops, for the single hand-configured probe. Any change to
provision-coilyco-ops-bot.shfollows the decision, not the probe.