feat(operator): spiffe-helper sidecar injection (proposal 011 PR-3) - #85
Merged
Conversation
3 tasks
Third PR of proposal 011 — when an AgentCollective has spec.spiffe.enabled=true, every agent pod gains a spiffe-helper sidecar that materialises the pod's X.509-SVID + JWT-SVID into a shared emptyDir. The agent container reads SVID files from there. Inert by design: pods are unchanged until an operator opts in. New operator/internal/reconcilers/collective/spiffe_sidecar.go: * ApplySpiffeSidecar(deploy, collective, helperCMName) mutates a built agent Deployment in place — adds the spiffe-helper container, three volumes (spiffe-svids emptyDir shared with the agent; spiffe-workload-api CSI volume exposing the SPIRE Agent Workload API socket; spiffe-helper-config ConfigMap), the spiffe.io/spire-managed-identity pod annotation, and the agent container's read mount + ACC_SVID_* env vars. No-op when SPIFFE is disabled. * RenderSpiffeHelperConfig() produces the helper.conf HCL that drives the sidecar (agent_address, cert_dir, jwt_svids with audience acc-role-update). * SpiffeEnabled() + SpiffeHelperConfigMapName() helpers, shared with the wiring in agent_deployment.go. agent_deployment.go changes: * ReconcileCollective upserts a per-collective spiffe-helper ConfigMap (<collective>-spiffe-helper) when SPIFFE is enabled. * reconcileRoleDeployment calls ApplySpiffeSidecar after building the base Deployment, before the Upsert. Test coverage: 6 unit tests in spiffe_sidecar_test.go covering SpiffeEnabled, helper.conf rendering, disabled-is-no-op, sidecar injection (containers/volumes/annotation/agent-env), helper container shape, and ConfigMap naming. contains() reused from role_catalogue_test.go (same package). Validated on lighthouse: go build ./... clean, full operator suite green. Stacked on spiffe/operator-controller (011 PR-2, PR #84). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
flg77
force-pushed
the
spiffe/agent-sidecar
branch
from
May 15, 2026 15:52
de26aa9 to
c87295d
Compare
flg77
added a commit
that referenced
this pull request
May 15, 2026
Second PR of proposal 012 — extends the operator-side SPIFFE
provisioning (011 PR-2) to edge deployments.
Inert by design: no behaviour change until an operator sets
deployMode=edge + spec.spiffe.
CRD changes (agentcollective_types.go + hand-updated CRD bases):
* SpiffeSpec gains EdgeTopology (nested | federated | ed25519,
default nested) + EdgeSiteID.
* AgentCollectiveStatus gains EdgeSiteID — echoes the site
qualifier baked into SpiffeID.
Reconciler (collective/spiffe.go):
* New computeSpiffeID() — when the owning AgentCorpus has
deployMode=edge AND spiffe.edgeTopology=nested, the SPIFFE ID
is site-qualified:
spiffe://<trust-domain>/edge/<site-id>/role/<collective>
Federated / ed25519 topologies + every non-edge deploy mode
keep the flat spiffe://<trust-domain>/role/<collective> form.
* nested topology without an edgeSiteID reports a config error
via SpiffeResult.Err -> status.spiffeError; never hard-fails
reconciliation.
* CollectiveReconciler.patchSpiffeStatus also patches EdgeSiteID.
Deploy manifests (deploy/edge-spire/):
* nested-spire-server.values.yaml — Helm values overlay for the
upstream spiffe/spire chart configured for nested topology
(edge SPIRE downstream of an rhoai parent). ACC does not
vendor SPIRE — operators helm-install it.
* edge-bundle-fetcher.yaml — PVC + CronJob caching the parent
SPIRE trust bundle every 6h for offline survival.
* README.md — install runbook + the edgeSiteID-uniqueness
requirement + the no-RWX fallback.
Test coverage: 5 unit tests in spiffe_edge_test.go covering the
site-qualified ID, the missing-edgeSiteID error path, federated
plain ID, non-edge topology-ignored, and ed25519 topology.
Validated on lighthouse: go build ./... clean, full operator
suite green.
Stacked on spiffe/agent-sidecar (011 PR-3, PR #85), which is
itself stacked on 011 PR-2 (#84).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
flg77
added a commit
that referenced
this pull request
May 15, 2026
Second PR of proposal 012 — extends the operator-side SPIFFE
provisioning (011 PR-2) to edge deployments.
Inert by design: no behaviour change until an operator sets
deployMode=edge + spec.spiffe.
CRD changes (agentcollective_types.go + hand-updated CRD bases):
* SpiffeSpec gains EdgeTopology (nested | federated | ed25519,
default nested) + EdgeSiteID.
* AgentCollectiveStatus gains EdgeSiteID — echoes the site
qualifier baked into SpiffeID.
Reconciler (collective/spiffe.go):
* New computeSpiffeID() — when the owning AgentCorpus has
deployMode=edge AND spiffe.edgeTopology=nested, the SPIFFE ID
is site-qualified:
spiffe://<trust-domain>/edge/<site-id>/role/<collective>
Federated / ed25519 topologies + every non-edge deploy mode
keep the flat spiffe://<trust-domain>/role/<collective> form.
* nested topology without an edgeSiteID reports a config error
via SpiffeResult.Err -> status.spiffeError; never hard-fails
reconciliation.
* CollectiveReconciler.patchSpiffeStatus also patches EdgeSiteID.
Deploy manifests (deploy/edge-spire/):
* nested-spire-server.values.yaml — Helm values overlay for the
upstream spiffe/spire chart configured for nested topology
(edge SPIRE downstream of an rhoai parent). ACC does not
vendor SPIRE — operators helm-install it.
* edge-bundle-fetcher.yaml — PVC + CronJob caching the parent
SPIRE trust bundle every 6h for offline survival.
* README.md — install runbook + the edgeSiteID-uniqueness
requirement + the no-RWX fallback.
Test coverage: 5 unit tests in spiffe_edge_test.go covering the
site-qualified ID, the missing-edgeSiteID error path, federated
plain ID, non-edge topology-ignored, and ed25519 topology.
Validated on lighthouse: go build ./... clean, full operator
suite green.
Stacked on spiffe/agent-sidecar (011 PR-3, PR #85), which is
itself stacked on 011 PR-2 (#84).
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 15, 2026
flg77
pushed a commit
that referenced
this pull request
Jun 15, 2026
…'t host-writable (#85) acc-deploy.sh apply <preset-with-required_packages> crashed with a raw PermissionError when the packages root (/var/lib/acc/packages) is the in-container acc-packages volume the host can't write — observed on the lighthouse edge stack. - registry: reads (list/find/find_by_name) no longer materialise the root; a read against a never-created root returns 'nothing installed' instead of raising. New non-destructive root_is_host_writable() probe. - collective pkg-install: when the spec declares required_packages but the root isn't host-writable, defer to in-container resolution with exit 20 (EXIT_PKG_ROOT_DEFERRED) + an actionable message naming the three provisioning surfaces (TUI Get pack / acc-deploy pkg add / infuse) — no traceback, no misleading ACC_ALLOW_UNSIGNED hint. - acc-deploy.sh: treats exit 20 as a soft-skip (apply continues; agents resolve roles from the in-container registry), other non-zero still aborts. - tests: tests/pkg/test_required_packages_host_degrade.py. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
flg77
added a commit
that referenced
this pull request
Jun 15, 2026
fix(acc-deploy/pkg): apply degrades gracefully when packages root isn't host-writable (#85)
flg77
pushed a commit
that referenced
this pull request
Jun 15, 2026
New how-to for collective.e2e-demo: build a Keycloak-secured stock-quotes web app (React + FastAPI, Yahoo Finance) reviewed before an RHOAI deploy, on external MaaS models. Covers: - the collective topology + collective_id=sol-01 rationale + MaaS/API-key handling (api_key_env + .env, never committed); - the end-to-end methodology (build -> redeploy -> install/infuse -> apply -> run), incl. why the acc-packages volume mount is required (#91); - package install / role INFUSION in depth — AutoMode assistant ([PROPOSE_INFUSE] -> always Compliance-gated even under AUTO -> spawn) vs Manual (pkg add / infuse --from-pkg / TUI Get-pack), plus the lighthouse reality (#85 host-can't-write, signed install-from-file with cosign, catalog #92); - prompt techniques + reasoning: the reviewer verdict contract, that depends_on sequences but does NOT thread step outputs (use the inline critic loop or KNOWLEDGE_SHARE, not {step:X}), model-to-job matching, and writing specific task_descriptions so mid-size models don't ramble; - a field troubleshooting table (dormant cells, 401, no-catalog, etc.). Linked from DEMOS.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Summary
Third PR of proposal 011. When an
AgentCollectivehasspec.spiffe.enabled: true, every agent pod gains aspiffe-helpersidecar that materialises the pod's X.509-SVID + JWT-SVID into a sharedemptyDir. The agent container reads SVID files from there — no agent code change beyond the env vars the operator now sets.Stacked on #84 (011 PR-2) — base is
spiffe/operator-controller. Merge #84 first, then retarget this tomain.Inert by design — pods are unchanged until an operator sets
spec.spiffe.enabled.What's new
operator/internal/reconcilers/collective/spiffe_sidecar.go:ApplySpiffeSidecar(deploy, collective, helperCMName)mutates a built agentDeployment: adds thespiffe-helpercontainer, three volumes (spiffe-svidsemptyDir shared with the agent;spiffe-workload-apiCSI volume exposing the SPIRE Agent Workload API socket;spiffe-helper-configConfigMap), thespiffe.io/spire-managed-identitypod annotation, and the agent container's read mount +ACC_SVID_*env vars. No-op when SPIFFE disabled.RenderSpiffeHelperConfig()produces thehelper.confHCL (agent_address,cert_dir,jwt_svidswith audienceacc-role-update).SpiffeEnabled()+SpiffeHelperConfigMapName()helpers.agent_deployment.go:ReconcileCollectiveupserts a per-collective<collective>-spiffe-helperConfigMap when SPIFFE is enabled.reconcileRoleDeploymentcallsApplySpiffeSidecarafter building the base Deployment.Test plan
go build ./...clean — validated on lighthousespiffe_sidecar_test.go—SpiffeEnabled,helper.confrendering, disabled-is-no-op, sidecar injection, helper-container shape, ConfigMap namingProposal 011 reference
011 - SPIFFE workload identity for ACC agents.md. PR-1 #81 merged; PR-2 #84 open. PR-4 (agent-side verifier) next.🤖 Generated with Claude Code