Skip to content

feat: add OpenBao agent injector component#23

Open
Soypete wants to merge 1 commit intocatalystcommunity:mainfrom
Soypete:feat/openbao-agent-injector-clean
Open

feat: add OpenBao agent injector component#23
Soypete wants to merge 1 commit intocatalystcommunity:mainfrom
Soypete:feat/openbao-agent-injector-clean

Conversation

@Soypete
Copy link
Copy Markdown
Contributor

@Soypete Soypete commented Mar 27, 2026

Summary

  • Adds openbao-injector as a new foundry component (foundry component install openbao-injector)
  • Installs the OpenBao agent injector via Helm (injector-only, server.enabled=false)
  • Registers a MutatingWebhookConfiguration so pods with vault.hashicorp.com/agent-inject: "true" annotations automatically receive secrets mounted from OpenBao
  • Auto-detects the OpenBao address from stackConfig.GetPrimaryOpenBAOAddress()
  • Adds docs/pod-secrets.md covering pod annotation patterns, dash-compatible entrypoints, Kubernetes auth setup, and troubleshooting

Test plan

  • foundry component install openbao-injector succeeds
  • kubectl get mutatingwebhookconfigurations | grep openbao shows the webhook
  • Pod with vault.hashicorp.com/agent-inject: "true" annotation gets a vault-agent-init init container
  • After configuring Kubernetes auth in OpenBao, secrets appear at /vault/secrets/

🤖 Generated with Claude Code

Adds openbao-injector as a new foundry component that installs the
OpenBao agent injector via Helm. The injector registers a
MutatingWebhookConfiguration so pods annotated with
vault.hashicorp.com/agent-inject can receive secrets from OpenBao
at runtime without storing them in k8s Secrets.

Also adds docs/pod-secrets.md covering how to annotate pods, source
injected files in dash-compatible containers, and configure Kubernetes
auth in OpenBao.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@todpunk todpunk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good foundation — the component structure, Helm lifecycle handling (deploy/upgrade/failed cleanup), and dependency wiring all follow existing patterns well. ParseConfig uses GetString() correctly and the HelmClient interface matches what other components do.

A few things to address before merge:

Tests (blocking)
We need tests for every feature per project policy. At minimum: config parsing (defaults, overrides, missing external_vault_addr), install with mock helm client (fresh, upgrade, failed release cleanup), and error paths. Other components have this pattern that can be followed.

CSIL schema missing
types.gen.go has the "Code generated by csilgen; DO NOT EDIT" header but there's no .csil file in csil/v1/components/. Either the schema file was accidentally left out or the generated header is misleading — please add the schema and regenerate since none of these files should be altered by anything post generation.

OpenBao address error silently swallowed
In install.go, if GetPrimaryOpenBAOAddress() fails, the error is dropped and the user later gets a generic "external_vault_addr is required" message with no indication why auto-detection failed. Please surface the underlying error.

Hardcoded http:// and port 8200
fmt.Sprintf("http://%s:8200", addr) will break silently with TLS or non-default ports. Try deriving protocol/port from config rather than hardcoding. The rest of the stack should already have that in config.

Minor

  • Config should have a Validate() method called from ParseConfig() to match the pattern used by other components
  • Extra blank line after the openbaoInjectorComp registration in registry/init.go
  • Adding openbao-injector to the k8sComponents map re-aligned existing entries — just add the new line without changing whitespace on external-dns and velero

@@ -0,0 +1,11 @@
// Package openbaoinjector contains generated types.
//
// Code generated by csilgen; DO NOT EDIT.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's no .csil file in csil/v1/components/. Either the schema file was accidentally left out or the generated header is misleading — please add the schema and regenerate since none of these files should be altered by anything post generation

case "openbao-injector":
// Inject the OpenBao address so the webhook knows where to reach it
if addr, err := stackConfig.GetPrimaryOpenBAOAddress(); err == nil {
cfg["external_vault_addr"] = fmt.Sprintf("http://%s:8200", addr)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fmt.Sprintf("http://%s:8200", addr) will break silently with TLS or non-default ports. Try deriving protocol/port from config rather than hardcoding. The rest of the stack should already have that in config.

componentWithClients = velero.NewComponent(helmClient, k8sClient)
case "openbao-injector":
// Inject the OpenBao address so the webhook knows where to reach it
if addr, err := stackConfig.GetPrimaryOpenBAOAddress(); err == nil {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if GetPrimaryOpenBAOAddress() fails, the error is dropped and the user later gets a generic "external_vault_addr is required" message with no indication why auto-detection failed. Please surface the underlying error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants