Availability boundary: this page defines the reviewed release contract. It does not claim that an Ardur image is public. Treat
STATUS.mdas the source of truth and use the pull commands below only after that status is updated with a verified registry digest.
The first supported OCI surface is the governance proxy:
ghcr.io/ardurai/ardur-proxy
Release automation creates only immutable version tags, such as v0.2.0 and
0.2.0. It does not create latest, branch, or moving major/minor tags. The
digest is the deployment identity and should be recorded in GitOps manifests:
docker pull ghcr.io/ardurai/ardur-proxy@sha256:<published-digest>The Personal Hub remains source-build-only and is outside this release contract.
| Property | Contract |
|---|---|
| Process user | UID/GID 65532:65532 |
| Listener | TCP 8443 on 0.0.0.0 |
| Persistent state | /home/ardur/.ardur |
| Health | GET /health and Docker HEALTHCHECK |
| Authentication | Required by default; inject VIBAP_API_TOKEN at runtime |
| TLS | Self-signed TLS by default; supply reviewed cert/key arguments for production |
| Root filesystem | Supports --read-only with the state path mounted writable |
| Linux privileges | No capabilities are required; use no-new-privileges |
Signing keys, session state, the TLS certificate, and the governance log all live under the state path. The directory must be writable by UID/GID 65532 and should use encrypted storage with access controls appropriate for signing-key material. Do not put API tokens, private keys, or development certificates in the image, build arguments, labels, or Kubernetes manifests.
Plain HTTP is supported only when a trusted local reverse proxy, sidecar, or
service mesh terminates TLS before traffic reaches the container. Append the
explicit --no-tls argument to the image command and set ARDUR_NO_TLS=1 so
the container healthcheck probes HTTP. The environment variable selects only
the healthcheck scheme; by itself it cannot disable proxy TLS. Bearer tokens
must not cross an unencrypted or untrusted network.
An equivalent hardened Docker invocation is:
docker run --rm \
--read-only \
--cap-drop ALL \
--security-opt no-new-privileges \
--tmpfs /tmp:rw,noexec,nosuid,nodev,size=16m \
--mount type=volume,src=ardur-data,dst=/home/ardur/.ardur \
--env VIBAP_API_TOKEN \
--publish 127.0.0.1:8443:8443 \
ghcr.io/ardurai/ardur-proxy@sha256:<published-digest>.github/workflows/oci-proxy.yml performs the following sequence:
- Validate that the release tag exactly matches the Python package version and
that the release commit is on
main. - Build a native image and run it with a read-only root filesystem, all Linux
capabilities dropped, and
no-new-privilegesenabled. - Prove public health, required bearer authentication, mission issuance,
session start, one
PERMIT, oneDENY, signed attestation, session end, and authenticated metrics. - Generate an SPDX JSON SBOM and a complete Trivy vulnerability/secret report.
- Stage amd64 and arm64 images by digest with BuildKit max-level provenance and SBOM attestations. Scan each exact digest before adding a registry tag.
- Create only the reviewed version tags after both platform scans pass, then verify that the public manifest contains exactly linux/amd64 and linux/arm64.
The publishing jobs use the repository GITHUB_TOKEN, not a registry PAT.
packages: write and id-token: write are job-scoped to release staging; pull
request and normal push jobs retain read-only repository permissions.
Every run stores the full scanner output, including findings with no vendor fix.
The blocking gate rejects embedded secrets and every HIGH or CRITICAL finding
for which a fixed package is available. Unfixed findings require review at the
protected ghcr environment before a release can proceed; they are not hidden
in a permanent ignore file.
The 2026-07-09 baseline on the digest-pinned Python 3.13.14 / Debian 13.5 image
reported no fixable HIGH or CRITICAL findings. It reported unfixed findings in
the following groups: util-linux (CVE-2026-53615), gzip
(CVE-2026-41992), libacl (CVE-2026-54369), ncurses
(CVE-2025-69720), and perl-base (CVE-2026-42496, CVE-2026-8376,
CVE-2026-42497, CVE-2026-48962, CVE-2026-9538). These are a dated
baseline, not a standing waiver. Review the retained JSON report and current
vendor status at every protected release approval.
The runtime restrictions reduce impact but do not prove those code paths are unreachable. Refresh the base digest promptly when Debian or the Python Official Image publishes fixes, then repeat the complete image smoke and platform scans.
- Keep release digests indefinitely unless a documented security revocation requires removal; deployments and attestations refer to them immutably.
- Bound retention for CI artifacts and untagged failed staging digests. The workflow retains ordinary scan artifacts for 14 days, release scan artifacts for 30 days, and digest handoff artifacts for one day.
- GHCR storage and egress are external operating costs. Measure pull volume and regional egress before broad distribution.
- Do not update Helm defaults or public install claims until the versioned digest is pullable without maintainer credentials and its manifest, attestations, health, and authenticated lifecycle have been independently verified.