feat(claude-code): share sudo's credential cache across sessions (task 0018)
Key sudo's credential cache per user rather than per terminal, holding it for 60 minutes. An authentication made in the operator's own terminal then covers commands issued by processes holding no terminal of their own, which previously failed with a bare non-zero exit and no output. No command is made passwordless. The password remains required; only the cache holding it is shared, and any process running as the primary user can spend that credential until it lapses. A PreToolUse hook refuses a privileged command while the cache is cold, naming the command that warms it, so the condition announces itself rather than presenting as a stall. Both states were exercised against the running system.
This commit is contained in:
29
modules/claude-code/hooks/agent-sudo-guard.sh
Executable file
29
modules/claude-code/hooks/agent-sudo-guard.sh
Executable file
@@ -0,0 +1,29 @@
|
||||
#!/bin/sh
|
||||
# agent-sudo-guard.sh — refuse a privileged command while sudo's credential
|
||||
# cache is cold, naming the command that warms it.
|
||||
#
|
||||
# Commands arrive here from subprocesses holding no terminal, so an uncached
|
||||
# sudo fails with a bare non-zero exit and no output, reading as an unexplained
|
||||
# stall. The probe below reads a cache keyed per user rather than per terminal,
|
||||
# so an authentication made in the operator's own terminal counts.
|
||||
|
||||
input=$(cat)
|
||||
command=$(printf '%s' "$input" | jq -r '.tool_input.command // ""')
|
||||
|
||||
# Anchored to a command position so a `sudo` appearing as an argument or inside
|
||||
# a string does not trip the guard.
|
||||
if ! printf '%s' "$command" | grep -qE '(^|[;&|(]|&&|\|\|)[[:space:]]*sudo([[:space:]]|$)'; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if sudo -n true 2>/dev/null; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Exit 2 blocks the call and feeds stderr back to the agent.
|
||||
echo 'Blocked: sudo has no cached credential, and this command cannot answer a password prompt.
|
||||
Ask the operator to run `sudo -v` in their own terminal, then retry.
|
||||
Never attempt to supply a password directly.
|
||||
If this still blocks immediately after the operator runs `sudo -v`, the cache is
|
||||
not the cause: check that this hook can reach sudo at all.' >&2
|
||||
exit 2
|
||||
Reference in New Issue
Block a user