Skip to content

chore(auth): prepare production Wolfi publication grant - #133

Merged
cpanato merged 2 commits into
wolfi-dev:mainfrom
joedborg:joedborg/os-2867-prod-publish-policy
Sep 29, 2026
Merged

cpanato merged 2 commits into
wolfi-dev:mainfrom
joedborg:joedborg/os-2867-prod-publish-policy

Conversation

@joedborg

@joedborg joedborg commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Why

The production publisher needs public repository write access without granting that access to the exporter.

How

Add an organization-hosted policy for the dedicated production publisher, restricted to repositories: [os] and contents: write. Keeping it outside mirrored history avoids policy commits diverging the publication branch.

Merge in step 2 after staging acceptance, fresh CI, and review. The paused foundation deployment is confirmed and the verified production numeric subjects are now populated. Keep the new schedules paused through policy installation and handover.

Proof

The production foundation deployment applied successfully at 2026-09-29 13:01:33 UTC (27 added, 0 changed, 0 destroyed). It deployed 20b01d2cc011307f62d7e389dc31355ea4ad1c8e, a verified descendant of merged foundation f605768657b04638e6d2a552ec3ff4cdd09c8514.

Direct GCP IAM reads and the run's tf-output-env-enforce.dev-iac-400-export-wolfi artifact agree:

Account Numeric subject
export-wolfi@prod-enforce-fabc.iam.gserviceaccount.com 100496071258544612791
export-wolfi-publish@prod-enforce-fabc.iam.gserviceaccount.com 111686246305885758377

All four prepared policy YAMLs structurally equal the deployment's octosts_policies outputs. Live read-only checks confirmed both jobs Ready at observed generation 1, saved DRY_RUN=true, empty bootstrap, separate runtime accounts, expected repositories/branches/horizon/signer, 2 CPU/8 GiB, and zero task retries. Both Scheduler jobs are PAUSED (hourly export; daily 14:00 UTC publication).

Both deployed image signatures were independently verified with cosign against exact identity https://github.com/chainguard-dev/mono/.github/workflows/.terraform.yaml@refs/heads/main and issuer https://token.actions.githubusercontent.com. Export digest: sha256:6027800bd11f80eeaecc6df67b4c7d158df1da87657524f29c87853e7f867027; publication digest: sha256:3d99353bb87f53adaf822cdc24789f6b5ccb2252e6e44a1c41b3bee2c999a279.

Both job-failure alert policies are enabled with troubleshooting documentation and the expected enabled destinations: #eng-os-prod-alerts, shared Pub/Sub alerts, and OS Pub/Sub alerts_os. This is a configuration check, not notification-delivery proof.

Pinned yam formatting, strict OctoSTS v0.8.0 schema/compile/scope/permission checks, and diff checks pass. For each policy, synthetic claims with the configured production subject are allowed; the opposite production identity, staging/dev identities, fixture subjects, empty subject, wrong issuer and wrong audience are rejected. These are offline authorization checks; production runtime token exchange and Git writes remain part of the later handover proof. Two independent reviews found no remaining findings.

The source-policy PR additionally passed all applicable stereo pre-commit hooks individually (yam, misspell, YAML, Markdown, large-file/case/conflict/private-key/todo checks). The all-hooks launcher initially failed installing the unrelated wolfictl package linter after a Go proxy stream error; that linter does not apply to these files. The temporary checker passed gofmt, go mod tidy, go test (no test files), and golangci-lint. No proof files were committed.

Merge order

  1. Staging gate: mono#62720 deployed; real-publication peak-memory evidence accepted.
  2. Foundation: chainguard-dev/mono#62783. Merged and deployed paused/dry-run on September 29; successful deployment evidence.
  3. Runtime policies, parallel after step 1: chainguard-dev/stereo#356262; chainguard-dev/.github#324; wolfi-dev/.github#133. Production numeric subjects are populated and verified against IAM and deployment outputs. Require fresh CI and review before merging.
  4. Stop Actions: chainguard-dev/stereo#356263. During the owned handover window, disable schedules/manual dispatch and drain queued/active runs before new writers may run.
  5. Legacy retirement after step 3: chainguard-dev/wolfi-staging#25 and chainguard-dev/git-export#160. Remove the destination grant in wolfi-staging only, before selecting the bootstrap SHA. Publication carries the same deletion into public; do not open a divergent public-policy removal commit. Keep mono's build-time policy.
  6. Operator handover proof: freeze/review destination history, review the exact bootstrap SHA, prove real export parity/signing and exact-commit publication with schedules still paused. Recheck every export advancement and publish only the final verified tip.
  7. Activation LAST: chainguard-dev/mono#62787. Merge only after the handover evidence is accepted, then have an authorized operator deploy it and verify natural scheduled execution.

Merging is not deployment. This PR set does not authorize or perform production releases, local production plans/applies, or runtime writes. Full procedure: production runbook. Tracking: OS-2867.

@joedborg joedborg added the ai-review Request automated review label Sep 28, 2026
@joedborg joedborg self-assigned this Sep 28, 2026
@joedborg
joedborg marked this pull request as ready for review September 28, 2026 17:16
cpanato
cpanato previously approved these changes Sep 29, 2026
@joedborg
joedborg marked this pull request as draft September 29, 2026 13:07
@joedborg
joedborg marked this pull request as ready for review September 29, 2026 13:10
@joedborg
joedborg enabled auto-merge (squash) September 29, 2026 13:40
joedborg added a commit to chainguard-dev/.github that referenced this pull request Sep 29, 2026
## Why

Export and publication require distinct, narrowly scoped access to the
production intermediate repository.

## How

Add organization policies outside mirrored history: exporter gets
`contents: write` only on `wolfi-staging`; publisher gets `contents:
read` only on `wolfi-staging`. Exact Google subjects are separate; no
public-write or git-export grant is added.

**Merge in step 2 after staging acceptance, fresh CI, and review.** The
paused foundation deployment is confirmed and the verified production
numeric subjects are now populated. Keep the new schedules paused
through policy installation and handover.

## Proof

The [production foundation
deployment](https://github.com/chainguard-dev/mono/actions/runs/36571602400/job/109416724297)
applied successfully at **2026-09-29 13:01:33 UTC** (27 added, 0
changed, 0 destroyed). It deployed
`20b01d2cc011307f62d7e389dc31355ea4ad1c8e`, a verified descendant of
merged foundation `f605768657b04638e6d2a552ec3ff4cdd09c8514`.

Direct GCP IAM reads and the run's
`tf-output-env-enforce.dev-iac-400-export-wolfi` artifact agree:

| Account | Numeric subject |
|---|---|
| `export-wolfi@prod-enforce-fabc.iam.gserviceaccount.com` |
`100496071258544612791` |
| `export-wolfi-publish@prod-enforce-fabc.iam.gserviceaccount.com` |
`111686246305885758377` |

All four prepared policy YAMLs structurally equal the deployment's
`octosts_policies` outputs. Live read-only checks confirmed both jobs
Ready at observed generation 1, saved `DRY_RUN=true`, empty bootstrap,
separate runtime accounts, expected
repositories/branches/horizon/signer, 2 CPU/8 GiB, and zero task
retries. Both Scheduler jobs are **PAUSED** (hourly export; daily 14:00
UTC publication).

Both deployed image signatures were independently verified with cosign
against exact identity
`https://github.com/chainguard-dev/mono/.github/workflows/.terraform.yaml@refs/heads/main`
and issuer `https://token.actions.githubusercontent.com`. Export digest:
`sha256:6027800bd11f80eeaecc6df67b4c7d158df1da87657524f29c87853e7f867027`;
publication digest:
`sha256:3d99353bb87f53adaf822cdc24789f6b5ccb2252e6e44a1c41b3bee2c999a279`.

Both job-failure alert policies are enabled with troubleshooting
documentation and the expected enabled destinations:
`#eng-os-prod-alerts`, shared Pub/Sub `alerts`, and OS Pub/Sub
`alerts_os`. This is a configuration check, not notification-delivery
proof.

Pinned yam formatting, strict OctoSTS v0.8.0
schema/compile/scope/permission checks, and diff checks pass. For each
policy, synthetic claims with the configured production subject are
allowed; the opposite production identity, staging/dev identities,
fixture subjects, empty subject, wrong issuer and wrong audience are
rejected. These are offline authorization checks; production runtime
token exchange and Git writes remain part of the later handover proof.
Two independent reviews found no remaining findings.

The source-policy PR additionally passed all applicable stereo
pre-commit hooks individually (yam, misspell, YAML, Markdown,
large-file/case/conflict/private-key/todo checks). The all-hooks
launcher initially failed installing the unrelated wolfictl package
linter after a Go proxy stream error; that linter does not apply to
these files. The temporary checker passed gofmt, go mod tidy, go test
(no test files), and golangci-lint. No proof files were committed.

## Merge order

0. **Staging gate:**
[mono#62720](chainguard-dev/mono#62720)
deployed; real-publication peak-memory evidence accepted.
1. **Foundation:**
[chainguard-dev/mono#62783](chainguard-dev/mono#62783).
Merged and deployed paused/dry-run on September 29; [successful
deployment
evidence](https://github.com/chainguard-dev/mono/actions/runs/36571602400/job/109416724297).
2. **Runtime policies, parallel after step 1:**
[chainguard-dev/stereo#356262](chainguard-dev/stereo#356262);
[#324](#324);
[wolfi-dev/.github#133](wolfi-dev/.github#133).
Production numeric subjects are populated and verified against IAM and
deployment outputs. Require fresh CI and review before merging.
3. **Stop Actions:**
[chainguard-dev/stereo#356263](chainguard-dev/stereo#356263).
During the owned handover window, disable schedules/manual dispatch and
drain queued/active runs before new writers may run.
4. **Legacy retirement after step 3:**
[chainguard-dev/wolfi-staging#25](chainguard-dev/wolfi-staging#25)
and
[chainguard-dev/git-export#160](chainguard-dev/git-export#160).
Remove the destination grant in wolfi-staging only, before selecting the
bootstrap SHA. Publication carries the same deletion into public; do not
open a divergent public-policy removal commit. Keep mono's build-time
policy.
5. **Operator handover proof:** freeze/review destination history,
review the exact bootstrap SHA, prove real export parity/signing and
exact-commit publication with schedules still paused. Recheck every
export advancement and publish only the final verified tip.
6. **Activation LAST:**
[chainguard-dev/mono#62787](chainguard-dev/mono#62787).
Merge only after the handover evidence is accepted, then have an
authorized operator deploy it and verify natural scheduled execution.

Merging is not deployment. This PR set does not authorize or perform
production releases, local production plans/applies, or runtime writes.
Full procedure: [production
runbook](https://github.com/chainguard-dev/mono/blob/main/env/enforce.dev/iac/400-export-wolfi/README.md).
Tracking: [OS-2867](https://linear.app/chainguard/issue/OS-2867).
@cpanato
cpanato disabled auto-merge September 29, 2026 14:02
@cpanato
cpanato merged commit 40b8d4a into wolfi-dev:main Sep 29, 2026
3 checks passed
@joedborg
joedborg deleted the joedborg/os-2867-prod-publish-policy branch September 29, 2026 14:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-review Request automated review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants