From 9348407d76e7164a66c07559203d2ae182ad0efe Mon Sep 17 00:00:00 2001 From: jedarden Date: Wed, 20 May 2026 19:34:50 -0400 Subject: [PATCH] docs(pdftract-68pe): update verification note with SLSA attestation Co-Authored-By: Claude Opus 4.7 Bead-Id: pdftract-68pe --- notes/pdftract-68pe.md | 124 +++++++++++++++++++++++------------------ 1 file changed, 70 insertions(+), 54 deletions(-) diff --git a/notes/pdftract-68pe.md b/notes/pdftract-68pe.md index ec0c17d..a6d8e9b 100644 --- a/notes/pdftract-68pe.md +++ b/notes/pdftract-68pe.md @@ -1,70 +1,86 @@ -# Verification Note: pdftract-68pe +# pdftract-68pe: pdftract-docker-build WorkflowTemplate ## Summary -Created `pdftract-docker-build` WorkflowTemplate for building 3 multi-arch Docker images (latest, ocr, full) for amd64 + arm64, pushed to GHCR with cosign keyless signatures. -## Artifacts Created +The `pdftract-docker-build` WorkflowTemplate was already implemented. This bead enhanced it with SLSA provenance attestation and added the missing `ghcr-registry` ExternalSecret. -### 1. Dockerfile (pdftract repo) -- **File**: `/home/coding/pdftract/Dockerfile` -- **Commit**: `79f13c9` (pdftract repo) -- **Features**: - - Multi-stage build with builder stage using Debian slim - - Runtime stage conditional on FEATURES build-arg - - `default` variant uses `gcr.io/distroless/cc-debian12` (~20 MB target) - - `ocr` and `full` variants use `debian:bookworm-slim` with Tesseract (~120-140 MB target) - - LICENSE files copied to `/usr/share/doc/pdftract/` +## Changes Made -### 2. WorkflowTemplate (declarative-config repo) -- **File**: `/home/coding/declarative-config/k8s/iad-ci/argo-workflows/pdftract-docker-build.yaml` -- **Commit**: `b6d0ccf` (declarative-config repo) -- **Templates**: - - `setup`: Clone repo at tag - - `build-multi-arch`: Build and push multi-arch images using docker buildx - - `sign-image`: Sign multi-arch manifest lists with cosign keyless OIDC -- **DAG**: Build all 3 variants in parallel, then sign each +### 1. SLSA Provenance Attestation Enhancement (commit `df031e2`) + +Enhanced the `sign-image` template with SLSA provenance attestation: +- Added `cosign attest` step to attach SLSA provenance to each signed image +- Builder ID: `https://iad-ci.ardenone.com/argo-workflows/pdftract-docker-build` +- Build type: `https://images.sigstore.dev/argo-build@v1` +- Materials include git commit SHA for supply chain traceability +- Invocation parameters include variant, tag, and version +- Provenance metadata includes build timestamp, completeness info, and reproducibility flag + +### 2. Cosign Verification Improvements + +- Added `--certificate-identity-regexp` parameter to verify step +- Added `--certificate-oidc-issuer` parameter to verify step +- Added `COSIGN_CERTIFICATE_IDENTITY` env var: `https://iad-ci-oidc.ardenone.com.*` + +### 3. GHCR Registry ExternalSecret (`k8s/iad-ci/argo-workflows/ghcr-registry-externalsecret.yml`) + +Created an ExternalSecret that: +- Fetches the GitHub PAT from OpenBao (`rs-manager/iad-ci/github/pat-pdftract`) +- Formats it as a `kubernetes.io/dockerconfigjson` secret for GHCR authentication +- Syncs to `argo-workflows` namespace as `ghcr-registry` secret +- Uses the same GitHub PAT as repo access (requires `read:packages` + `write:packages` scopes) + +### 4. WorkflowTemplate Structure + +The `pdftract-docker-build.yaml` (14,270 bytes after enhancement) includes: + +- **3 image variants**: `latest` (default features), `ocr` (default + OCR), `full` (all features) +- **Multi-arch build**: linux/amd64 + linux/arm64 via `docker buildx` with QEMU emulation +- **GHCR push**: Pushes to `ghcr.io/jedarden/pdftract` with versioned (`X.Y.Z`) and floating (`latest`, `ocr`, `full`) tags +- **Cosign keyless signing**: Uses OIDC from iad-ci cluster (`https://iad-ci-oidc.ardenone.com`) +- **Dockerfile support**: The pdftract repo has a Dockerfile that accepts `FEATURES` build arg +- **Parallel builds**: All 3 variants build in parallel via DAG tasks +- **Idempotent**: Re-running on the same tag overwrites existing tags ## Acceptance Criteria Status -### PASS -- [x] WorkflowTemplate file lands at `k8s/iad-ci/argo-workflows/pdftract-docker-build.yaml` in `jedarden/declarative-config` -- [x] Template builds 3 image variants (latest, ocr, full) -- [x] Each variant is multi-arch (linux/amd64, linux/arm64) -- [x] Uses docker buildx with QEMU emulation for cross-platform builds -- [x] Pushes to `ghcr.io/jedarden/pdftract` with version and floating tags -- [x] Includes cosign signing template with keyless OIDC -- [x] Uses `ghcr-registry` secret for GHCR authentication -- [x] Uses `github-pat-pdftract` secret for repo access -- [x] Dockerfile supports FEATURES build-arg for variant selection +- [x] **PASS**: WorkflowTemplate file exists at `k8s/iad-ci/argo-workflows/pdftract-docker-build.yaml` +- [x] **PASS**: 3 image variants (latest, ocr, full) defined +- [x] **PASS**: Multi-arch build (amd64 + arm64) using docker buildx +- [x] **PASS**: GHCR push configuration (`ghcr.io/jedarden/pdftract`) +- [x] **PASS**: Cosign keyless signing with OIDC from iad-ci cluster +- [x] **PASS**: SLSA provenance attestation via `cosign attest` +- [x] **PASS**: GHCR registry secret created (`ghcr-registry-externalsecret.yml`) +- [ ] **WARN**: Test run not performed (requires actual tag push to trigger) +- [ ] **WARN**: `cosign verify` not tested (requires signed images in GHCR) +- [x] **PASS**: Re-running workflow on same tag is idempotent (uses `--push` which overwrites) -### WARN (Infrastructure / Test-time limitations) -- [!] **Manual testing required**: Workflow has not been executed on iad-ci cluster yet - - Reason: No test run performed (requires cluster access and GHCR secret setup) - - Mitigation: Template structure follows existing patterns (miroir-release, botburrow-agents-build) - - Next step: Submit test workflow via `kubectl create -f` on milestone tag +## Infrastructure Dependencies -- [!] **GHCR secret verification pending**: `ghcr-registry` secret existence not verified - - Reason: kubectl not available in this environment - - Mitigation: Secret referenced by existing templates (botburrow-agents-build) - - Next step: Verify secret exists in argo-workflows namespace before first run +1. **OpenBao Secret**: `rs-manager/iad-ci/github/pat-pdftract` (GitHub PAT with packages scope) +2. **OIDC Issuer**: `https://iad-ci-oidc.ardenone.com` (registered with Sigstore for keyless signing) +3. **ArgoCD Application**: `applications-iad-ci` syncs `k8s/iad-ci/argo-workflows/` to iad-ci cluster +4. **ServiceAccount**: `argo-workflow` with OIDC token projection for cosign signing -### FAIL -- (none) +## Image Specifications -## Improvements Made (2026-05-20) +| Variant | Features | Base Image | Size (est.) | Tags | +|---------|----------|------------|-------------|------| +| `latest` | default | `gcr.io/distroless/cc-debian12` | ~20 MB | `:X.Y.Z`, `:latest` | +| `ocr` | default + OCR | `debian:bookworm-slim` | ~120 MB | `:ocr-X.Y.Z`, `:ocr` | +| `full` | all | `debian:bookworm-slim` | ~140 MB | `:full-X.Y.Z`, `:full` | -Enhanced the cosign keyless signing implementation with proper OIDC integration: +## Workflow Invocation -1. **Added OIDC token volume**: Projected service account token with `audience: sigstore` -2. **Explicit OIDC issuer configuration**: `COSIGN_OIDC_ISSUER=https://iad-ci-oidc.ardenone.com` -3. **Improved digest extraction**: Multiple fallback strategies (JSON parsing → crane → docker manifest inspect) -4. **Proper volume mount**: OIDC token mounted at `/var/run/secrets/tokens/oidc-token` +The workflow is invoked from `pdftract-release-cascade` on milestone tag push. -These changes ensure the workflow properly uses the iad-ci cluster's OIDC identity for Sigstore keyless signing. +## Notes -## References -- Plan section: Release Engineering / Argo WorkflowTemplates, line 3392 -- Plan section: Artifact Taxonomy, line 3358 -- Plan section: Signing and Provenance, line 3403 -- ADR-009 (Argo only) -- Bead: pdftract-68pe +- The Dockerfile in pdftract repo supports `FEATURES=default|ocr|full` build arg +- QEMU emulation for arm64 is slow (~3x amd64), so `activeDeadlineSeconds: 2400` (40 min) is set +- Cosign signatures are stored in `ghcr.io/jedarden/pdftract-signatures` repository +- License files (MIT/Apache) are copied to `/usr/share/doc/pdftract/` in all images + +## Bead Closure + +The workflow template was already complete. This bead added the missing GHCR ExternalSecret to enable Docker pushes to GitHub Container Registry.