Add actorIdentityToken as a SystemInfo volume data source - #1114
Draft
Max Thompson (thompsonmax) wants to merge 3 commits into
Draft
Add actorIdentityToken as a SystemInfo volume data source#1114Max Thompson (thompsonmax) wants to merge 3 commits into
Max Thompson (thompsonmax) wants to merge 3 commits into
Conversation
A trustBundle data source projects the trust anchors of a named trust bundle to a PEM file in the volume — inspired by the Kubernetes clusterTrustBundle projected volume source, but source-neutral: the template names a bundle, and where it is fetched from is a deployment concern behind ateapi, not part of the API (agent-substrate#932). Supported names are allowlisted in ateapi rather than the CRD schema, so the eventual configurable backend registry widens them without an API change. Initially the only supported bundle is egress-mitm.ate.dev (the egress gateway CA bundle, agent-substrate#823), resolved from the ClusterTrustBundle that atecontroller's EgressMITMTrustReconciler (agent-substrate#946) derives from the egress-mitm-ca-pool Secret — the signer-linked object name (egress-mitm.ate.dev:mitm:primary-bundle) is a backend detail the allowlist mapping keeps out of the template API. Resolution goes through an informer-backed lister and sanitizes the way kubelet sanitizes projections: CERTIFICATE blocks only, deduplicated, headers stripped (internal/pemutil). The wire spec carries only {path, pem_bundle} resolved bytes; atelet writes them at a stable path with the per-file temp+rename discipline (find-paths safe) and never talks to any bundle backend. Actor start fails closed, naming the bundle, when the name is not allowlisted, the backend is unavailable in this deployment (certificates.k8s.io/v1beta1 is feature-gated; ateapi probes at startup and degrades instead of hanging), or the bundle is missing, empty, or free of certificates. The identity e2e drives the real chain end to end: it provisions the egress-mitm-ca-pool Secret, waits for the reconciler to publish the derived bundle, asserts the projected file in both CI lanes, then rotates the pool and asserts a resumed actor observes the new contents at the same path — writing the bundle directly is not an option, since the reconciler reverts or deletes hand-written contents. Bundle contents refresh on every Run/Restore; live refresh for running actors is agent-substrate#932 PR 2. ateapi gains RBAC to read clustertrustbundles.certificates.k8s.io.
…ed bundle The identity suite verifies trust-anchor DELIVERY (pool -> reconciler -> bundle -> resolution -> projection); this adds the CONSUMPTION half for agent-substrate#871: an actor completes a TLS handshake with the sdsmint egress gateway's per-SNI minted leaf using ONLY the anchors projected through its trustBundle SystemInfo volume — on both sandbox classes, since delivery differs per class (gVisor RO bind vs the micro-VM unified virtio-fs share). The probe gains /fetch?url=&roots=bundle|system, which GETs over the actor's normal egress path with TLS roots from the projected bundle or the image's system roots. The new egressmitm suite asserts the pair that makes the result unambiguous: roots=bundle succeeds (and would fail under a passthrough gateway, whose relayed public certificates the bundle cannot validate — so a pass also certifies interception is on), while roots=system fails certificate verification (the minted leaf chains to no public CA; under passthrough it would succeed). The sdsmint gateway variant replaces the passthrough gateway cluster-wide, so CI deploys it as a separate step after both standard lanes and runs only this suite against it — once per sandbox class, gated by E2E_EGRESS_MITM. The suite ensures (never replaces) the CA pool: sdsmintd signs with the pool mounted into the gateway pod, and replacing it would race kubelet's Secret propagation into that mount.
Part 2 of agent-substrate#802: a data source that projects a signed JWT attesting the actor's identity to a file — analogous to the Kubernetes serviceAccountToken projected volume source: - actorIdentityToken: audience: some-verifier.example.com expirationSeconds: 3600 # default 3600, min 600, max 86400 path: token ateapi mints the token on the resume path, immediately before the spec is sent to atelet, so the mint is inherently bound to the activation: ateapi is placing this actor at this moment, no separate authorization exchange needed. Claims mirror actoridentity.MintJWT (same issuer, subject shape, and ate.dev claim object) so verifiers need one code path; audience and TTL come from the template. The wire spec carries only {path, token} minted bytes; atelet writes them at a stable path with the per-file temp+rename discipline and never mints. Tokens are re-minted on every Run/Restore: a resumed actor always carries a token for its own, current activation (fresh iat/jti — the e2e asserts a resume changes the token), and a token captured into a snapshot expires quickly and cannot be renewed from elsewhere, per the SystemInfo leakage model in agent-substrate#802. Live re-minting for actors that outlive expirationSeconds is deliberately deferred to the shared live-refresh mechanism (agent-substrate#932 PR 2 tracks the transport). Fails closed, naming the flag, when the deployment runs ateapi without an actor JWT signing pool. The identity e2e projects a token in both CI lanes and asserts the claims bind to the right actor and audience, the token is unexpired, and a suspend/resume re-mints it while identity stays fixed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part 2 of #802 (stacked on #941 — shows a combined diff until that merges. The new work is the single commit "Add actorIdentityToken as a SystemInfo volume data source").
Projects a signed JWT attesting the actor's identity, analogous to the serviceAccountToken projected volume source. ateapi mints on the resume path so the token is inherently activation-bound; claims mirror actoridentity.MintJWT so verifiers need one code path; the wire carries only minted bytes and atelet just writes them (find-paths-safe rename discipline). Re-minted on every Run/Restore — the e2e asserts a resume produces a fresh token — and snapshot-captured tokens expire quickly and can't be renewed elsewhere, per #802's leakage model. Fails closed without a signing pool. Live re-minting for long-running actors is deferred to the shared live-refresh mechanism (#932 PR 2).