Files
server-deploy/internal/aptrepo/README.md
T

91 lines
5.6 KiB
Markdown

# Staged Docker repository authentication
`deployctl verify-repository` accepts strict JSON with `directory` (absolute trusted
staging directory), `suite`, `architecture`, and `versions` (exact version strings
for docker-ce, docker-ce-cli, containerd.io, docker-buildx-plugin and
docker-compose-plugin). It does not select a latest version or resolve dependencies.
The directory must contain `docker.asc`, `Release`, `Release.gpg` and uncompressed
`Packages`. The caller obtains these from the Docker Ubuntu repository. No runtime
network request is performed by this command. Limits are 1 MiB, 1 MiB, 64 KiB and
16 MiB respectively. Files must be nonempty regular files; symlinks are rejected.
Trusted ancestors and absence of concurrent writers are required. This is not an
atomic filesystem snapshot against hostile writers. Additional staging files are
ignored, never executed.
## Trust and verification
1. Exact armored key SHA-256 is pinned in source. Initial trust was bootstrapped
from `https://download.docker.com/linux/ubuntu/gpg`, not supplied by the request.
Primary fingerprint: `9DC858229FC7DD38854AE2D88D81803C0EBFCD88`.
Rotation or formatting changes require a reviewed source update; fail closed.
2. Linux `/usr/bin/gpg` dearmors into a new private temporary directory; `/usr/bin/gpgv`
verifies the detached signature against the copied Release bytes, with that
keyring and isolated homedir. No shell, ambient GnuPG config or personal keyring.
Each child has a 15-second timeout and bounded output. Errors do not expose raw
GnuPG diagnostics or metadata. Non-Linux or missing tools fail closed.
3. Successful process exit and a single accepted primary-fingerprint signature
are required; weak digests, expired/revoked/bad signatures and unknown status
types fail closed. SHA-256/384/512 are accepted.
4. Authenticated Release must describe Docker CE and the requested supported Ubuntu
suite, architecture and stable component. Date must be within 30 days and no
more than 10 minutes in the future; Valid-Until is enforced when present.
5. The exact uncompressed stable Packages entry's SHA-256 and byte size must match.
Five explicitly requested versions are resolved to authenticated index records;
the derived lock is checked by installplan's source/path/version constraints.
The machine clock, OS and installed GnuPG are trusted. This is not a persistent
anti-rollback ledger: an older authentic Release inside the freshness window can
pass, and a missing Valid-Until is governed by the local 30-day policy. No online
key revocation lookup is performed. Key pin maintenance is an operator responsibility.
## Result boundaries
`repositoryAuthenticated: true` attests to these metadata bytes at `verifiedAt`.
For `verify-repository`, `packageBytesVerified: false` and `executable: false` remain explicit: no deb bytes,
Ubuntu dependency repository, dependency closure, installation scripts, system
compatibility or service behavior have been verified. The result is not a signed
capability. `plan-environment` still treats a supplied lock as untrusted and does
not accept a caller's authentication claim to clear its trust blockers.
Signature scratch data is removed on normal return; a killed process can leave its own
private temporary directory. Deployment writes remain disabled. `writesEnabled`
in `version` refers to deployment writes, not verification scratch files.
`scripts/probe-docker-repository.sh /absolute/path/to/deployctl` is an optional
local online integration check. It downloads public metadata over HTTPS into a
new temporary directory, tests real authentication and rejects tampering. Versions
selected by this test are fixtures, not recommended installation versions. It
does not install packages, alter APT, use SSH or touch application data.
## Verify actual deb bytes
`verify-artifacts` requires the same request fields as `verify-repository`, plus
`artifactDirectory`: an absolute trusted directory containing exactly the five deb
files named by the basename of each authenticated `Filename`. No other entries,
subdirectories, symlinks or special files are accepted. The two directories must
not be concurrently modified. Repository signatures and metadata are verified
anew in the same call; the command accepts neither a supplied lock nor trust flags.
Each file is streamed through SHA-256 with a 64 KiB copy buffer and its signed
index size as the read bound (plus one overflow-detection byte). The existing
lock policy caps each file at 512 MiB and requires exactly five files. A last-file
failure rejects the entire result. No partial successful report is emitted.
The verifier never unpacks a deb or executes its contents. It does not change
the staged files. Metadata identity checks supplement, not replace, the trusted
directory/no concurrent writer requirement.
Only `verify-artifacts` may set `packageBytesVerified: true`; `executable` stays
false. This verifies the selected five Docker package bytes, not the complete
Ubuntu dependency closure, package-internal safety or installation compatibility.
It is a point-in-time observation: do not reuse this JSON to authorize later
execution of paths that may have changed. A future installer must recheck or
own immutable verified snapshots under its operation lock.
Set `DEPLOYCTL_ONLINE_ARTIFACT_PROBE=1` along with
`DEPLOYCTL_ONLINE_REPOSITORY_PROBE=1` when running `scripts/verify-linux.sh` to
also download the five real public deb fixtures into a new local temporary
directory. The optional probe verifies all files, then changes one byte without
changing length and asserts rejection. It retains test files for inspection;
they are not installed and one is intentionally damaged by the negative test.