Ops rollout: Forgejo external-account lockdown and scoped runners #664

Closed
opened 2026-07-28 10:42:24 +00:00 by coilyco-ops · 4 comments
Member

Parent: #658

Engineering checkpoint: commit 6f8beb3 on canonical main.

The tracked target state is complete and offline validation passes. This issue owns the live boundary that the engineer role cannot cross.

Acceptance:

  • Record the current global runner registrations, replica state, successful workflow baselines, and the existence of the legacy SSM registration-token path.
  • Run the scoped-token provisioner and staged-runner rollout from docs/forgejo-external-account-lockdown-runners.md. Keep legacy runners available through the canary and rollback window.
  • Prove general workflows in all three approved organizations, image builds in agentic-os and infrastructure, one deploy from coilyco-bridge/deploy, and tap-writer visibility only in coilyco-flight-deck/homebrew-tap.
  • Prove an unrelated repository has no scoped runner, then remove every global registration only after the approved workflows pass.
  • Apply deploy/forgejo.yml and verify an authenticated external account cannot create a repository, organization, push-created repository, fork, or runner surface while issue creation still works.
  • Install and verify the hardened summon units from docs/forgejo-external-account-lockdown-summon.md. Record the immutable approval checks and evidence that Goose lacks AWS, SSH, Kubernetes, Forgejo, GitHub, and registry credentials.
  • Promote the proven scoped aggregate into the Flux overlay, remove the legacy runner resources and SSM token after the rollback window, run the repository gate, commit, and push the final tracked state.
  • Attach before-state, rollback commands, registration ids, token timing, workflow results, denial checks, and final commit to this issue and #658.

Rollback: retain the current runner manifests, registrations, replica counts, and legacy token until the scoped path passes. The runbook contains the scale-down and restore sequence.

Parent: #658 Engineering checkpoint: commit 6f8beb3 on canonical main. The tracked target state is complete and offline validation passes. This issue owns the live boundary that the engineer role cannot cross. Acceptance: - [ ] Record the current global runner registrations, replica state, successful workflow baselines, and the existence of the legacy SSM registration-token path. - [ ] Run the scoped-token provisioner and staged-runner rollout from docs/forgejo-external-account-lockdown-runners.md. Keep legacy runners available through the canary and rollback window. - [ ] Prove general workflows in all three approved organizations, image builds in agentic-os and infrastructure, one deploy from coilyco-bridge/deploy, and tap-writer visibility only in coilyco-flight-deck/homebrew-tap. - [ ] Prove an unrelated repository has no scoped runner, then remove every global registration only after the approved workflows pass. - [ ] Apply deploy/forgejo.yml and verify an authenticated external account cannot create a repository, organization, push-created repository, fork, or runner surface while issue creation still works. - [ ] Install and verify the hardened summon units from docs/forgejo-external-account-lockdown-summon.md. Record the immutable approval checks and evidence that Goose lacks AWS, SSH, Kubernetes, Forgejo, GitHub, and registry credentials. - [ ] Promote the proven scoped aggregate into the Flux overlay, remove the legacy runner resources and SSM token after the rollback window, run the repository gate, commit, and push the final tracked state. - [ ] Attach before-state, rollback commands, registration ids, token timing, workflow results, denial checks, and final commit to this issue and #658. Rollback: retain the current runner manifests, registrations, replica counts, and legacy token until the scoped path passes. The runbook contains the scale-down and restore sequence.
Author
Member

Ops checkpoint at commit 9c24a88 on canonical main.\n\nCompleted:\n\n* Before-state recorded seven instance-global registrations, legacy replicas 4 general / 1 image / 1 deploy / 1 tap, and the legacy SecureString at version 1.\n* Forgejo now preserves external-only registration while repository creation is zero, push-create is off for users and organizations, regular organization creation is off, organization creation defaults off, and forks plus the limit bypass are off.\n* Five owner-revealed scoped registration tokens were stored through private mode-0600 files. No token entered argv, output, tracked state, or the bot permission surface.\n* Seven scoped registrations are live: Flight Deck general 2, Bridge general 1, Gaming general 1, Flight Deck image 1, deploy repository 1, and tap repository 1.\n* Flux is Ready and Healthy on 9c24a88 with all six scoped StatefulSet health checks. The complete repository gate passed before landing.\n* Clean-boundary canaries passed for Flight Deck lint, infrastructure image build, Agentic OS image publish, Bridge CI, Bridge deploy, and Gaming hygiene. Tap-writer is visible only in homebrew-tap.\n* The unrelated coilysiren/website canary remains waiting with no eligible runner.\n* All seven global registrations were deleted. No Global row remains. Legacy StatefulSets are 0/0 with PVCs retained only for rollback.\n* The legacy SSM parameter was invalidated at version 2. The guarded SSM surface has no delete operation.\n* The sirens-discord-ops CI canary exposed a separate post-checkout workflow failure. A different Gaming workflow passed on the same scoped runner, and coilyco-gaming/sirens-discord-ops#43 owns that defect.\n\nRollback:\n\n* Scoped registrations and PVCs remain intact.\n* Restoring the global path requires an owner-revealed instance token through the guarded file source, followed by the recorded legacy replica counts. The deleted registrations and invalidated token cannot restart accidentally.\n\nTwo human checks remain:\n\n1. Kai installs the hardened summon units from scripts/install-coilyco-ops-summon.sh in an interactive kai-server TTY. The host checkout is current and clean, and all 34 summon tests pass. Sudo is the only install wall.\n2. Kai uses a real external OAuth test account to prove issue creation succeeds while repository, organization, fork, push-create, and runner settings are denied. The live server controls are in place, but the Ops bot is not an external OAuth identity.\n\nThe issue stays open for those two interactive acceptance checks.

Ops checkpoint at commit 9c24a88 on canonical main.\n\nCompleted:\n\n* Before-state recorded seven instance-global registrations, legacy replicas 4 general / 1 image / 1 deploy / 1 tap, and the legacy SecureString at version 1.\n* Forgejo now preserves external-only registration while repository creation is zero, push-create is off for users and organizations, regular organization creation is off, organization creation defaults off, and forks plus the limit bypass are off.\n* Five owner-revealed scoped registration tokens were stored through private mode-0600 files. No token entered argv, output, tracked state, or the bot permission surface.\n* Seven scoped registrations are live: Flight Deck general 2, Bridge general 1, Gaming general 1, Flight Deck image 1, deploy repository 1, and tap repository 1.\n* Flux is Ready and Healthy on 9c24a88 with all six scoped StatefulSet health checks. The complete repository gate passed before landing.\n* Clean-boundary canaries passed for Flight Deck lint, infrastructure image build, Agentic OS image publish, Bridge CI, Bridge deploy, and Gaming hygiene. Tap-writer is visible only in homebrew-tap.\n* The unrelated coilysiren/website canary remains waiting with no eligible runner.\n* All seven global registrations were deleted. No Global row remains. Legacy StatefulSets are 0/0 with PVCs retained only for rollback.\n* The legacy SSM parameter was invalidated at version 2. The guarded SSM surface has no delete operation.\n* The sirens-discord-ops CI canary exposed a separate post-checkout workflow failure. A different Gaming workflow passed on the same scoped runner, and coilyco-gaming/sirens-discord-ops#43 owns that defect.\n\nRollback:\n\n* Scoped registrations and PVCs remain intact.\n* Restoring the global path requires an owner-revealed instance token through the guarded file source, followed by the recorded legacy replica counts. The deleted registrations and invalidated token cannot restart accidentally.\n\nTwo human checks remain:\n\n1. Kai installs the hardened summon units from scripts/install-coilyco-ops-summon.sh in an interactive kai-server TTY. The host checkout is current and clean, and all 34 summon tests pass. Sudo is the only install wall.\n2. Kai uses a real external OAuth test account to prove issue creation succeeds while repository, organization, fork, push-create, and runner settings are denied. The live server controls are in place, but the Ops bot is not an external OAuth identity.\n\nThe issue stays open for those two interactive acceptance checks.
Author
Member

Kai reported both interactive acceptance checks complete. Ops verification found one installer defect before closure: the timer was enabled, but coilyco-ops-summon.service failed because uv tried to repair the checkout virtualenv under the hidden home. Commit 6e30cc3 moves the uv environment and managed Python into the service-owned cache and makes the installer prove one complete token-refresh plus poll cycle. The clean kai-server checkout is fast-forwarded through that fix, but the installed unit files still require one repeated sudo-backed installer run.

During diagnosis, verbose dependency logging disclosed the summon bot token in operator tool output. Ops treated it as compromised immediately. The bot password, API token, deploy read token, and MCP read token were rotated through the tracked provisioner without printing the replacements. The new credentials authenticated successfully. The deploy ExternalSecret refreshed from SSM and the repository-scoped deploy runner completed its rolling restart. Commits 759503c and 8bceea3 repaired two stale provisioner paths exposed during that rotation.

This issue remains open only for Kai to rerun scripts/install-coilyco-ops-summon.sh. Ops will then verify a successful constrained poll cycle and close #664 plus #658.

Kai reported both interactive acceptance checks complete. Ops verification found one installer defect before closure: the timer was enabled, but `coilyco-ops-summon.service` failed because uv tried to repair the checkout virtualenv under the hidden home. Commit `6e30cc3` moves the uv environment and managed Python into the service-owned cache and makes the installer prove one complete token-refresh plus poll cycle. The clean kai-server checkout is fast-forwarded through that fix, but the installed unit files still require one repeated sudo-backed installer run. During diagnosis, verbose dependency logging disclosed the summon bot token in operator tool output. Ops treated it as compromised immediately. The bot password, API token, deploy read token, and MCP read token were rotated through the tracked provisioner without printing the replacements. The new credentials authenticated successfully. The deploy ExternalSecret refreshed from SSM and the repository-scoped deploy runner completed its rolling restart. Commits `759503c` and `8bceea3` repaired two stale provisioner paths exposed during that rotation. This issue remains open only for Kai to rerun `scripts/install-coilyco-ops-summon.sh`. Ops will then verify a successful constrained poll cycle and close #664 plus #658.
Author
Member

Kai chose full retirement instead of repairing or migrating the native summon service. Canonical commit dd9d903 removes the poller, tests, installer, three systemd units, Ward verbs, operator skill, dedicated runbook, and dead cross-references. Future bot-token rotations also drop the now-unused write:notification scope. The shared coilyco-ops identity remains for its other Forgejo automation consumers.

Live verification still shows the old timer enabled and its installed unit files present on kai-server. Kai has the explicit sudo removal command. Close this issue and #658 after those unit files report absent.

Kai chose full retirement instead of repairing or migrating the native summon service. Canonical commit `dd9d903` removes the poller, tests, installer, three systemd units, Ward verbs, operator skill, dedicated runbook, and dead cross-references. Future bot-token rotations also drop the now-unused `write:notification` scope. The shared `coilyco-ops` identity remains for its other Forgejo automation consumers. Live verification still shows the old timer enabled and its installed unit files present on kai-server. Kai has the explicit sudo removal command. Close this issue and #658 after those unit files report absent.
Author
Member

Final Ops verification passed.

  • coilyco-ops-summon.timer, coilyco-ops-summon.service, and coilyco-ops-summon-token.service each report LoadState=not-found and inactive.
  • All three installed unit files are absent.
  • /run/coilyco-ops-summon and /var/cache/coilyco-ops-summon are absent.
  • The clean kai-server checkout is fast-forwarded to canonical dd9d903.
  • The poller, tests, installer, units, Ward verbs, operator skill, and runbook are absent from both canonical main and the host checkout.
  • Kai completed the external OAuth acceptance checks. The scoped-runner and credential-rotation evidence remains in the preceding checkpoints.

The retired surface gives external issue content no path to host-side Goose. Acceptance is complete.

Final Ops verification passed. * `coilyco-ops-summon.timer`, `coilyco-ops-summon.service`, and `coilyco-ops-summon-token.service` each report `LoadState=not-found` and inactive. * All three installed unit files are absent. * `/run/coilyco-ops-summon` and `/var/cache/coilyco-ops-summon` are absent. * The clean kai-server checkout is fast-forwarded to canonical `dd9d903`. * The poller, tests, installer, units, Ward verbs, operator skill, and runbook are absent from both canonical main and the host checkout. * Kai completed the external OAuth acceptance checks. The scoped-runner and credential-rotation evidence remains in the preceding checkpoints. The retired surface gives external issue content no path to host-side Goose. Acceptance is complete.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
coilyco-flight-deck/infrastructure#664
No description provided.