Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Certificates / TLS Backlog

Bounded implementation slice chain for the certificates/TLS track. It decomposes Certificates and TLS into dispatchable slices and is owned by the Certificates / TLS track in docs/tasks/README.md. The dispatchable records live under docs/tasks/; this file is the long-form decomposition and sequencing rationale.

Grounding

  • Certificates and TLS – the schema surface and Phase 1-9 ordering. Phases 1-2 are the near-term target; Phase 1 is Certificate / CertificateChain / TrustStore / CertVerifier over a RAM-only webpki-roots store and a rustls-webpki verifier. The Phase 2 client-only local proof now completes a TLS 1.3 handshake over a userspace-served TcpSocket cap with embedded-tls; the server/config service surface remains future Phase 2 work.
  • Cryptography and Key Management – partial implementation. The minimal SymmetricKey, PrivateKey, and PublicKey ABI, RAM-only XChaCha20+HMAC/P-256 key cores, RAM-only KeyVault handle custody, and development-only software KeySource bootstrap exist for local proofs. There is still no persistence or production custody source, so production/public TLS and ACME remain blocked on a reviewed source that can mint key handles without exposing raw private-key material.
  • Time and Clock AuthorityWallClock Phase 1 landed (88cf4b5d): a read cap with wallTime and a ClockProvenance label, but the fixed-boot-base source reports Untrusted. Cert-validity (notBefore/notAfter) and OIDC exp/iat compare against it. Host-tested verify logic passes an explicit atEpochSeconds and needs no live clock; security-grade validity against an adversarial clock wants the trusted-provenance upgrade (WallClock Phase 2). Recorded as a sequencing dependency on the live consumer slices, not on the host verifier slice.
  • Phase C Userspace NIC Driver Relocation – the userspace TcpSocket cap the TLS stack wraps arrives via Phase C slice-7 (cloud-prod-userspace-network-stack-smoltcp-local-proof). The TLS stack is a userspace consumer of that cap and must not move into the kernel.

Sequencing Rationale

The proposal’s suggested shape (library -> handshake -> cert caps -> consumer) is reordered to land the lowest-risk real logic first, grounded in what exists:

  • The verifier path (TrustStore + CertVerifier over webpki-roots) needs no socket and no private key – it is pure no_std + alloc host-testable logic. It lands before the handshake.
  • A TLS client handshake needs a TcpSocket cap but no private key.
  • A TLS server (the Web UI consumer) needs a KeyVault-issued PrivateKey handle and a server cert source, so it remains the most-blocked terminal slice.

Slice Chain

#TaskProposal phaseStatusDepends on
1cloud-tls-vendor-rustls-webpki-roots-no-std-provenancePhase 1 depsdone
2cloud-tls-cert-truststore-certverifier-phase1-host-proofPhase 1doneslice 1
3cloud-tls-client-handshake-over-tcpsocket-local-proofPhase 2 (client)doneslice 2 + Phase C slice-7 socket cap
4cloud-tls-self-hosted-webui-terminated-endpointPhase 2 (server) consumerblockedslice 3 + key-cap surface + provider-terminated GCE Web UI proof
K0crypto-key-custody-tls-acme-decompositionkey-management precursordone
K1crypto-privatekey-publickey-ram-signing-local-proofkey Phase 1 subsetdoneslice 2
K2crypto-keyvault-ram-privatekey-custody-local-proofkey Phase 2 subsetdoneK1
K3crypto-development-keysource-tls-acme-bootstrap-local-proofkey source local bootstrapdoneK2
5cloud-tls-acme-account-order-local-proofPhase 3 (ACME core)doneslice 3 + K3
6cloud-tls-acme-http01-challenge-solver-local-proofPhase 3 (http-01)doneslice 5 + Web UI L4 path
7cloud-tls-acme-renewal-certstore-rotation-local-proofPhase 3 (renewal)blockedslices 4-6
8cloud-gce-public-webui-letsencrypt-direct-termination-proofpublic GCE successorblockedprovider proof + slice 7 + public DNS/authorization
  1. Vendor the Phase-1 verifier crates. rustls-webpki + webpki-roots as static-pinned no_std+alloc snapshots with VENDORED_FROM.md provenance, recorded under docs/trusted-build-inputs.md, proved to build for the bare-metal target. Slice 3 later selected embedded-tls for the local client proof’s no_std TLS state machine; the broader server/config service stack remains future work.
  2. Certificate / TrustStore / CertVerifier (Phase 1). Schema additions plus host-tested verify logic over rustls-webpki seeded by webpki-roots, with chain verification proved against committed good/bad vectors and explicit atEpochSeconds. No running cap service, no socket, no key – the lowest-risk real cert logic.
  3. Client TLS handshake over TcpSocket (Phase 2, client-only). Done 2026-06-08. A userspace process completes one TLS 1.3 client handshake over the Phase C userspace TcpSocket cap, validating the peer chain with the slice-2 verifier, with an observable local QEMU proof. The no_std determination selected a vendored embedded-tls 0.19.0 client state machine for this local proof rather than full rustls.
  4. capOS-terminated Web UI endpoint (terminal consumer). Serves the Web UI over capOS-held TLS as a direct-termination successor after the first GCE public Web UI proof closes through provider-terminated HTTPS. Deeply blocked: needs a KeyVault-issued PrivateKey cap and a server cert source (ACME / provisioned).
  5. Minimal key-custody decomposition. Done. It decomposes the missing PrivateKey / KeyVault / KeySource subset into the three implementation records below, keeping production hardware/cloud custody out of the local TLS/ACME bootstrap.
  6. PrivateKey / PublicKey RAM signing proof. Done 2026-06-04. Adds the minimal asymmetric-key ABI and host-tested RAM signing core: sign/public/info, public verify/export/info, purpose metadata, and no raw private-key export.
  7. RAM KeyVault custody. Done 2026-06-05. Adds handle-based key generation/open/list/destroy and a local QEMU proof for TLS and ACME account key handles, still RAM-only and not production custody.
  8. Development-only KeySource bootstrap. Done 2026-06-05. Grants local proofs a development software key source that mints key handles without putting raw private keys in manifests, images, logs, task records, or evidence, and is rejected for production/public profiles.
  9. ACME account/order local proof. Done 2026-06-08. capos-tls now has a no_std+alloc ACME account/new-order/CSR-finalize/certificate-retrieval core, with ES256 JWS signing through AcmeAccount PrivateKey caps and CSR signing through a separate TLS-purpose PrivateKey cap. Challenge validation stays fake or pre-authorized here; the proof does not call Let’s Encrypt staging or production.
  10. Scoped http-01 solver. Done 2026-06-09. capos-tls adds a bounded, token-scoped Http01ChallengeSolver and the RFC 8555 http-01 authorization flow (pending order, authorization fetch, key-authorization derivation via the RFC 7638 account-key thumbprint, challenge response, out-of-band validation, and cleanup). remote-session-web-ui serves only /.well-known/acme-challenge/<token> for currently-published tokens through that same solver; retired, unknown, sub-path, and traversal tokens fail closed (404). The host ACME http-01 test proves the protocol and cleanup; the Web UI L4 QEMU proof fetches the challenge through the served origin. It grants no generic route, static-file, DNS, or Web UI authority and adds no public CA call.
  11. CertificateStore.watch renewal and rotation. Proves local renewal with short-lived test certificates, storing the fresh chain under a stable handle and rotating the Web UI TLS server without restart.
  12. Public GCE Let’s Encrypt direct-termination proof. A separately reviewed successor after the provider-managed first public proof. It requires a public DNS name controlled for the run, explicit billable/public-ingress authorization, and explicit authorization before any Let’s Encrypt production call; staging remains the default external CA target.

Let’s Encrypt / ACME Public TLS Decomposition

Let’s Encrypt support is implementable for the public TLS milestone only as the capability-native, capOS-terminated successor path. It is not the already selected closeout path for the first public GCE Web UI proof. That first proof continues to terminate HTTPS at the GCP external load balancer with a provider-managed certificate, no capOS private-key custody, and no raw public HTTP closeout.

The missing prerequisites are represented as named task records:

Local proofs and public CA/cloud proofs stay distinct. The ACME account/order, challenge, and renewal slices use a local RFC 8555-compatible directory and local QEMU/cloudboot paths. A public GCE/Let’s Encrypt run requires a separately authorized harness mode, a controlled public DNS name, public-ingress teardown evidence, and no private key material in manifests, images, logs, task records, or evidence directories.

Next Gap

Slices 1 and 2 landed on 2026-06-03: rustls-webpki and webpki-roots are vendored as static-pinned no_std+alloc snapshots, and capos-tls contains the Phase 1 Certificate / TrustStore / CertVerifier host verifier proof over those crates. K1 landed on 2026-06-04: capos-tls also contains the minimal RAM-only P-256 PrivateKey / PublicKey signing core. K2 landed on 2026-06-05: RAM-only KeyVault generation/open/list/destroy handle custody for those keys. K3 landed on 2026-06-05: local development software KeySource bootstrap now mints TLS and ACME account key handles without raw private-key material in manifests or evidence and rejects production/public profiles. Capability-infrastructure key-cap reconciliation landed on 2026-06-06: the minimal RAM-only SymmetricKey ABI and local AEAD/MAC proof now exist. Slice 3 landed on 2026-06-08: the local QEMU proof now completes one TLS 1.3 client handshake over a userspace-served TcpSocket cap and validates the peer chain with capos-tls. ACME slice 5 landed on 2026-06-08: capos-tls now proves account registration, order creation, CSR finalize, and returned-chain parsing against a local RFC 8555-style directory using purpose-scoped key caps. ACME slice 6 (proposal item 10) landed on 2026-06-09: the scoped http-01 solver now serves bounded /.well-known/acme-challenge/<token> responses through remote-session-web-ui, with the http-01 authorization/validation/cleanup flow proven host-side and the served route proven in the Web UI L4 QEMU proof. The next ACME gap is renewal and certificate-store rotation (slice 11). The next server-side TLS behavior gap remains the Web UI consumer, still blocked on reviewed server key custody and a certificate source. The behavior chain then advances slice-by-slice – each kernel/lib-first with a local proof – until the Web UI consumer slice can add a separately reviewed direct-termination successor after cloud-gce-public-self-hosted-webui-ingress-tls closes with provider-terminated HTTPS. The key-custody local-proof precursor is now complete for PrivateKey / PublicKey, RAM KeyVault, and development KeySource; production custody remains future.