Repository navigation
feat(workflows): mirror signed images to acr and seed dr secrets - #31
Merged
Merged
Conversation
Capture the production digest, signed platform graph, and four-secret transfer requirements before implementing the DR workflows. The offline contracts fail against the current workflow set as required by spec 009 T121.
…ting a value Adds the reusable sync-dr-secrets workflow (gitops spec 009 T131, research Decision 14): short-lived AWS and Azure OIDC sessions in a GitHub environment copy exactly four Secrets Manager values byte-exact into the DR Key Vault. Tracing is disabled, values are masked before any other use, the one CLI file is mode 0600 in a 0700 directory removed by an EXIT trap, and the only output is an in-process jwt-value-match boolean. A self-test runs the contract. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Preserve the existing AWS promotion tuples while routing the explicit prod/full/aks-dr/dr-rolling tuple through a separate mirror and secret seed chain. The companion workflows are being added in the same pull request.
The two DR identities receive reviewed tenant and subscription inputs from the caller. Runtime metadata stays explicit while the AWS promotion path keeps its previous inputs.
…mission The service-mirror contract required `id-token: write` and also forbade the literal `token:`, which that permission contains, so no workflow could satisfy it. The rule's intent is that the public GitOps checkout takes no token; it now forbids a key named exactly `token` instead. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Add the reusable DR service mirror for gitops spec 009 T131 (research.md Decision 13, release-promotion-contract.md rules 8 and 9). It accepts only the repository and digest the GitOps production overlay declares, reaches AWS and Azure through OIDC alone, reads the public GitOps repository with no persisted credential, installs oras, crane and cosign by checksum from the toolchain lock, copies the signed OCI graph by digest with any tag-scheme signature, attestation and SBOM, fails unless the ACR manifest digest equals the ECR one, and verifies the Cosign signature and SPDX attestation in ACR against the service CI identity. Nothing is rebuilt or re-signed. The self-test runs tests/workflows/mirror-to-acr.bats on changes to the mirror, its self-test, promote.yml and the test. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Extend mirror-platform-images.yml for gitops spec 009 T131 (research Decision 13). An optional mirror-to-acr job, gated on acr-name and run after the unchanged ECR mirror, validates the whole lock and every ECR digest first, then copies each locked image by digest with oras cp -r, plus tag-scheme .sig/.att/.sbom when present. It proves image, referrer and tag digests are equal in ACR and verifies the platform-mirror Cosign identity there. AWS and Azure use OIDC only, tools come checksum-locked from the toolchain lock, and nothing is rebuilt or re-signed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 of 5 tasks
EstebanGZam
marked this pull request as ready for review
September 21, 2026 21:40
2 of 3 tasks
EstebanGZam
added a commit
to MicroTodoSuite/microservice-app-gitops
that referenced
this pull request
Sep 22, 2026
…228) ## What changes The full-platform register now distinguishes the AWS foundations that were created from the evidence that was actually retained. It records the redacted T052 preflight, the first-creation and lifecycle re-up facts for every rebuilt root, the hub half-apply and repair, and the still-missing proof for T053-T067. The disaster-recovery register now follows the governing IaC layout: Azure modules belong in `terraform-azure-modules`, live Azure state is split into the six `fprd` domain roots, and T122 belongs to the rebuilt `shd/dns` and `fprd/security-irsa` owners. It also records the six-vCPU warm-standby scope, the Azure for Students ownership boundary, the economical backup-only Azure boundary, and follow-up tasks for ops#128 and the AKS inventory contract. T121 and T131 are recorded complete against the merged organization workflows. The preflight and per-root summaries contain counts, result lines, checksums, backup paths, and recorded Infracost figures only; no plan JSON, state, secret, resource ID, or ARN is copied into Git. ## Why The register still described legacy foundation and Azure layouts after the AWS estate was rebuilt and the DR workflows landed. Leaving those tasks unchanged would make successful applies look more complete than their retained evidence, would direct Azure work toward a forbidden local module and monolithic root, and would require an AKS capability inventory that cannot fit the verified student-subscription quota. This reconciliation applies constitution principles 12 and 13: DR scope stays truthful about quota and function, and tasks are ticked only against located and inspected artifacts. Successful infrastructure creation is annotated without claiming missing topology, economical-baseline, or acceptance evidence. ## Tasks - gitops `specs/009-full-platform-rollout` T052: completed against `evidence/runs/20260921T192300Z-full-profile-foundations/infrastructure/preflight.json`. - gitops `specs/009-full-platform-rollout` T053: partial; plan/cost/checksum records exist, topology and rollback-acceptance proof does not. - gitops `specs/009-full-platform-rollout` T054: partial; apply and backup records exist, output/route/flow-log/NAT/economical proof does not. - gitops `specs/009-full-platform-rollout` T055: partial; the three spoke plan records exist, the named network-topology proof does not. - gitops `specs/009-full-platform-rollout` T057: partial; exact-plan re-up and backups exist, route/flow-log/economical proof does not. - gitops `specs/009-full-platform-rollout` T058: partial; security roots were created, but Infracost and the named security/no-secret proof were not retained. - gitops `specs/009-full-platform-rollout` T059: partial; apply/checksum/receipt records exist, 2026-09-14 approval provenance, named outputs, and economical proof do not. - gitops `specs/009-full-platform-rollout` T060: partial; workload and IRSA passes exist, but the complete readiness/identity/lifecycle baseline does not. - gitops `specs/009-full-platform-rollout` T063: partial; root files exist, but the current gate's review/check/golden-render evidence does not. - gitops `specs/009-full-platform-rollout` T064: open; no audited bootstrap transcript exists. - gitops `specs/009-full-platform-rollout` T065: open; no post-bootstrap read-only root proof exists. - gitops `specs/009-full-platform-rollout` T066: open; no network-isolation evidence exists. - gitops `specs/009-full-platform-rollout` T067: open; no validated `evidence.json` or US2 acceptance exists. - gitops `specs/009-full-platform-rollout` T118: re-targeted to per-resource module tests in `terraform-azure-modules`; remains unchecked. - gitops `specs/009-full-platform-rollout` T119: re-targeted to the six Azure `fprd` domain-root tests; remains unchecked. - gitops `specs/009-full-platform-rollout` T120: completed artifact retained; its superseded complete-inventory assertion is assigned to T179. - gitops `specs/009-full-platform-rollout` T121: completed against the three merged workflow tests on MicroTodoSuite/.github `main`. - gitops `specs/009-full-platform-rollout` T122: re-targeted to the existing `shd/dns` and `fprd/security-irsa` roots; remains unchecked. - gitops `specs/009-full-platform-rollout` T125: re-targeted to independently released per-resource modules; remains unchecked. - gitops `specs/009-full-platform-rollout` T126: re-targeted to domain-split live roots consuming exact module tags; remains unchecked. - gitops `specs/009-full-platform-rollout` T131: completed against `mirror-to-acr.yml`, `mirror-platform-images.yml`, `sync-dr-secrets.yml`, and the DR routing in `promote.yml` on MicroTodoSuite/.github `main`. - gitops `specs/009-full-platform-rollout` T133: remains unchecked; its activation scope is reconciled to the minimum six-vCPU warm-standby inventory. - gitops `specs/009-full-platform-rollout` T178: added for the microservice-app-ops#128 rule-compliant rework. - gitops `specs/009-full-platform-rollout` T179: added for the test-first AKS inventory and planned-inventory update. T056, T061, and T062 remain unticked and unchanged as superseded work. The located artifacts for every task newly ticked by this pull request are: - T052: `evidence/runs/20260921T192300Z-full-profile-foundations/infrastructure/preflight.json`. - T121: `tests/workflows/{mirror-to-acr,mirror-platform-images,sync-dr-secrets}.bats` at MicroTodoSuite/.github merge `0624824`. - T131: `.github/workflows/{mirror-to-acr,mirror-platform-images,sync-dr-secrets,promote}.yml` at MicroTodoSuite/.github merge `0624824`. This pull request is the section 8 companion of [MicroTodoSuite/.github#31](MicroTodoSuite/.github#31). The preserved, closed prior attempt remains documented in [terraform-azure-modules#2](MicroTodoSuite/terraform-azure-modules#2), [terraform-azure-modules#3](MicroTodoSuite/terraform-azure-modules#3), [microservice-app-ops#124](MicroTodoSuite/microservice-app-ops#124), and [microservice-app-ops#127](MicroTodoSuite/microservice-app-ops#127). Those pull requests are not reopened. The currently open local-module [microservice-app-ops#128](MicroTodoSuite/microservice-app-ops#128) is reworked through T178. - [x] The task register is updated in this pull request - [x] Every task ticked here was verified by locating its artifact ## How it is verified The branch and carried work were inspected before editing: ```text git status --short --branch ## docs/reconcile-full-foundations-and-dr-scope...origin/docs/reconcile-full-foundations-and-dr-scope git log --oneline origin/main..HEAD 52417a1 docs(specs): reconcile the full-profile foundations and the dr scope da5454d docs(evidence): record the per-root full-profile foundation summaries d1849f6 docs(evidence): record the redacted full-profile preflight snapshot ``` The 13 first-creation plan JSON files and apply logs were inspected without copying their contents. Their managed action/result summaries are: ```text shd-networking: create=24; Apply complete! Resources: 24 added, 0 changed, 0 destroyed. fdev/fstg/fprd networking: create=28 each; 28 added, 0 changed, 0 destroyed. fdev/fstg/fprd security: create=31 each; 31 added, 0 changed, 0 destroyed. fdev/fstg/fprd workload: create=26 each; 26 added, 0 changed, 0 destroyed. fdev/fstg/fprd security-irsa: create=15 each; 15 added, 0 changed, 0 destroyed. ``` Every saved-plan and JSON checksum in the three 2026-09-21 lifecycle bundles was verified with `sha256sum -c`. The decisive action summaries were: ```text full-up-20260921T192817Z: shd-networking create=24 full-up-20260921T195633Z: shd create=2/no-op=22; each spoke create=7/no-op=21; each workload create=26 full-up-20260921T210444Z: each security-irsa create=15; every other root no-op ``` All committed evidence JSON files parse with `jq -e .`. The merged workflow contracts were then run from the MicroTodoSuite/.github checkout: ```text bash tests/workflows/mirror-to-acr.bats mirror-to-acr-contract: OK: production-validated input only ... bash tests/workflows/mirror-platform-images.bats mirror-contract: OK — OIDC-only dedicated-role mirror ... bash tests/workflows/sync-dr-secrets.bats sync-dr-secrets-contract: OK: OIDC-only AWS/Azure sessions ... ``` `git diff --check` is clean. A path guard confirms this pull request does not change `tests/profiles/aks-dr.bats`, `clusters/aks-dr`, or `experiments/`. MTS-IAC-102, PC-IAC-015, PC-IAC-022, constitution principles 12/13, the pull request/task conventions sections 7/8, ADR-0001, and the plan-reconciliation worked example were read before the register was changed. After the quota decision merges, T179 must change these exact `tests/profiles/aks-dr.bats` assertions in a separate test-first pull request: - `required_capabilities` must require only Istio, cert-manager, and External Secrets; the root's existing ArgoCD assertion remains. - The 18 deferred capabilities must be absent from the planned and activated AKS inventory, through `forbidden_capabilities` or an equivalent exact-inventory assertion. - The exact Prometheus destination-path assertion must be removed. - The Prometheus/Grafana `managed-csi` persistence loop must be removed because both capabilities are deferred. - The header comments and final PASS text that claim a complete equivalent full inventory must describe the minimum warm-standby inventory instead. - `clusters/aks-dr/planned-inventory.yaml` must match the revised assertions before T133 activation. The conventions validator was run locally with `PR_TITLE`, `PR_HEAD_BRANCH`, `PR_BODY`, and `CHANGED_FILES_FILE`; it returned `conventions: PASS`. - [ ] Infrastructure changes: the documentation consulted through the required MCP servers is listed above (N/A: this pull request changes evidence and the task register only, not Terraform, tfvars, or Kubernetes manifests) ## Risk and rollback The risk is documentary: a mistaken tick or scope decision could authorize later work from an inaccurate register. The conservative annotations keep tasks unchecked wherever their full text lacks retained proof, and the Azure implementation tasks remain unchecked until compliant artifacts merge. Rollback is a Git revert of this pull request. No live resource, cluster, workflow, or GitOps-managed path changes when these commits are reverted. ## What this PR does not do - It does not run a cloud command, mutate AWS or Azure, call `kubectl`, bootstrap ArgoCD, dispatch a workflow, or apply a Terraform plan. - It does not edit `tests/profiles/aks-dr.bats`, `clusters/aks-dr`, or `experiments/`. - It does not provide the missing T053-T067 topology, baseline, bootstrap, reachability, schema-validation, or acceptance evidence. - It does not merge, reopen, or modify terraform-azure-modules#2/#3 or microservice-app-ops#124/#127/#128. - It does not implement T118/T119/T125/T126, run T133, enable production traffic, or claim full-profile or DR acceptance. - It does not approve or merge this pull request; microservice-app-gitops requires one human approval.
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
What changes
Adds the disaster-recovery registry mirror and the secret seed as reusable workflows. None of them rebuilds, re-signs, or stores a credential.
mirror-to-acr.ymlcopies one production-validated service image's complete OCI graph (image, signatures, SBOM attestations) from ECR to ACR without rebuilding it. It proves the manifest digests are equal and verifies the signature in ACR against the service CI identity.mirror-platform-images.ymlnow also copies the complete, already-signed, locked platform graph from ECR to ACR. The copy uses AWS and Azure OIDC, runs no build and adds no re-signature, and the image, signature, and attestation digests stay equal.sync-dr-secrets.ymlseeds exactly the four mapped secrets into Azure Key Vault inside a GitHub environment. It masks early and disables tracing. Files are mode 0600 and removed by an EXIT trap. It keeps no cache, artifact, environment variable, or value output. The production-JWT equality check is an in-process boolean with no digest.promote.ymlroutes a promotion by destination, so only the production/full/aks-dr paths trigger the DR mirror.Why
Constitution principle 12 requires Azure to hold the same immutable production digest and off-provider recovery copies. These workflows move the artifacts and the secrets that the AKS disaster-recovery destination needs, without breaking the build-once, promote-by-digest chain.
Tasks
tests/workflows/{mirror-to-acr,mirror-platform-images,sync-dr-secrets}.bats, committed red in2fc0f31.promote.ymlintegration; all three contracts now pass.Register:
gitops specs/009-full-platform-rollout/tasks.md, updated in the companion microservice-app-gitops pull request opened by the lead (conventions §8). This pull request is the.githubhalf of that cross-repository change.How it is verified
Run locally, offline, from this branch's head:
One test correction, recorded here openly. The first red commit's service-mirror contract required
id-token: writeand also forbade the literaltoken:, which that permission contains, so no workflow could satisfy both.949bd92narrows the rule to what its comment states: the public GitOps checkout takes notoken:input. It now forbids a key named exactlytoken(^[[:space:]]*token:) and still requirespersist-credentials: false. No other assertion changed.Documentation consulted through the MCP servers (aws-knowledge, microsoft-learn, terraform):
No workflow was run, and no cloud or GitHub setting was touched.
microservice-app-ai-agents/rules/mcp.md)Risk and rollback
The new workflows run only when called.
promote.ymlgains destination routing, and the reusable-workflow contract still passes for the existing prod/staging paths. The DR paths need ACR and Key Vault, which do not exist until T128. Rollback is a revert.What this PR does not do
🤖 Generated with Claude Code