Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions charts/openab/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,13 @@ app.kubernetes.io/component: {{ .agent }}
{{- define "openab.persistenceEnabled" -}}
{{- if and . .persistence (eq (.persistence.enabled | toString) "false") }}false{{ else }}true{{ end }}
{{- end }}

{{/* Validate secretEnv entries: each must have name, secretName, and secretKey.
Call with: dict "secretEnv" $cfg.secretEnv "agentName" $name */}}
{{- define "openab.validateSecretEnv" -}}
{{- range .secretEnv }}
{{- if not (and .name .secretName .secretKey) }}
{{- fail (printf "agents.%s.secretEnv entries require name, secretName, and secretKey" $.agentName) }}
{{- end }}
{{- end }}
{{- end }}
12 changes: 10 additions & 2 deletions charts/openab/templates/configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,16 @@ data:
{{- if $cfg.env }}
env = { {{ $first := true }}{{ range $k, $v := $cfg.env }}{{ if not $first }}, {{ end }}{{ $k }} = {{ $v | toJson }}{{ $first = false }}{{ end }} }
{{- end }}
{{- if $cfg.inheritEnv }}
inherit_env = {{ $cfg.inheritEnv | toJson }}
{{- range $cfg.secretEnv }}
{{- if hasKey ($cfg.env | default dict) .name }}
{{- fail (printf "agents.%s.secretEnv key %q also exists in env — remove it from env to avoid plaintext secret in ConfigMap" $name .name) }}
{{- end }}
{{- end }}
{{- $secretEnvKeys := list }}
{{- range $cfg.secretEnv }}{{ $secretEnvKeys = append $secretEnvKeys .name }}{{ end }}
{{- $mergedInheritEnv := concat ($cfg.inheritEnv | default list) $secretEnvKeys | uniq }}
{{- if $mergedInheritEnv }}
inherit_env = {{ $mergedInheritEnv | toJson }}
{{- end }}

[pool]
Expand Down
8 changes: 8 additions & 0 deletions charts/openab/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ spec:
- name: {{ $k }}
value: {{ $v | quote }}
{{- end }}
{{- include "openab.validateSecretEnv" (dict "secretEnv" $cfg.secretEnv "agentName" $name) }}
{{- range $cfg.secretEnv }}
- name: {{ .name }}
valueFrom:
secretKeyRef:
name: {{ .secretName }}
key: {{ .secretKey }}
{{- end }}
{{- with $cfg.envFrom }}
envFrom:
{{- toYaml . | nindent 12 }}
Expand Down
78 changes: 78 additions & 0 deletions charts/openab/tests/secretenv_deployment_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
suite: secretEnv — Deployment rendering and field validation
templates:
- templates/deployment.yaml

tests:
# ── valueFrom.secretKeyRef rendering ──────────────────────────────────────

- it: renders secretEnv as valueFrom.secretKeyRef in Deployment
set:
agents.kiro.secretEnv:
- name: GEMINI_API_KEY
secretName: openab-secrets
secretKey: GEMINI_API_KEY
asserts:
- contains:
path: spec.template.spec.containers[0].env
content:
name: GEMINI_API_KEY
valueFrom:
secretKeyRef:
name: openab-secrets
key: GEMINI_API_KEY

- it: renders multiple secretEnv entries as separate secretKeyRef vars
set:
agents.kiro.secretEnv:
- name: GEMINI_API_KEY
secretName: openab-secrets
secretKey: GEMINI_API_KEY
- name: OPENAI_API_KEY
secretName: openab-secrets
secretKey: OPENAI_API_KEY
asserts:
- contains:
path: spec.template.spec.containers[0].env
content:
name: GEMINI_API_KEY
valueFrom:
secretKeyRef:
name: openab-secrets
key: GEMINI_API_KEY
- contains:
path: spec.template.spec.containers[0].env
content:
name: OPENAI_API_KEY
valueFrom:
secretKeyRef:
name: openab-secrets
key: OPENAI_API_KEY

# ── field validation guards ────────────────────────────────────────────────

- it: fails when secretEnv entry is missing secretKey
set:
agents.kiro.secretEnv:
- name: GEMINI_API_KEY
secretName: openab-secrets
asserts:
- failedTemplate:
errorPattern: "secretEnv entries require name, secretName, and secretKey"

- it: fails when secretEnv entry is missing secretName
set:
agents.kiro.secretEnv:
- name: GEMINI_API_KEY
secretKey: GEMINI_API_KEY
asserts:
- failedTemplate:
errorPattern: "secretEnv entries require name, secretName, and secretKey"

- it: fails when secretEnv entry is missing name
set:
agents.kiro.secretEnv:
- secretName: openab-secrets
secretKey: GEMINI_API_KEY
asserts:
- failedTemplate:
errorPattern: "secretEnv entries require name, secretName, and secretKey"
84 changes: 84 additions & 0 deletions charts/openab/tests/secretenv_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
suite: secretEnv — ConfigMap rendering (inherit_env merge, no plaintext)
templates:
- templates/configmap.yaml

tests:
# ── inherit_env merge ──────────────────────────────────────────────────────

- it: adds secretEnv key to inherit_env in ConfigMap
set:
agents.kiro.secretEnv:
- name: GEMINI_API_KEY
secretName: openab-secrets
secretKey: GEMINI_API_KEY
asserts:
- matchRegex:
path: data["config.toml"]
pattern: 'inherit_env = \["GEMINI_API_KEY"\]'

- it: does not render the secret value in ConfigMap
set:
agents.kiro.secretEnv:
- name: GEMINI_API_KEY
secretName: openab-secrets
secretKey: GEMINI_API_KEY
asserts:
- notMatchRegex:
path: data["config.toml"]
pattern: 'GEMINI_API_KEY\s*='

- it: merges secretEnv keys with existing inheritEnv and deduplicates
set:
agents.kiro.inheritEnv:
- GEMINI_API_KEY
- API_BASE_URL
agents.kiro.secretEnv:
- name: GEMINI_API_KEY
secretName: openab-secrets
secretKey: GEMINI_API_KEY
asserts:
- matchRegex:
path: data["config.toml"]
pattern: 'inherit_env = \[.*"GEMINI_API_KEY".*\]'
- matchRegex:
path: data["config.toml"]
pattern: 'inherit_env = \[.*"API_BASE_URL".*\]'
- notMatchRegex:
path: data["config.toml"]
pattern: '"GEMINI_API_KEY"[^"]*"GEMINI_API_KEY"'

- it: renders multiple secretEnv keys in inherit_env
set:
agents.kiro.secretEnv:
- name: GEMINI_API_KEY
secretName: openab-secrets
secretKey: GEMINI_API_KEY
- name: OPENAI_API_KEY
secretName: openab-secrets
secretKey: OPENAI_API_KEY
asserts:
- matchRegex:
path: data["config.toml"]
pattern: 'inherit_env = \["GEMINI_API_KEY","OPENAI_API_KEY"\]'

# ── conflict guard (env collision) ─────────────────────────────────────────

- it: fails when secretEnv key conflicts with env
set:
agents.kiro.env:
GEMINI_API_KEY: plaintext-value
agents.kiro.secretEnv:
- name: GEMINI_API_KEY
secretName: openab-secrets
secretKey: GEMINI_API_KEY
asserts:
- failedTemplate:
errorPattern: 'also exists in env'

# ── backward compat ────────────────────────────────────────────────────────

- it: does not render inherit_env when neither inheritEnv nor secretEnv is set
asserts:
- notMatchRegex:
path: data["config.toml"]
pattern: 'inherit_env'
11 changes: 11 additions & 0 deletions charts/openab/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ agents:
# nameOverride: ""
# env: {}
# envFrom: []
# # secretEnv: inject API keys from a Kubernetes Secret without storing them in the ConfigMap.
# # Each entry renders as valueFrom.secretKeyRef in the Deployment and auto-adds the key name
# # to inherit_env in config.toml. ⚠️ Do NOT also list the same key in env — use one or the other.
# # secretEnv:
# # - name: GEMINI_API_KEY
# # secretName: my-secrets
# # secretKey: GEMINI_API_KEY
# secretEnv: []
# pool:
# maxSessions: 10
# sessionTtlHours: 24
Expand Down Expand Up @@ -76,6 +84,7 @@ agents:
# workingDir: /home/node
# env: {}
# envFrom: []
# secretEnv: []
# pool:
# maxSessions: 10
# sessionTtlHours: 24
Expand Down Expand Up @@ -107,6 +116,7 @@ agents:
# workingDir: /home/agent
# env: {}
# envFrom: []
# secretEnv: []
# pool:
# maxSessions: 10
# sessionTtlHours: 24
Expand Down Expand Up @@ -178,6 +188,7 @@ agents:
workingDir: /home/agent
env: {}
envFrom: []
secretEnv: [] # list of {name, secretName, secretKey} — rendered as valueFrom.secretKeyRef; keys auto-added to inherit_env
pool:
maxSessions: 10
sessionTtlHours: 24
Expand Down
Loading