pki: the StarshipOS CA, made on the CI box; capsules signed in CI
Ruled by Captain Bob, 2026-11-07: "New root CA on the CI box. Valid StarshipOS rather than snake oil intermediate." - ci/pki/make-ca.sh makes the StarshipOS Root CA (its key stays on the CI box) and the StarshipOS Capsule Signing intermediate it issues, and stores the signing key as the secret CAPSULE_SIGN_KEY. - The kernel finds the signing certificate by one name, CAPSULE_SIGNING_CERT_NAME = pki:starshipos-intermediate.der. The certificate itself lands once make-ca.sh has run; until then the snakeoil intermediate is in the tree under its old name and the capsules check as "no root key" (a warning, as "missing" was). - mkcapsule refuses a signing key that is not that certificate's. - SIGN_KEY has no default; acceptance, build, nightly and release set it from the secret. FABRIC-3.md XLVI. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GE3SDvQn5EoxdGufk84zz2
This commit is contained in:
@@ -6061,3 +6061,47 @@ four conflicts resolved to the branch's files (`92ca805e`).
|
||||
- The first scheduled nightly's publish to Nexus (#17).
|
||||
- The Pi 5 and Mars images booted on their boards (#27, #28); a Pi 4 port (#26).
|
||||
- Revoke the access token `claude-session-20261106` (Settings, Applications).
|
||||
|
||||
## XLVI. The StarshipOS CA: capsules signed in CI, by a root on the CI box (2026-11-07)
|
||||
|
||||
### 1. Found
|
||||
|
||||
Every image built anywhere but Captain Bob's machine carried unsigned capsules: CI, the
|
||||
acceptance runs, the nightly bound for Nexus, a release, the demo. The capsule-signing key -- the
|
||||
snakeoil intermediate of the offline LithosAnanke Root CA (FABRIC-2.md, Milestone 6) -- lived only
|
||||
there, `kernel/Makefile`'s `SIGN_KEY` named its path, and a missing signature is a warning by
|
||||
design (2026-08-26), so they booted: `V4: capsule v4:sys:core.f18 signature: missing (unsigned)`
|
||||
in every accepted log (`logs/20261106-004933`). And `mkcapsule` signed with whatever key it was
|
||||
given: a key that is not the embedded certificate's makes every signature INVALID, which refuses
|
||||
Mama.
|
||||
|
||||
### 2. Ruled
|
||||
|
||||
Captain Bob, 2026-11-07: "New root CA on the CI box. Valid StarshipOS rather than snake oil
|
||||
intermediate."
|
||||
|
||||
### 3. Built
|
||||
|
||||
- `ci/pki/make-ca.sh`, run once on the CI box: **StarshipOS Root CA** (Ed25519, 20 years,
|
||||
self-signed; its key stays on that box, in `/var/lib/starshipos-ca`) and **StarshipOS Capsule
|
||||
Signing** (Ed25519, 10 years, issued by the root, `CA:TRUE, pathlen:0`). It refuses to
|
||||
overwrite a CA, prints both certificates, and stores the signing key as the repository secret
|
||||
`CAPSULE_SIGN_KEY` (or says how).
|
||||
- The image carries `capsules/pki/starshipos-intermediate.der` in place of the snakeoil
|
||||
intermediate; the kernel finds it by one name, `CAPSULE_SIGNING_CERT_NAME` (`capsule_sig.h`).
|
||||
- `mkcapsule` checks the signing key against that certificate before it writes anything, and
|
||||
refuses a key that is not its, or a key with no certificate to check.
|
||||
- `SIGN_KEY` has no default (`kernel/Makefile`, `v4/Makefile`): CI sets it from the secret (a step
|
||||
in `acceptance.yml`, `build.yml`, `nightly.yml`, `release.yml`); unset, the capsules are built
|
||||
unsigned, as before.
|
||||
|
||||
What it is not: the kernel still does not check the intermediate against a root at boot
|
||||
(`x509_ed25519.h`; `ACL.4th`'s `ACL-CA-KEY` is still 0). A signature proves a capsule matches the
|
||||
certificate in the same image. That is unchanged by this, and a ruling of its own.
|
||||
|
||||
### 4. Verified
|
||||
|
||||
With a CA made by `make-ca.sh` in a scratch directory (not the real one): `openssl verify` of the
|
||||
chain OK; `make-ca.sh` refuses a second run; `mkcapsule` with the signing key -- "signing key
|
||||
matches"; with the root's key -- refused; with a key and no certificate -- refused; with no key --
|
||||
unsigned, as before. The acceptance with the real certificate is the PR's.
|
||||
|
||||
Reference in New Issue
Block a user