Repository navigation
Open
Labels
area/dev-infrakind/featureAn enhancement / feature request or implementationAn enhancement / feature request or implementation
Milestone
Description
Tracks the Boostrap Interface from Extensible Install Roadmap
Goal
Defines what the in-cluster bootstrap creates, so operators who disable it know exactly what to provide, and Helm and provider paths can drive it.
Owner: kustomize release workstream (#3169). Consumers: Helm workstream (#3170), GKE workstream (ai-on-gke/substrate-gke#70).
Working Specification:
| Object | Namespace | Type | Keys | Content | Semantics |
|---|---|---|---|---|---|
| actor-id-jwt-pool | ate-system | Opaque | pool, jwks | pool: JSON JWT-authority pool, one active key, ID = key thumbprint; ES256 (ECDSA P-256) default, RS256 (4096-bit RSA) optional. jwks: public JWK Set (JSON) | Create if absent; jwks recomputed from pool and updated when stale |
| actor-id-ca-pool | ate-system | kubernetes.io/tls | pool, tls.crt, tls.key | JSON CA pool; PEM root chain; PEM key; ECDSA P-256 (since #3251), 365-day root | Create if absent |
| actor-id-ca-certs | ate-system | Opaque | ca.crt | PEM root copied from actor-id-ca-pool | Create if absent |
| egress-mitm-ca-pool | ate-system | kubernetes.io/tls | pool, tls.crt, tls.key | JSON CA pool; ECDSA P-256 | Create if absent |
| service-dns-ca-pool | podcertificate-controller-system | kubernetes.io/tls | pool, tls.crt, tls.key | JSON CA pool; ED25519 | Create if absent |
| pod-identity-ca-pool | podcertificate-controller-system | kubernetes.io/tls | pool, tls.crt, tls.key | JSON CA pool; ED25519 | Create if absent |
| postgres-ca-pool | podcertificate-controller-system | kubernetes.io/tls | pool, tls.crt, tls.key | JSON CA pool; ED25519 | Create if absent |
| k8s-credential-provider-namespace-policy | ate-system | ConfigMap | namespace-policy.yaml | policies: [] | Create if absent |
- Not created by bootstrap:
- the settings objects in [FEATURE] Establish cluster-side install setting records #3172, which ship as manifests;
- bundled Postgres identities, which Postgres creates itself ([FEATURE] Extensible DB Identity Setup #3184).
- Image and command. The ate-setup image, running ate-setup bootstrap.
- Arguments.
- --database-mode=bundled|external, rendered from the same setting that selects bundled Postgres (Proposed name).
- --namespace; default ate-system.
- Guards. If ate-api-server-secret-envvars exists with a non-bundled connection string and the database mode is bundled, or if the separate owner login would be dropped, the Job exits non-zero before the control plane is applied. Exit codes:
- 0: success;
- 1: unexpected error;
- 2: guard refused the change.
- RBAC. Get and create on Secrets and ConfigMaps in both namespaces, update on actor-id-jwt-pool only, get on ate-api-server-secret-envvars. No pods/exec.
- Ordering. release/bootstrap/ includes the ate-system and podcertificate-controller-system namespaces. Under Helm, the RBAC and Job run as pre-install and pre-upgrade hooks with ordered weights ([FEATURE] Run the install bootstrap as Helm hooks #3685). The namespaces must not be hooks with
before-hook-creation: that policy deletes both namespaces, including the key pools, on every upgrade (see the 2026-11-05 comment). Open: create them from a create-if-missing Job at an earlier weight, or ship them ashelm.sh/resource-policy: keepobjects in a chart installed before the bootstrap. - Disabled mode. With bootstrap.enabled=false (Helm) or the bootstrap base omitted (kustomize), operators create every object in the first table themselves, with the same names, types, keys, and formats. The JSON pool formats are documented with an example generator command.
Consumers of these objects
| Consumer | Objects |
|---|---|
| podcertificate-controller | pool from the three signer pools |
| ate-api-server | pool from actor-id-jwt-pool and actor-id-ca-pool |
| ate-idp-server | pool from actor-id-jwt-pool (may change to the public JWKS, #3562) |
| atenet-egress | pool from egress-mitm-ca-pool; actor-id-ca-certs |
| k8s-credential-provider | The policy ConfigMap |
Open points
- Disabled mode: does it still run the read-only guards and the release-transition checks (Add pre-upgrade safety checks and reusable policy evaluation #2941, ate-setup: validate release transitions #3493)? Raised in the 2026-10-25 comment.
- The
ate-setupimage is not in the released image set today. The Job needs it, or a dedicated bootstrap image ([FEATURE] Release coordinates for images, bases, charts and binaries #3664).
Enforcement
- Running bootstrap twice changes nothing.
- A test cluster with pre-created objects starts with bootstrap disabled.
- The guard test exits
2on a forbidden switch.
Implementation: #3676. Related: #3273.
IMPORTANT: Working spec is a point-in-time analysis. Review latest changes.
Parent Issue: #3160
Metadata
Metadata
Assignees
Labels
area/dev-infrakind/featureAn enhancement / feature request or implementationAn enhancement / feature request or implementation
Activity
tryambak2019 commentedon Oct 25, 2026
Thanks Steven Shriver (@stshrive) for documenting this. One question remains unresolved between this issue and #2941.
Haven Xia (@HavenXia) proposed invoking release-transition validation from bootstrap so Helm and Kustomize upgrades cannot skip it.
Disabling the entire Job currently turns off two things:
Could disabled mode skip object creation and updates while still running the read-only safety checks?
QuentinBisson commentedon Nov 5, 2026
One concern with the ordering line: "Helm runs the namespace, RBAC, and Job as pre-install and pre-upgrade hooks, with weights -10, -5, and 0 and delete policy before-hook-creation."
As a hook, the Namespace object is deleted before every run.
before-hook-creationdeletes the object named in the hook's manifest, whoever created it, and waits for the deletion to finish before creating it again. It is also the default when a hook sets no delete policy (hookSetDeletePolicyinpkg/action/hooks.go, Helm 3 and 4). On everyhelm upgrade,ate-systemandpodcertificate-controller-systemwould be deleted with everything in them, including the CA and JWT pools the bootstrap promises to keep. A first install into a cluster where the namespaces already exist would delete them the same way.Two shapes avoid it:
getandcreateon namespaces, and the Roles at -5 then have somewhere to go.helm.sh/resource-policy: keepin a chart that installs before the bootstrap. Given the stage charts in [EPIC] Helm Chart Support for Substrate Base Installation #3170,agent-substrate-crdsor the first stage chart could hold them.The first keeps the bootstrap self-contained, and we run it that way today.