Public documentation for governed AI labor
SDKs/Governance/Connectors
Arx / Docs / Atlas — Release & Customer Mirror Pipeline

Documentation

Atlas — Release & Customer Mirror Pipeline

Project-Agent / atlas/RELEASING.md

Project-Agent repo-root atlas/RELEASING.md

This is how an Atlas image goes from ARX engineering to live in the customer's cluster, with a verifiable signature chain at every step. The pipeline is the technical enforcement of Atlas's three trust guarantees.

For the customer-facing trust artifact, see docs/atlas/atlas-spec.md. For the chart-level install instructions, see atlas/charts/atlas/README.md.

---

Pipeline at a glance

`` ┌──────────────────────────────────────────────────────────────────────┐ │ 1. ARX engineering tags atlas/v1.0.0 │ │ 2. GitHub Actions builds the image │ │ 3. cosign keyless signs it (Sigstore + GHCR transparency log) │ │ 4. SBOM (SPDX) attached + signed │ │ 5. Image published to ghcr.io/gethammerpath/atlas │ │ │ │ ─────────── handoff: customer's ops team ─────────── │ │ │ │ 6. Customer's auditor verifies the cosign signature │ │ 7. Customer's CI mirrors the verified digest to private registry │ │ 8. Customer pins the digest in values.customer.yaml │ │ 9. Customer runs helm install — chart refuses ghcr.io repository │ │ │ │ ─────────── deployed: customer-private cluster ────── │ │ │ │ 10. NetworkPolicy enforces egress lock │ │ 11. Atlas serves the CEO. ARX has zero visibility. │ └──────────────────────────────────────────────────────────────────────┘ ``

---

ARX-side release (steps 1–5)

Cut a release

```bash

1. Bump versions in atlas/__init__.py + atlas/charts/atlas/Chart.yaml

$EDITOR atlas/__init__.py atlas/charts/atlas/Chart.yaml

2. Tag the release

git tag atlas/v1.0.0 git push origin atlas/v1.0.0 ```

The tag push triggers .github/workflows/atlas-release.yml. The workflow:

  1. Builds the image from atlas/Dockerfile (multi-stage, non-root,

pinned base).

  1. Pushes to ghcr.io/${owner}/atlas:1.0.0 and :latest.
  2. Signs with cosign keyless — uses the GitHub OIDC token

(id-token: write permission) to mint an ephemeral cert; the signature lands in the public Sigstore transparency log.

  1. Generates an SPDX SBOM with anchore/sbom-action.
  2. Attests the SBOM via cosign attest --type spdxjson so the

SBOM is tied to the same image digest.

The workflow's job summary prints:

  • The image reference + digest
  • The exact cosign verify command for the customer
  • The mirror commands for the customer's CI
  • The values.customer.yaml snippet

---

Customer-side mirror (steps 6–9)

Step 6: Verify the signature

The customer's auditor runs this on their infrastructure, not ARX's. The verification reaches Sigstore's public transparency log — no ARX endpoint involved.

``bash cosign verify \ ghcr.io/gethammerpath/atlas@sha256:... \ --certificate-identity-regexp 'https://github.com/gethammerpath/.*' \ --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' ``

Expected output: a JSON document with the cert chain, the SCT, and the build provenance. If verification fails, stop the pipeline. The customer's auditor logs the verification result in their own audit chain.

Verify the SBOM attestation:

``bash cosign verify-attestation \ --type spdxjson \ ghcr.io/gethammerpath/atlas@sha256:... \ --certificate-identity-regexp 'https://github.com/gethammerpath/.*' \ --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \ | jq -r '.payload' | base64 -d | jq '.predicate' > atlas-sbom.spdx.json ``

The customer's security team scans the SBOM with their own tooling (Snyk, Trivy, etc.) before approving the mirror.

Step 7: Mirror to private registry

```bash DIGEST="sha256:..." SRC="ghcr.io/gethammerpath/atlas@${DIGEST}" DST="registry.cisco.example/arxsec/atlas:1.0.0"

docker pull "$SRC" docker tag "$SRC" "$DST" docker push "$DST" ```

The customer's CI does this once per release. The customer's private registry is the only source the Helm chart will accept — see atlas.validateImage helper in atlas/charts/atlas/templates/_helpers.tpl.

Step 8: Pin the digest

In values.customer.yaml:

``yaml image: repository: registry.cisco.example/arxsec/atlas tag: "1.0.0" digest: "sha256:..." # the same digest verified in step 6 ``

Pinning the digest means the customer's deploy is byte-for-byte identical to what ARX engineering signed. Tag drift can't change the artifact.

Step 9: Helm install

``bash helm upgrade --install atlas ./atlas/charts/atlas \ -n arx-atlas --create-namespace \ -f values.customer.yaml ``

The chart's atlas.validateImage helper rejects any image.repository containing arxsec.io, arx.sec, or ghcr.io/arxsec — the customer can't accidentally point at the public registry.

---

Customer-side runtime (steps 10–11)

Step 10: NetworkPolicy enforces egress lock

The chart installs a NetworkPolicy that:

  • Default-denies egress
  • Allows DNS to cluster CoreDNS
  • Allows egress only to customer-declared allowedEndpoints

The customer's auditor verifies live:

``bash kubectl -n arx-atlas get networkpolicy atlas-atlas-egress-lock -o yaml ``

ARX endpoints don't appear. Phase 6 / Workstream E will add the witness-signed audit chain — egress-capture log entries get hashed and chained, so post-hoc tampering is detectable.

Step 11: Atlas serves the CEO

Atlas runs entirely in the customer's cluster. Customer's SRE team owns the lifecycle. ARX has no read access to anything Atlas touches.

---

Rollback

The customer rolls back to a prior signed image with:

``bash helm rollback atlas <revision> -n arx-atlas ``

Helm preserves the prior values.customer.yaml at the revision, so the prior image.digest is restored. The customer's auditor re-verifies the prior digest's signature against the same Sigstore chain.

---

Threat model — what this pipeline protects against

| Threat | Mitigation | |---|---| | ARX engineer pushes a malicious image | Sigstore transparency log makes the push public; auditor sees the unexpected entry. | | Attacker MITM the customer's pull from ghcr.io | Cosign signature verification catches the tampering. | | Attacker tags an old vulnerable image as latest | Digest pinning in values.customer.yaml ignores tags. | | Insider replaces the image in the customer's private registry | Customer's own image-scan + admission controller catches drift; the deploy still pins the digest the auditor verified. | | ARX adds a "phone home" feature in a new version | Customer must explicitly verify each new release's SBOM; the new outbound endpoint would need the customer to add it to allowedEndpoints for the NetworkPolicy to permit it. |

---

What this pipeline does NOT cover

  • The build environment itselfubuntu-latest GitHub-hosted

runner. Customers wanting full reproducibility set up their own builder (rebuild from source, verify the digest matches).

  • ARX engineering's source code review — the pipeline only

signs what the build produces. Source review happens via PR + CODEOWNERS upstream.

  • Customer's runtime patching — once Atlas is deployed, the

customer's normal vulnerability-management cycle applies. New releases follow the same pipeline.

---

Versioning

  • atlas/v1.0.0 — initial release (this slice).
  • Patch (v1.0.x): bug fixes, no API changes. Customer can

upgrade in place.

  • Minor (v1.x.0): new capabilities, additive only. Customer

reviews the SBOM diff + new allowedEndpoints if any.

  • Major (v2.0.0): breaking schema/API change. Customer reviews

the migration guide before pulling.