Skip to content

fix(security): harden k8s sample manifest defaults#1324

Open
jyaunches wants to merge 2 commits intoNVIDIA:mainfrom
jyaunches:fix/harden-k8s-manifest-defaults
Open

fix(security): harden k8s sample manifest defaults#1324
jyaunches wants to merge 2 commits intoNVIDIA:mainfrom
jyaunches:fix/harden-k8s-manifest-defaults

Conversation

@jyaunches
Copy link
Copy Markdown
Contributor

@jyaunches jyaunches commented Apr 2, 2026

Fixes #1323 — Partially addresses #803.

Summary

Hardens the experimental Kubernetes sample manifest (k8s/nemoclaw-k8s.yaml) with safer defaults. This work was cherry-picked from @13ernkastel's PR #1149, which was closed after its auth hardening portion was superseded by #1217. The k8s hardening in #1149 was independent and valuable, so we're carrying it forward here with proper attribution.

Changes

Pod-level

  • automountServiceAccountToken: false — pod does not need k8s API access
  • enableServiceLinks: false — prevents service env var injection

Workspace container security context

  • allowPrivilegeEscalation: false
  • capabilities.drop: [ALL]
  • seccompProfile.type: RuntimeDefault

Credential handling

  • COMPATIBLE_API_KEY loaded from optional Secret (nemoclaw-compatible-api-key) with dummy fallback for unauthenticated endpoints (Dynamo/vLLM)
  • NEMOCLAW_POLICY_MODE default changed from skip to suggested

Installer download

  • Replaced curl ... | bash with download-then-execute pattern using curl --proto =https --tlsv1.2

Documentation

  • Updated k8s/README.md with Secret setup instructions and revised config table

Tests

  • Added test/security-configuration-hardening.test.js with regression coverage for all k8s manifest hardening

Attribution

Co-authored-by: @13ernkastel (from PR #1149)

Context

This came up during post-merge cleanup of #1217 (fix(security): harden gateway auth defaults and restrict auto-pair). PR #1149 bundled k8s hardening with auth changes; we split them apart so the k8s work doesn't get lost.

Summary by CodeRabbit

  • New Features

    • Added optional NEMOCLAW_POLICY_MODE environment variable for deployment configuration (default: suggested).
  • Documentation

    • Updated Kubernetes deployment guide with revised manifest setup instructions and safer configuration examples.
  • Configuration Changes

    • API key now sourced from Kubernetes Secret with optional override; defaults to dummy when not provided.
    • Kubernetes manifest applies stricter default configurations.
  • Tests

    • Added validation tests for manifest configuration.

Cherry-picked k8s hardening from @13ernkastel's PR NVIDIA#1149, which was
closed after its auth changes were superseded by NVIDIA#1217.

Changes to k8s/nemoclaw-k8s.yaml:
- automountServiceAccountToken: false
- enableServiceLinks: false
- workspace container: allowPrivilegeEscalation false, drop ALL caps,
  RuntimeDefault seccomp
- COMPATIBLE_API_KEY from optional Secret with dummy fallback
- NEMOCLAW_POLICY_MODE default changed from skip to suggested
- Replace curl|bash with download-then-execute pattern

Also adds k8s/README.md updates and regression test.

Co-authored-by: 13ernkastel <LennonCMJ@live.com>
@jyaunches
Copy link
Copy Markdown
Contributor Author

@ericksoa — this came up as a potential follow-up while cleaning up after our recently merged #1217. PR #1149 by @13ernkastel had bundled k8s manifest hardening (pod security context, Secret-backed credentials, safer installer download) alongside the auth changes that #1217 superseded. We closed #1149 but cherry-picked the k8s portion here so it doesn't get lost.

Do you agree this is complementary for the k8s deployment path? The changes are scoped to k8s/nemoclaw-k8s.yaml, k8s/README.md, and a new regression test — no overlap with the auth/auto-pair work.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 2, 2026

📝 Walkthrough

Walkthrough

Security hardening of the Kubernetes sample manifest with stricter pod and container settings, safer installer execution via download-then-execute pattern, optional API key Secret loading, and updated documentation with corresponding test suite validation.

Changes

Cohort / File(s) Summary
Documentation & Configuration
k8s/README.md
Updated deployment instructions with optional Secret creation for API key, conditional environment variables, stricter manifest security defaults documentation, and HTTPS-only curl flags for installer download.
Kubernetes Manifest Hardening
k8s/nemoclaw-k8s.yaml
Added pod-level security: disabled token automounting and service link injection. Container security context now enforces strict isolation: prevents privilege escalation, drops all capabilities, uses RuntimeDefault seccomp. Installer execution changed from piping curl directly to bash to controlled download-to-file with permissions and explicit execution. API key now loaded from optional Secret with fallback default. Policy mode updated from skip to suggested.
Security Test Suite
test/security-configuration-hardening.test.js
New test file validating all security hardening properties: pod-level settings, container security context, seccomp profile, capability dropping, policy mode environment variable, Secret-based API key configuration, and anti-patterns (absence of curl-pipe-to-shell).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A burrow secured with locks and keys,
No tokens leaking on the breeze,
Capsules dropped with utmost care,
Scripts now safer, debts more fair,
Our warren hardened, strong, and right! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(security): harden k8s sample manifest defaults' clearly summarizes the main objective: hardening the Kubernetes sample manifest with security improvements.
Linked Issues check ✅ Passed The PR implements all core coding requirements from issue #1323: pod-level hardening (automountServiceAccountToken and enableServiceLinks), container securityContext (allowPrivilegeEscalation, capabilities.drop, seccompProfile), credential handling (COMPATIBLE_API_KEY from Secret with fallback, NEMOCLAW_POLICY_MODE default change), and secure installer pattern.
Out of Scope Changes check ✅ Passed All changes are strictly scoped to the linked issue #1323: k8s/nemoclaw-k8s.yaml manifest hardening, k8s/README.md documentation updates, and a new regression test. No unrelated changes detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
k8s/README.md (1)

1-2: ⚠️ Potential issue | 🟡 Minor

Missing SPDX license header.

As per coding guidelines, Markdown files require an HTML comment SPDX license header at the top:

<!-- SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -->
<!-- SPDX-License-Identifier: Apache-2.0 -->
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@k8s/README.md` around lines 1 - 2, Add the required SPDX HTML comment header
to the top of the Markdown file that currently starts with the title "# NemoClaw
on Kubernetes": insert the two lines for Copyright and License as HTML comments
(the SPDX-FileCopyrightText and SPDX-License-Identifier) immediately before the
existing content so the README.md contains the SPDX header above the title.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@k8s/README.md`:
- Around line 1-2: Add the required SPDX HTML comment header to the top of the
Markdown file that currently starts with the title "# NemoClaw on Kubernetes":
insert the two lines for Copyright and License as HTML comments (the
SPDX-FileCopyrightText and SPDX-License-Identifier) immediately before the
existing content so the README.md contains the SPDX header above the title.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7672ed34-5739-4886-91b5-e300b1583162

📥 Commits

Reviewing files that changed from the base of the PR and between db65da8 and 6685ef7.

📒 Files selected for processing (3)
  • k8s/README.md
  • k8s/nemoclaw-k8s.yaml
  • test/security-configuration-hardening.test.js

@ericksoa
Copy link
Copy Markdown
Contributor

ericksoa commented Apr 2, 2026

Reviewed the changes — the API key fallback and policy mode switch both look safe after code analysis (no early consumers for COMPATIBLE_API_KEY; suggested mode is fully headless when NEMOCLAW_NON_INTERACTIVE=1). Two items:

Blocker: workspace securityContext breaks apt-get

Have you tried running this manifest in a real pod? The workspace container runs apt-get update && apt-get install before the installer, and apt-get internally sandboxes itself by switching to the _apt user — which requires CAP_SETUID/CAP_SETGID. With drop: [ALL], that fails:

E: setgroups 65534 failed - setgroups (1: Operation not permitted)
E: seteuid 42 failed - seteuid (1: Operation not permitted)

(Reproducible with: docker run --rm --cap-drop=ALL --security-opt no-new-privileges node:22 bash -c "apt-get update -qq")

Since the workspace container doesn't need elevated privileges beyond the package install phase, and DinD is already the privileged sidecar, would it make sense to drop the workspace securityContext from this PR and tackle it separately? The pod-level hardening (automountServiceAccountToken, enableServiceLinks), Secret-backed credentials, and installer download changes all stand on their own.

Style: We're moving all new code to TypeScript — could test/security-configuration-hardening.test.js be a .test.ts file instead?

@wscurran wscurran added security Something isn't secure priority: medium Issue that should be addressed in upcoming releases K8s Use this label to identify Kubernetes deployment issues with NemoClaw. labels Apr 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

K8s Use this label to identify Kubernetes deployment issues with NemoClaw. priority: medium Issue that should be addressed in upcoming releases security Something isn't secure

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(security): harden k8s sample manifest defaults

3 participants