Skip to content

feat(docker): switch seccomp profile to deny-by-default#1286

Merged
Mossaka merged 2 commits intomainfrom
feat/084-seccomp-hardening
Mar 13, 2026
Merged

feat(docker): switch seccomp profile to deny-by-default#1286
Mossaka merged 2 commits intomainfrom
feat/084-seccomp-hardening

Conversation

@Mossaka
Copy link
Collaborator

@Mossaka Mossaka commented Mar 13, 2026

Summary

  • Switch seccomp profile from SCMP_ACT_ALLOW (allow-by-default) to SCMP_ACT_ERRNO (deny-by-default) with an explicit allowlist of ~340 syscalls
  • Explicitly allow all syscalls needed by development tools (git, npm, curl, node, python, java, rust, Go, etc.) and container setup (iptables, mount, chroot)
  • Keep explicit deny rules for dangerous syscalls (ptrace, kexec, reboot, module loading, pivot_root, umount) as defense-in-depth
  • Add 12 validation tests ensuring profile structure, deny-by-default action, essential syscall coverage, and no duplicate entries

Test plan

  • All 973 unit tests pass
  • New seccomp-profile.test.ts validates profile structure (12 tests)
  • CI integration tests verify agent workloads still function (git, npm, curl, language runtimes)
  • Chroot edge cases tests verify escape prevention still works

Fixes #311

🤖 Generated with Claude Code

Change defaultAction from SCMP_ACT_ALLOW to SCMP_ACT_ERRNO with an
explicit allowlist of ~340 syscalls needed by development tools (git,
npm, curl, node, python, java, rust, etc.). Dangerous syscalls like
ptrace, kexec_load, reboot, init_module, pivot_root, and umount remain
explicitly blocked as defense-in-depth.

Add seccomp-profile.test.ts with 12 validation tests ensuring the
profile structure, deny-by-default action, essential syscall coverage,
and no duplicate entries.

Fixes #311

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 13, 2026 02:00
@Mossaka Mossaka enabled auto-merge (squash) March 13, 2026 02:00
@github-actions
Copy link
Contributor

github-actions bot commented Mar 13, 2026

✅ Coverage Check Passed

Overall Coverage

Metric Base PR Delta
Lines 84.41% 84.70% 📈 +0.29%
Statements 84.36% 84.65% 📈 +0.29%
Functions 84.88% 85.28% 📈 +0.40%
Branches 77.44% 77.52% 📈 +0.08%
📁 Per-file Coverage Changes (2 files)
File Lines (Before → After) Statements (Before → After)
src/cli.ts 56.3% → 56.0% (-0.31%) 56.8% → 56.5% (-0.30%)
src/docker-manager.ts 87.0% → 87.6% (+0.51%) 86.4% → 86.9% (+0.49%)
✨ New Files (1 files)
  • src/rules.ts: 98.2% lines

Coverage comparison generated by scripts/ci/compare-coverage.ts

@Mossaka Mossaka changed the title feat(security): switch seccomp profile to deny-by-default feat(docker): switch seccomp profile to deny-by-default Mar 13, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Switches the agent container's seccomp profile from allow-by-default (SCMP_ACT_ALLOW) to deny-by-default (SCMP_ACT_ERRNO) with an explicit allowlist of ~340 syscalls, and adds validation tests.

Changes:

  • Changed defaultAction to SCMP_ACT_ERRNO and added a comprehensive allowlist of syscalls needed by development tools
  • Retained explicit deny rules for dangerous syscalls as defense-in-depth, with updated comments
  • Added 12 validation tests for profile structure, essential syscalls, and no-duplicate enforcement

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
containers/agent/seccomp-profile.json Switch to deny-by-default with ~340 allowed syscalls and updated comments on deny rules
src/seccomp-profile.test.ts New test suite validating profile structure, essential syscalls, deny rules, and no duplicates

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@github-actions
Copy link
Contributor

Smoke Test Results

GitHub MCP: Last 2 merged PRs: feat(cli): add --enable-dind flag (#1276), feat(ci): add documentation preview environment for PRs (#1273)
Playwright: github.com title contains "GitHub"
File Write: /tmp/gh-aw/agent/smoke-test-claude-23032805873.txt created
Bash: File verified via cat

Overall: PASS

💥 [THE END] — Illustrated by Smoke Claude for issue #1286

@github-actions
Copy link
Contributor

Smoke test results
PR titles: feat(docker): switch seccomp profile to deny-by-default
PR titles: feat(docker): separate iptables setup into init container
GitHub MCP ✅ | safeinputs-gh ✅ | Playwright ✅
Tavily web search ❌ | File write ✅ | Bash cat ✅
Discussion comment ✅ | Build ✅
Overall: FAIL

🔮 The oracle has spoken through Smoke Codex for issue #1286

@github-actions
Copy link
Contributor

Smoke test results for @Mossaka (no assignees):

✅ GitHub MCP — Last 2 merged PRs: feat(cli): add --enable-dind flag (#1276), feat(ci): add documentation preview environment for PRs (#1273)
✅ Playwright — github.com title contains "GitHub"
✅ File write — /tmp/gh-aw/agent/smoke-test-copilot-23032805918.txt created
✅ Bash verify — file read back successfully

Overall: PASS

📰 BREAKING: Report filed by Smoke Copilot for issue #1286

@github-actions
Copy link
Contributor

Chroot Version Comparison Results

Runtime Host Version Chroot Version Match?
Python Python 3.12.12 Python 3.12.3 ❌ NO
Node.js v24.14.0 v20.20.0 ❌ NO
Go go1.22.12 go1.22.12 ✅ YES

Result: ❌ Not all versions matched — Python and Node.js versions differ between host and chroot environments.

Tested by Smoke Chroot for issue #1286

@github-actions

This comment has been minimized.

Removes -f flag to avoid exit code 22 on GitHub API 403 rate limits.
The test only needs to generate Squid logs, not verify HTTP 200.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Contributor

Smoke Test Results — Copilot Engine

Test Result
GitHub MCP (last 2 merged PRs) #1279 feat(cli): add --ruleset-file, #1276 feat(cli): add --enable-dind flag
Playwright (github.com title contains "GitHub")
File write (smoke-test-copilot-23033612439.txt)
Bash verification (cat file)

Overall: PASS

PR author: @Mossaka · No assignees

📰 BREAKING: Report filed by Smoke Copilot for issue #1286

@github-actions
Copy link
Contributor

Smoke Test Results

Overall: PASS

💥 [THE END] — Illustrated by Smoke Claude for issue #1286

@github-actions
Copy link
Contributor

Smoke test: FAIL
PRs: feat(cli): add --ruleset-file for YAML domain rule configuration
PRs: feat(cli): add --enable-dind flag to opt-in to Docker socket access
GitHub MCP ✅ | safeinputs-gh ✅ | Playwright ✅
Tavily ❌ (missing tool)
File write ✅ | cat ✅ | Discussion ✅
Build ✅

🔮 The oracle has spoken through Smoke Codex for issue #1286

@github-actions
Copy link
Contributor

Chroot Version Comparison Results

Runtime Host Version Chroot Version Match?
Python Python 3.12.12 Python 3.12.3
Node.js v24.14.0 v20.20.0
Go go1.22.12 go1.22.12

Result: Not all runtimes matched — Go matches, but Python and Node.js versions differ between host and chroot.

Tested by Smoke Chroot for issue #1286

@github-actions
Copy link
Contributor

🏗️ Build Test Suite Results

Ecosystem Project Build/Install Tests Status
Bun elysia 1/1 passed ✅ PASS
Bun hono 1/1 passed ✅ PASS
C++ fmt N/A ✅ PASS
C++ json N/A ✅ PASS
Deno oak N/A 1/1 passed ✅ PASS
Deno std N/A 1/1 passed ✅ PASS
.NET hello-world N/A ✅ PASS
.NET json-parse N/A ✅ PASS
Go color passed ✅ PASS
Go env passed ✅ PASS
Go uuid passed ✅ PASS
Java gson 1/1 passed ✅ PASS
Java caffeine 1/1 passed ✅ PASS
Node.js clsx passed ✅ PASS
Node.js execa passed ✅ PASS
Node.js p-limit passed ✅ PASS
Rust fd 1/1 passed ✅ PASS
Rust zoxide 1/1 passed ✅ PASS

Overall: 8/8 ecosystems passed — ✅ PASS

Note: Java Maven required using the Squid proxy IP (172.30.0.10) instead of the hostname squid-proxy in settings.xml, as the hostname is only resolvable inside Docker containers.

Generated by Build Test Suite for issue #1286 ·

@Mossaka Mossaka merged commit f76ee0f into main Mar 13, 2026
61 checks passed
@Mossaka Mossaka deleted the feat/084-seccomp-hardening branch March 13, 2026 03:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[plan] harden seccomp profile with deny-by-default approach

2 participants