-
Notifications
You must be signed in to change notification settings - Fork 2.7k
fix: add rootless DinD daemon.json path fallback in preflight #2045
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 4 commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
06a6eaa
fix(k8s): replace privileged DinD with rootless DinD
ericksoa 0fc74e8
fix(k8s): interpose docker socket proxy between workspace and daemon
ericksoa f4f912a
Merge branch 'main' into fix/docker-socket-proxy
ericksoa b2b5f04
test: migrate security-hardening test to .ts and revert .js edit
ericksoa 6015b32
Merge branch 'main' into fix/docker-socket-proxy
ericksoa 681c577
fix(test): add non-null assertions for regex match results
ericksoa 61467e7
fix(k8s): address CodeRabbit review feedback on docker socket proxy
ericksoa 69487e6
merge: resolve conflict with main in onboard.ts
ericksoa 393939f
Merge branch 'main' into fix/docker-socket-proxy
ericksoa 3f6bd24
fix(test): tighten workspace-section regex to container-level indenta…
ericksoa d3ff441
Merge branch 'main' into fix/docker-socket-proxy
ericksoa d9c3c93
Merge branch 'main' into fix/docker-socket-proxy
ericksoa 680a22a
Merge branch 'main' into fix/docker-socket-proxy
ericksoa c6737a6
fix(k8s): bind docker-socket-proxy to localhost only
ericksoa 0b4d070
Merge branch 'main' into fix/docker-socket-proxy
ericksoa cf09c01
Merge branch 'main' into fix/docker-socket-proxy
ericksoa 494471a
Merge branch 'main' into fix/docker-socket-proxy
ericksoa 686fa71
Merge branch 'main' into fix/docker-socket-proxy
ericksoa b3bbf66
Merge branch 'main' into fix/docker-socket-proxy
ericksoa aeb5961
merge: resolve conflicts with main after k8s/ removal (#2107)
ericksoa af9891e
fix: remove k8s files already deleted by #2107
ericksoa cd98cac
fix: remove k8s security test (manifest deleted in #2107)
ericksoa cf39790
Merge branch 'main' into fix/docker-socket-proxy
ericksoa 42b8ea7
Merge branch 'main' into fix/docker-socket-proxy
ericksoa File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| import { describe, it, expect } from "vitest"; | ||
| import fs from "node:fs"; | ||
| import path from "node:path"; | ||
|
|
||
| const ROOT = path.join(import.meta.dirname, ".."); | ||
| const K8S_MANIFEST = path.join(ROOT, "k8s", "nemoclaw-k8s.yaml"); | ||
|
|
||
| describe("security configuration hardening", () => { | ||
| it("hardens the Kubernetes sample manifest with safer defaults", () => { | ||
| const manifest = fs.readFileSync(K8S_MANIFEST, "utf8"); | ||
| const workspaceMatch = manifest.match( | ||
| /- name: workspace[\s\S]*?(?=\n\s*-\s*name: |\n\s*initContainers:|\n\s*volumes:|$)/, | ||
| ); | ||
|
coderabbitai[bot] marked this conversation as resolved.
Outdated
|
||
| expect(workspaceMatch).not.toBeNull(); | ||
| const workspaceSection = workspaceMatch[0]; | ||
| expect(manifest).toMatch(/automountServiceAccountToken:\s*false/); | ||
| expect(manifest).toMatch(/enableServiceLinks:\s*false/); | ||
| expect(workspaceSection).toMatch(/allowPrivilegeEscalation:\s*false/); | ||
| expect(workspaceSection).toMatch(/capabilities:\s*[\r\n]+\s*drop:\s*[\r\n]+\s*-\s*ALL/); | ||
| expect(workspaceSection).toMatch(/seccompProfile:\s*[\r\n]+\s*type:\s*RuntimeDefault/); | ||
| expect(manifest).toMatch(/- name: NEMOCLAW_POLICY_MODE[\s\S]*value:\s*"suggested"/); | ||
| expect(manifest).toContain('export COMPATIBLE_API_KEY="${COMPATIBLE_API_KEY:-dummy}"'); | ||
| const compatibleApiKeySection = manifest.match( | ||
| /- name: COMPATIBLE_API_KEY[\s\S]*?(?=\n\s*-\s*name: |\n\s*volumeMounts:|\n\s*command:|$)/, | ||
| )?.[0]; | ||
| expect(compatibleApiKeySection).toBeTruthy(); | ||
| expect(compatibleApiKeySection).toMatch( | ||
| /secretKeyRef:[\s\S]*name:\s*nemoclaw-compatible-api-key/, | ||
| ); | ||
| expect(compatibleApiKeySection).toMatch(/optional:\s*true/); | ||
| expect(manifest).toContain("curl --proto '=https' --tlsv1.2 --fail --show-error --silent"); | ||
| expect(manifest).toContain("--output /tmp/nemoclaw-install.sh"); | ||
| expect(manifest).toContain("chmod 700 /tmp/nemoclaw-install.sh"); | ||
| expect(manifest).toContain("bash /tmp/nemoclaw-install.sh"); | ||
| expect(manifest).not.toMatch(/curl\b[^\n|]*\|\s*(?:ba|z|k)?sh\b/i); | ||
| }); | ||
|
|
||
| it("interposes a docker socket proxy between workspace and the daemon", () => { | ||
| const manifest = fs.readFileSync(K8S_MANIFEST, "utf8"); | ||
|
|
||
| // Extract docker-proxy section | ||
| const proxyMatch = manifest.match( | ||
| /- name: docker-proxy[\s\S]*?(?=\n\s{4}-\s*name: |\n\s*initContainers:|\n\s*volumes:|$)/, | ||
| ); | ||
| expect(proxyMatch).not.toBeNull(); | ||
| const proxySection = proxyMatch[0]; | ||
|
|
||
| // Proxy is hardened | ||
| expect(proxySection).toMatch(/allowPrivilegeEscalation:\s*false/); | ||
| expect(proxySection).toMatch(/capabilities:\s*[\r\n]+\s*drop:\s*[\r\n]+\s*-\s*ALL/); | ||
| expect(proxySection).toMatch(/seccompProfile:\s*[\r\n]+\s*type:\s*RuntimeDefault/); | ||
| expect(proxySection).toMatch(/runAsNonRoot:\s*true/); | ||
|
|
||
| // Proxy mounts socket read-only | ||
| expect(proxySection).toMatch(/readOnly:\s*true/); | ||
|
|
||
| // Dangerous Docker API endpoints are denied | ||
| expect(proxySection).toMatch(/name:\s*EXEC[\s\S]*?value:\s*"0"/); | ||
| expect(proxySection).toMatch(/name:\s*BUILD[\s\S]*?value:\s*"0"/); | ||
|
|
||
| // Workspace does NOT mount the docker-socket volume | ||
| const workspaceMatch = manifest.match( | ||
| /- name: workspace[\s\S]*?(?=\n\s{4}-\s*name: |\n\s*initContainers:|\n\s*volumes:|$)/, | ||
| ); | ||
| expect(workspaceMatch).not.toBeNull(); | ||
| const workspaceSection = workspaceMatch[0]; | ||
| expect(workspaceSection).not.toMatch(/name:\s*docker-socket/); | ||
|
|
||
| // Workspace talks to the proxy over TCP, not to the raw socket | ||
| expect(workspaceSection).toMatch(/DOCKER_HOST[\s\S]*?value:\s*tcp:\/\//); | ||
| expect(workspaceSection).not.toMatch(/DOCKER_HOST[\s\S]*?value:\s*unix:\/\//); | ||
| }); | ||
| }); | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.