From 90bc58cbda002d4d9d9efbac35239511a463b3e2 Mon Sep 17 00:00:00 2001 From: yen <5915590+antigenius0910@users.noreply.github.com> Date: Sat, 23 May 2026 08:42:51 -0500 Subject: [PATCH 1/2] feat(chart): add serviceAccountName support at per-agent and global level MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per-agent value (agents..serviceAccountName) wins when set; otherwise falls back to chart-global $.Values.serviceAccountName. Both empty preserves current behaviour (no serviceAccountName rendered, Kubernetes uses cluster default SA). This is required to activate IRSA on EKS — without an explicit serviceAccountName, the pod-identity-webhook never injects AWS credentials and workloads silently fall back to the broad EC2 node role, breaking least-privilege. Scope: string reference to an existing SA only. The chart does NOT create a new SA or manage IRSA annotations (operators provision out-of-band via Terraform / IDP / kubectl), matching how PR #901 (existingSecret) and #910 (imagePullSecrets) reference existing K8s resources rather than creating them. Closes #913 --- charts/openab/README.md | 2 + charts/openab/templates/deployment.yaml | 4 ++ charts/openab/tests/serviceaccount_test.yaml | 51 ++++++++++++++++++++ charts/openab/values.yaml | 14 ++++++ 4 files changed, 71 insertions(+) create mode 100644 charts/openab/tests/serviceaccount_test.yaml diff --git a/charts/openab/README.md b/charts/openab/README.md index 1ef465392..8e472814f 100644 --- a/charts/openab/README.md +++ b/charts/openab/README.md @@ -12,6 +12,7 @@ This page highlights commonly used values and deployment patterns. For the compl |-------|-------------|---------| | `nameOverride` | Override the chart name portion used in generated resource names. For per-agent resource names, use `agents..nameOverride`. | `""` | | `fullnameOverride` | Override the full generated release name for chart resources. Useful when deploying multiple instances with predictable names. | `""` | +| `serviceAccountName` | Chart-global ServiceAccount name attached to every agent pod that doesn't define its own. Empty = cluster `default` SA. Per-agent `agents..serviceAccountName` fully overrides this. Chart references an existing SA only — does not create one. Required to activate IRSA on EKS. | `""` | ### Agent values @@ -50,6 +51,7 @@ Each agent lives under `agents.`. | `persistence.enabled` | Enable persistent storage for auth and settings. | `true` | | `persistence.existingClaim` | Reuse an existing PVC instead of creating one. | `""` | | `agentsMd` | Contents of `AGENTS.md` mounted into the working directory. | `""` | +| `serviceAccountName` | Per-agent ServiceAccount name. When set (non-empty), fully overrides chart-global `serviceAccountName`. Useful when only some agents need an IRSA-bound SA. | `""` | | `extraInitContainers` | Additional init containers for the agent pod. | `[]` | | `extraContainers` | Additional sidecar containers for the agent pod. | `[]` | | `extraVolumeMounts` | Additional volume mounts for the main agent container. | `[]` | diff --git a/charts/openab/templates/deployment.yaml b/charts/openab/templates/deployment.yaml index a47a3e8be..44091495f 100644 --- a/charts/openab/templates/deployment.yaml +++ b/charts/openab/templates/deployment.yaml @@ -29,6 +29,10 @@ spec: securityContext: {{- toYaml . | nindent 8 }} {{- end }} + {{- $svcAcct := default $.Values.serviceAccountName $cfg.serviceAccountName }} + {{- if $svcAcct }} + serviceAccountName: {{ $svcAcct }} + {{- end }} {{- with $cfg.extraInitContainers }} initContainers: {{- toYaml . | nindent 8 }} diff --git a/charts/openab/tests/serviceaccount_test.yaml b/charts/openab/tests/serviceaccount_test.yaml new file mode 100644 index 000000000..d5b92de43 --- /dev/null +++ b/charts/openab/tests/serviceaccount_test.yaml @@ -0,0 +1,51 @@ +suite: serviceAccountName support (chart-global + per-agent override) +templates: + - templates/deployment.yaml + +tests: + - it: does not render serviceAccountName when neither global nor per-agent is set + asserts: + - notExists: + path: spec.template.spec.serviceAccountName + + - it: renders chart-global serviceAccountName when only the global value is set + set: + serviceAccountName: "openab" + asserts: + - equal: + path: spec.template.spec.serviceAccountName + value: openab + + - it: renders per-agent serviceAccountName when only the per-agent value is set + set: + agents.kiro.serviceAccountName: "kiro-sa" + asserts: + - equal: + path: spec.template.spec.serviceAccountName + value: kiro-sa + + - it: per-agent serviceAccountName fully overrides chart-global + set: + serviceAccountName: "openab" + agents.kiro.serviceAccountName: "kiro-sa" + asserts: + - equal: + path: spec.template.spec.serviceAccountName + value: kiro-sa + + - it: empty per-agent serviceAccountName falls back to chart-global + set: + serviceAccountName: "openab" + agents.kiro.serviceAccountName: "" + asserts: + - equal: + path: spec.template.spec.serviceAccountName + value: openab + + - it: explicit empty global + empty per-agent renders no serviceAccountName field + set: + serviceAccountName: "" + agents.kiro.serviceAccountName: "" + asserts: + - notExists: + path: spec.template.spec.serviceAccountName diff --git a/charts/openab/values.yaml b/charts/openab/values.yaml index 50b659159..b84402054 100644 --- a/charts/openab/values.yaml +++ b/charts/openab/values.yaml @@ -11,6 +11,15 @@ nameOverride: "" # Override the full release name used in generated resource names. fullnameOverride: "" +# Chart-global ServiceAccount name for agent pods, used when an agent doesn't +# set its own `serviceAccountName`. Empty string = use cluster default SA. +# Per-agent values (agents..serviceAccountName) take precedence — when +# set, they fully override this. The chart only references an existing SA; it +# does NOT create one or manage IRSA annotations (provision out-of-band). +# Example: +# serviceAccountName: "openab" +serviceAccountName: "" + podSecurityContext: runAsNonRoot: true runAsUser: 1000 @@ -349,6 +358,11 @@ agents: nodeSelector: {} tolerations: [] affinity: {} + # Per-agent ServiceAccount name. When set (non-empty), overrides the + # chart-global `serviceAccountName` for this agent only. Useful in + # multi-agent deployments where only some agents need an IRSA-bound SA. + # serviceAccountName: "openab" + serviceAccountName: "" # extraInitContainers adds init containers to the pod (runs before the main container) extraInitContainers: [] # extraContainers adds sidecar containers to the pod From bab40a449347525815b983edd5aeea0a343dcd16 Mon Sep 17 00:00:00 2001 From: "chaodu-agent[bot]" Date: Sat, 23 May 2026 19:00:23 +0000 Subject: [PATCH 2/2] docs: generalize serviceAccountName descriptions, remove EKS/IRSA-specific wording --- charts/openab/README.md | 4 ++-- charts/openab/values.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/charts/openab/README.md b/charts/openab/README.md index 8e472814f..2c6489c75 100644 --- a/charts/openab/README.md +++ b/charts/openab/README.md @@ -12,7 +12,7 @@ This page highlights commonly used values and deployment patterns. For the compl |-------|-------------|---------| | `nameOverride` | Override the chart name portion used in generated resource names. For per-agent resource names, use `agents..nameOverride`. | `""` | | `fullnameOverride` | Override the full generated release name for chart resources. Useful when deploying multiple instances with predictable names. | `""` | -| `serviceAccountName` | Chart-global ServiceAccount name attached to every agent pod that doesn't define its own. Empty = cluster `default` SA. Per-agent `agents..serviceAccountName` fully overrides this. Chart references an existing SA only — does not create one. Required to activate IRSA on EKS. | `""` | +| `serviceAccountName` | Chart-global ServiceAccount name attached to every agent pod that doesn't define its own. Empty = cluster `default` SA. Per-agent `agents..serviceAccountName` fully overrides this. Chart references an existing SA only — does not create one. Required for workload identity and pod-level RBAC. | `""` | ### Agent values @@ -51,7 +51,7 @@ Each agent lives under `agents.`. | `persistence.enabled` | Enable persistent storage for auth and settings. | `true` | | `persistence.existingClaim` | Reuse an existing PVC instead of creating one. | `""` | | `agentsMd` | Contents of `AGENTS.md` mounted into the working directory. | `""` | -| `serviceAccountName` | Per-agent ServiceAccount name. When set (non-empty), fully overrides chart-global `serviceAccountName`. Useful when only some agents need an IRSA-bound SA. | `""` | +| `serviceAccountName` | Per-agent ServiceAccount name. When set (non-empty), fully overrides chart-global `serviceAccountName`. Useful when only some agents need a dedicated SA. | `""` | | `extraInitContainers` | Additional init containers for the agent pod. | `[]` | | `extraContainers` | Additional sidecar containers for the agent pod. | `[]` | | `extraVolumeMounts` | Additional volume mounts for the main agent container. | `[]` | diff --git a/charts/openab/values.yaml b/charts/openab/values.yaml index b84402054..d22ea0995 100644 --- a/charts/openab/values.yaml +++ b/charts/openab/values.yaml @@ -15,7 +15,7 @@ fullnameOverride: "" # set its own `serviceAccountName`. Empty string = use cluster default SA. # Per-agent values (agents..serviceAccountName) take precedence — when # set, they fully override this. The chart only references an existing SA; it -# does NOT create one or manage IRSA annotations (provision out-of-band). +# does NOT create one or manage annotations (provision out-of-band). # Example: # serviceAccountName: "openab" serviceAccountName: "" @@ -360,7 +360,7 @@ agents: affinity: {} # Per-agent ServiceAccount name. When set (non-empty), overrides the # chart-global `serviceAccountName` for this agent only. Useful in - # multi-agent deployments where only some agents need an IRSA-bound SA. + # multi-agent deployments where only some agents need a dedicated SA. # serviceAccountName: "openab" serviceAccountName: "" # extraInitContainers adds init containers to the pod (runs before the main container)