0pt had no SBOM/sign/digest chain at all (re-confirmed live before this change: no cosign/syft/sbom hit anywhere under .gitea/workflows/, only doc mentions in CHANGELOG.md/docs/architecture/ARCHITECTURE.md). Applies the same two-part pattern already proven on sax3l/cl0ud and sax3l/st0re (fix/wire-signed-digest-to-deploy, 2026-09-14): 1. .gitea/workflows/release.yml (new): builds the image, pushes it to git.cloud.siax.io/sax3l/0pt:sha-<12>, SBOMs it (syft), signs it (cosign, key-based), verifies the signature in the same run, and commits source-bundle/production-evidence records back to the repo. 2. .gitea/workflows/cd.yml: the `deploy` job now polls the registry for this exact commit's release-chain image and cosign-verifies it (against the committed cosign.pub) before calling Coolify's deploy endpoint -- fails closed (10 min timeout) if release.yml never produced a verifiable artifact for this sha. Added AFTER the existing guard step, which still fails closed first on 0pt's real, pre-existing blocker: no Coolify Application is provisioned for 0pt yet (COOLIFY_APP_ID is a literal placeholder). This gate is wired ahead of that so it's already in place the day the app is provisioned, instead of a second follow-up change. Honest limitation carried over from cl0ud/st0re/h0st: once provisioned, 0pt's Coolify Application is expected to use the `dockerfile` build pack (per siax.config.json), so Coolify would still perform its own independent docker build rather than pulling the signed image, and /api/v1/deploy has no digest parameter to pin against -- true digest-pinning needs a production Coolify resource-type decision, out of CI-YAML scope. This gate proves a signed, verified build of the exact commit exists before authorizing any deploy call; it does not prove byte-identical output from Coolify's own rebuild. cosign.pub is a fresh, 0pt-specific keypair generated offline for this change. NOT YET SET on sax3l/0pt (release.yml/cd.yml's gate will fail closed until present): REGISTRY_USER, REGISTRY_TOKEN, COSIGN_PRIVATE_KEY, COSIGN_PASSWORD, SIAX_CI_TOKEN repo secrets. Validated without live Coolify/registry access: YAML-parsed all 2 files, bash -n syntax-checked all 19 embedded run: blocks, and dry-ran the actual verification logic -- the RepoDigests filter and bounded poll-retry loop against mocked scenarios, plus a real cosign sign+verify round-trip (offline signing-config, local throwaway registry container) proving the gate's cosign verify command genuinely passes on the correct key/digest and fails closed on a wrong key and on an unsigned image. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
3.2 KiB
Runbook: Deploy — 0pt
Mål: sätta 0pt.app på SIAX-flottan (Coolify) och avveckla Vercel i ordning. Status 2026-08-10:
siax.config.jsondeklarerartarget: coolify; ingen Coolify-app provisionerad; live-instansen körs fortfarande på Vercel.
1. Förutsättningar (blockerare för cutover)
- Coolify-app provisionerad i
cloud.siax.io(build_pack: dockerfile, repogit.siax.io/sax3l/0pt, grenmain). COOLIFY_APP_ID(appens UUID) ifylld i.gitea/workflows/cd.yml.COOLIFY_TOKEN-secret satt på repot (Gitea → Settings → Actions → Secrets).- Env-secrets inlagda i Coolify-appen från Infisical-projektet
0pt(se backup/restore + incident runbooks). - DNS-cutover planerad:
0pt.app→ Coolify-appens ingress (eller Caddy).
1b. Signerad-artefakt-grind (tillagd 2026-09-14, samma mönster som cl0ud/st0re/h0st)
.gitea/workflows/release.yml (nytt) bygger, SBOM:ar (syft), signerar
(cosign) och evidensbokför varje push till main, och pushar till
git.cloud.siax.io/sax3l/0pt:sha-<12>. cd.ymls deploy-jobb har nu ett
extra steg (efter guard-steget i punkt 1 ovan) som kräver att exakt denna
commits avbildning finns i registret och att dess cosign-signatur
verifierar (mot committad cosign.pub) innan Coolify överhuvudtaget
anropas.
Detta är byggt FÖRE Coolify-appen finns (se blockerarna i punkt 1) — så att
grinden redan är på plats den dag appen provisioneras, i stället för att bli
ett separat uppföljningsarbete. Samma ärliga begränsning som cl0ud/st0re/
h0st: när appen väl provisioneras som dockerfile build pack (så som
siax.config.json föreskriver) kör Coolify sin EGEN oberoende
docker build från git-källan, inte den signerade avbildningen —
/api/v1/deploy saknar digest-parameter helt. Sann digest-pinning skulle
kräva att appen provisioneras som Coolifys separata dockerimage-resurstyp
i stället, ett beslut som inte är fattat än. Se .gitea/workflows/cd.ymls
"SIGNED-ARTIFACT GATE"-kommentar för den fullständiga skrivningen.
Inte satt på sax3l/0pt ännu: repo-secrets REGISTRY_USER,
REGISTRY_TOKEN, COSIGN_PRIVATE_KEY, COSIGN_PASSWORD, SIAX_CI_TOKEN —
release.yml fail-closed:ar på sin första körning tills dessa finns.
2. Deploy (när appen finns)
- Push till
main→.gitea/workflows/cd.ymlPOSTar tillhttps://cloud.siax.io/api/v1/deploy?uuid=$COOLIFY_APP_ID&force=false, efter att den signerade-artefakt-grinden i punkt 1b gått grön. - Följ run i Gitea Actions; verifiera att den slutar grön.
- Verifiera hälsa:
curl https://0pt.app/api/health→ok:trueochdb: configured(när Postgres kopplats in).
3. Manuell redeploy (nöd)
curl -fsS -X POST "https://cloud.siax.io/api/v1/deploy?uuid=<UUID>&force=true" \
-H "Authorization: Bearer $COOLIFY_TOKEN"
4. Vercel-avveckling (EFFER att Coolify kör stabilt)
- Verifiera att ingen verklig trafik/data ligger bakom (2026-08-10:
/api/healthvisardb/queue: not_configured— marknads-/dev-läge). - Peka DNS om till Coolify. 3. Behåll Vercel-projektet tills certifierad paritet (katalog, orderflöde, betalningar). 4. Avveckla först därefter.