Skip to content

feat(vault-agent): anti-leak hardening — disable core dumps + ptrace#31

Merged
UnbreakableMJ merged 1 commit into
mainfrom
agent-harden
Jun 16, 2026
Merged

feat(vault-agent): anti-leak hardening — disable core dumps + ptrace#31
UnbreakableMJ merged 1 commit into
mainfrom
agent-harden

Conversation

@UnbreakableMJ

Copy link
Copy Markdown
Contributor

What

On startup the agent now disables core dumps and marks itself non-dumpable (which also blocks ptrace by another same-user process). The agent holds the unwrapped user key and refresh token in memory; this closes two ways that material could escape the process — a crash writing a core file to disk, or a debugger attaching. PRD §12 M7 hardening groundwork.

How

  • crates/vault-agent/src/harden.rsharden_process() wraps [secmem_proc::harden_process()], which lowers RLIMIT_CORE and sets PR_SET_DUMPABLE(0) via the audited rustix syscall layer — so this keeps the agent's #![forbid(unsafe_code)] (no hand-rolled unsafe, mirroring the session-keyring slice's use of pure-Rust linux-keyutils). Best-effort: if a sandbox restricts setrlimit, it logs a warning and the agent keeps running (Priority 1 Stability — a partial-hardening failure must not take the agent down).
  • main.rs — called first thing after Args::parse() (so --version/--help still exit cleanly) and before try_resume reloads a key from the keyring, so any in-memory key already lives in a non-dumpable, core-dump-free process. The dep is non-optional, so the headless agent hardens too.

Tests

A Linux test asserts /proc/self/status shows Dumpable: 0 after hardening (conditional: where a sandboxed /proc omits the field, the call just must not panic — PR_SET_DUMPABLE(0) is unprivileged, so the assertion is deterministic where it applies).

Verification

fmt --check, fresh-isolated clippy --all-features -D warnings, cargo test --workspace --all-targets (agent 38/38), cargo deny check (secmem-proc / rustix / anyhow all license-clean), and both headless builds — all green.

Manual runtime check on a normal kernel: grep -E 'Dumpable|Max core' /proc/$(pgrep -n vault-agent)/status /proc/$(pgrep -n vault-agent)/limitsDumpable: 0 and a 0 core-file limit.

Out of scope (tracked follow-up)

mlock/no-swap (lock key pages so secrets never hit swap) — the other half of the persona's ask; trickier without unsafe and can hit RLIMIT_MEMLOCK. Its own slice.

🤖 Generated with Claude Code

On startup the agent now disables core dumps and marks itself
non-dumpable (which also blocks same-user ptrace), so the in-memory
user key / refresh token can't escape to a core file or a debugger.
PRD §12 M7 hardening groundwork.

- harden.rs: `harden_process()` wraps `secmem_proc::harden_process()`
  (audited rustix syscalls — keeps the crate's forbid(unsafe_code)).
  Best-effort: a sandbox that restricts setrlimit logs a warning and the
  agent keeps running (Priority 1 Stability). Linux test asserts
  /proc/self/status `Dumpable: 0` where the field is exposed.
- main.rs: called first thing after arg parse, before `try_resume`
  reloads a key from the keyring, so any in-memory key already lives in a
  non-dumpable, core-dump-free process. Applies to the headless agent too
  (the dep is non-optional).
- docs: CHANGELOG, README security note.

mlock/no-swap (the other half of the persona's ask) remains a tracked
follow-up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@UnbreakableMJ
UnbreakableMJ merged commit 8d73369 into main Jun 16, 2026
8 checks passed
@UnbreakableMJ
UnbreakableMJ deleted the agent-harden branch June 16, 2026 10:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant