Skip to content

feat(kubernetes): add operator allowlists for sandbox pod annotations and labels - #4497

Merged
matthewgrossman merged 6 commits into
mainfrom
feat/k8s-pod-annotation-allowlist/matthewgrossman
Oct 13, 2026
Merged

matthewgrossman merged 6 commits into
mainfrom
feat/k8s-pod-annotation-allowlist/matthewgrossman

Conversation

@matthewgrossman

@matthewgrossman matthewgrossman commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

Summary

Add operator-controlled allowlists for the pod annotations and labels that sandbox templates can set on Kubernetes sandbox pods. By default, no template annotations or labels are allowed.

Related Issue

Related: #2102. This PR adds the operator allowlist that applying --label values to pods would need.

Changes

  • New allowed_pod_annotations and allowed_pod_labels fields in [openshell.drivers.kubernetes]. Each entry is an exact key (example.com/team, app) or a <domain>/* wildcard, which matches keys in that domain only, not subdomains. Both lists use the same format and validation.
  • Sandbox create rejects template annotations or labels that don't match their list (InvalidArgument, naming each rejected key). The check runs in both validate_sandbox_create and create_sandbox_inner.
  • Annotation and label keys under openshell.ai and agents.x-k8s.io (and their subdomains) are always rejected. The gateway refuses to start if either list includes one of them or a malformed entry.
  • Helm: set through gatewayConfig["openshell.drivers.kubernetes"].allowed_pod_annotations / allowed_pod_labels (no legacy server.* alias). Standalone driver: --allowed-pod-annotations / OPENSHELL_K8S_ALLOWED_POD_ANNOTATIONS and --allowed-pod-labels / OPENSHELL_K8S_ALLOWED_POD_LABELS.
  • Docs: gateway configuration reference and Kubernetes runtime options table.

Behavior change: On Kubernetes deployments, sandbox templates that set pod annotations or labels are rejected until an operator allowlists those keys. The openshell CLI doesn't set template labels or annotations, and reusable workload-template labels are metadata only, so this affects only direct API or SDK callers that set SandboxTemplate.labels or SandboxTemplate.annotations. It applies to new sandbox creation and to recovery of existing sandboxes: when the gateway recreates a sandbox after a timed-out provisioning attempt, the stored template is validated again. A normal stop and start does not re-validate. Sandbox metadata labels (--label, --selector) and other drivers are unchanged.

Testing

  • cargo test -p openshell-driver-kubernetes (288 passed)
  • cargo clippy -p openshell-driver-kubernetes -p openshell-gateway --all-targets clean
  • helm unittest deploy/helm/openshell (330 passed), mise run helm:docs:check
  • Unit tests added/updated
  • E2E tests added/updated (if applicable)

Checklist

  • Follows Conventional Commits
  • Commits are signed off (DCO)

Add allowed_pod_annotations to the Kubernetes driver config. Sandbox
template annotations must match an exact key or a <domain>/* entry, and
the default empty list rejects all of them. Keys in the openshell.ai and
agents.x-k8s.io domains are always rejected. Expose the setting through
the server.allowedPodAnnotations Helm value.

Signed-off-by: Matthew Grossman <mgrossman@nvidia.com>
@copy-pr-bot

copy-pr-bot Bot commented Oct 13, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@matthewgrossman
matthewgrossman marked this pull request as ready for review October 13, 2026 18:01
…on-allowlist/matthewgrossman

Signed-off-by: Matthew Grossman <mgrossman@nvidia.com>

# Conflicts:
#	deploy/helm/openshell/templates/gateway-config.yaml
@github-actions

Copy link
Copy Markdown

@johntmyers johntmyers added the test:e2e Requires end-to-end coverage label Oct 13, 2026
@github-actions

Copy link
Copy Markdown

Label test:e2e applied for 64c20fb. Open the existing run and click Re-run all jobs to execute with the label set. The run will execute the standard E2E suite after building the required gateway, sandbox, and supervisor images once. The matching required CI gate status on this PR will flip green automatically once the run finishes.

@johntmyers

Copy link
Copy Markdown
Collaborator

gator-agent

PR Review Status

The independent review found no blocking issues in the Kubernetes pod annotation allowlist. The operator configuration, validation on both sandbox-create paths, reserved-domain rejection, and Fern docs cover the stated behavior.

Blocking findings: None.

Carried findings: None.

Non-blocking suggestions: None.

Branch Checks, Helm Lint, and Trivy Changes passed. I applied test:e2e and followed the E2E Label Help bot's instruction to rerun all jobs in the current-head workflow; that run is now queued. Gator will monitor the E2E results next cycle.

Gator metadata
  • Validation: Focused Kubernetes driver change from a verified maintainer.
  • Docs: Gateway configuration reference and Kubernetes runtime options updated.
  • Checks: Current-head Branch Checks, Helm Lint, Trivy Changes, DCO, and PR Issue Acceptance passed.
  • E2E: test:e2e applied; Branch E2E Checks run 38444250670 rerun confirmed queued for the current head. Prior skipped suites are not counted as runtime coverage.
  • Head SHA: 64c20fb788122cdf5c63d540c716f0beb918e5df
  • Base SHA: b9dc1f64660942a168b06f53b9dcbdfb3dd63de7
  • Merge base SHA: b9dc1f64660942a168b06f53b9dcbdfb3dd63de7
  • Patch ID: afdd174dadf74e53e5c9bef61f9e82ba4a5cd2c1
  • Gator payload: 12
  • Review mode: initial
  • Previous reviewed SHA: none
  • Review budget exhausted: no
  • Maintainer decision required: no
  • Next state: gator:watch-pipeline

@johntmyers johntmyers added the gator:watch-pipeline Gator is monitoring PR CI/CD status label Oct 13, 2026
TaylorMutch
TaylorMutch previously approved these changes Oct 13, 2026
@johntmyers johntmyers added gator:merge-ready and removed gator:watch-pipeline Gator is monitoring PR CI/CD status labels Oct 13, 2026
Assert the exact rejected annotation keys, exercise create_sandbox_inner
with a disallowed annotation, and point the rejection error at the Helm
gatewayConfig path.

Signed-off-by: Matthew Grossman <mgrossman@nvidia.com>
The rejection error reaches API callers, not operators, so name only the
gateway config key. Spell the Helm path in the runtimes docs with the
quoted table key to avoid an invalid nested gatewayConfig rendering.

Signed-off-by: Matthew Grossman <mgrossman@nvidia.com>
@johntmyers

Copy link
Copy Markdown
Collaborator

gator-agent

PR Review Status

The independent follow-up review found no blocking issues in the new annotation-rejection test or the corrected Helm configuration key. The earlier clean review still applies to the unchanged implementation, and no review obligations remain.

Required checks are pending on the current head. test:e2e is already applied, and the current-head Branch E2E Checks workflow is queued with builds underway. Gator will monitor those results; maintainer approval is still required after checks pass.

Blocking findings: None.

Carried findings: None.

Gator metadata
  • Validation: Focused Kubernetes driver change from a verified maintainer.
  • Docs: Gateway configuration reference and Kubernetes runtime options updated; follow-up corrects the literal Helm configuration key.
  • Checks: Current-head Branch Checks, Helm Lint, and Trivy Changes running; DCO and PR Issue Acceptance passed.
  • E2E: test:e2e applied; current-head Branch E2E Checks run 38456742706 queued, with build jobs queued or running. The earlier bot rerun instruction applied to the previous head; no additional rerun is needed for this new run.
  • Head SHA: 061731e0319286c15c3c251f6af7ccb899dd9ad9
  • Base SHA: b9dc1f64660942a168b06f53b9dcbdfb3dd63de7
  • Merge base SHA: b9dc1f64660942a168b06f53b9dcbdfb3dd63de7
  • Patch ID: e21414c2714f52cb3bfee3c4b78fcdea4e78be8b
  • Gator payload: 12
  • Review mode: follow_up
  • Previous reviewed SHA: 64c20fb788122cdf5c63d540c716f0beb918e5df
  • Review budget exhausted: no
  • Maintainer decision required: no
  • Next state: gator:watch-pipeline

@johntmyers johntmyers added gator:watch-pipeline Gator is monitoring PR CI/CD status and removed gator:merge-ready labels Oct 13, 2026
Fold the allowlist matching and validation cases into table-driven tests,
reuse the json_struct helper for templates, and document why the
openshell.ai and agents.x-k8s.io domains are reserved.

Signed-off-by: Matthew Grossman <mgrossman@nvidia.com>
@johntmyers

Copy link
Copy Markdown
Collaborator

gator-agent

PR Review Status

The independent follow-up review found no blocking issues in the annotation allowlist test consolidation or reserved-domain documentation clarification. The earlier clean review still applies to the unchanged implementation, and no review obligations remain.

Branch Checks, Helm Lint, and E2E are running on the current head. test:e2e is already applied; the earlier bot rerun instruction concerned an older head, and the new E2E workflow is running without another rerun. Gator will inspect the results next cycle.

Blocking findings: None.

Carried findings: None.

Gator metadata
  • Validation: Focused Kubernetes driver change from an author with verified repository admin permission.
  • Docs: Gateway configuration reference and Kubernetes runtime options clarify reserved annotation domains; no navigation change needed.
  • Checks: Current-head DCO, PR Issue Acceptance, and Trivy Changes passed; Branch Checks and Helm Lint pending.
  • E2E: test:e2e applied; current-head Branch E2E Checks run 38458951737 confirmed in progress. No mirror refresh or workflow rerun needed.
  • Head SHA: bf237fb8d15a80e53d93ce66105d45ca92d8c3f2
  • Base SHA: b9dc1f64660942a168b06f53b9dcbdfb3dd63de7
  • Merge base SHA: b9dc1f64660942a168b06f53b9dcbdfb3dd63de7
  • Patch ID: 25740d699acc0095ccd5c5b4d4f72c947e9d4923
  • Gator payload: 12
  • Review mode: follow_up
  • Previous reviewed SHA: 061731e0319286c15c3c251f6af7ccb899dd9ad9
  • Review budget exhausted: no
  • Maintainer decision required: no
  • Next state: gator:watch-pipeline

TaylorMutch
TaylorMutch previously approved these changes Oct 13, 2026
@johntmyers johntmyers added gator:merge-ready and removed gator:watch-pipeline Gator is monitoring PR CI/CD status labels Oct 13, 2026
Sandbox template labels were copied onto workload pods unfiltered. Labels
select pods for NetworkPolicy rules and Services, so a caller could place a
sandbox under rules meant for other workloads or set OpenShell-owned labels.

Add allowed_pod_labels, sharing the allowed_pod_annotations entry format,
validation, and reserved openshell.ai / agents.x-k8s.io domains. Empty by
default, which rejects every template label.

Signed-off-by: Matthew Grossman <mgrossman@nvidia.com>
@matthewgrossman matthewgrossman changed the title feat(kubernetes): add operator allowlist for sandbox pod annotations feat(kubernetes): add operator allowlists for sandbox pod annotations and labels Oct 13, 2026
@johntmyers

Copy link
Copy Markdown
Collaborator

gator-agent

PR Review Status

The independent Critical-only follow-up review found no new Critical defects in the pod label allowlist or shared annotation/label validation. The earlier reviews continue to cover the unchanged implementation, and no carried findings or concrete maintainer scope decision remain.

Branch Checks, Helm Lint, Trivy Changes, and DCO have passed on the current head. Maintainer approval is present, and the current-head E2E workflow is running, including Kubernetes and workspace suites. Gator will monitor the remaining results before returning this PR to merge-ready.

Blocking findings: None.

Carried findings: None.

Gator metadata
  • Validation: Focused Kubernetes metadata allowlist change from an author with verified repository admin permission.
  • Docs: Gateway configuration reference and Kubernetes runtime options document the new label allowlist and default rejection behavior.
  • Checks: Current-head Branch Checks, Helm Lint, Trivy Changes, DCO, and PR Issue Acceptance passed; E2E pending.
  • E2E: test:e2e already applied; current-head Branch E2E Checks run 38472982850 confirmed in progress. The earlier bot rerun instruction applies to an older head; no new rerun or mirror refresh is needed.
  • Head SHA: 09d5580e8d0f0c5be17708ec6c223e601ebdf014
  • Base SHA: b9dc1f64660942a168b06f53b9dcbdfb3dd63de7
  • Merge base SHA: b9dc1f64660942a168b06f53b9dcbdfb3dd63de7
  • Patch ID: f2100dfa1a6e8f8c2c7938225da700525779314f
  • Gator payload: 12
  • Review mode: critical_only
  • Previous reviewed SHA: bf237fb8d15a80e53d93ce66105d45ca92d8c3f2
  • Review budget exhausted: yes
  • Maintainer decision required: no — no unresolved obligation, remediation scope growth, or proposed Warning requiring authorization.
  • Next state: gator:watch-pipeline

@johntmyers johntmyers added gator:watch-pipeline Gator is monitoring PR CI/CD status and removed gator:merge-ready labels Oct 13, 2026
@johntmyers johntmyers added gator:merge-ready and removed gator:watch-pipeline Gator is monitoring PR CI/CD status labels Oct 13, 2026
@matthewgrossman
matthewgrossman added this pull request to the merge queue Oct 13, 2026
Merged via the queue into main with commit 90161fb Oct 13, 2026
127 of 130 checks passed
@matthewgrossman
matthewgrossman deleted the feat/k8s-pod-annotation-allowlist/matthewgrossman branch October 13, 2026 23:09
@johntmyers

Copy link
Copy Markdown
Collaborator

gator-agent

Monitoring Complete

Monitoring is complete because this PR has merged.

Final status: Gator reached merge-ready with no blocking review findings. The final-head Branch Checks, Helm Lint, and E2E gates passed.

I am removing the active gator:merge-ready label because there is nothing left for Gator to monitor on this PR.

Gator metadata
  • Head SHA: 09d5580e8d0f0c5be17708ec6c223e601ebdf014
  • Gator payload: 12

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

Labels

test:e2e Requires end-to-end coverage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants