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:
@@ -1,6 +1,7 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
# Claude Code for the primary user, configured through home-manager, which ships
|
||||
@@ -23,38 +24,72 @@ let
|
||||
];
|
||||
in
|
||||
{
|
||||
options.modules.claude-code.enable = lib.mkEnableOption "Claude Code, Anthropic's CLI, configured via home-manager";
|
||||
options.modules.claude-code.enable = lib.mkEnableOption ''
|
||||
Claude Code, Anthropic's CLI, configured via home-manager.
|
||||
|
||||
Enabling this also widens sudo's credential cache, keying it per user rather
|
||||
than per terminal and holding it for 60 minutes, so that a single
|
||||
authentication covers commands the agent issues. No command is made
|
||||
passwordless, but any process running as the primary user can spend the
|
||||
cached credential while it lasts. Suitable for a single-user machine'';
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
home-manager.users.${user}.programs.claude-code = {
|
||||
enable = true;
|
||||
# Keying sudo's credential cache per user rather than per terminal lets one
|
||||
# authentication cover commands issued by processes holding no terminal of
|
||||
# their own. Any process running as this user can spend that credential
|
||||
# until it lapses, so this suits a single-user machine.
|
||||
security.sudo.extraConfig = ''
|
||||
Defaults timestamp_type=global
|
||||
Defaults timestamp_timeout=60
|
||||
'';
|
||||
|
||||
# Global agent instructions, rendered to ~/.claude/CLAUDE.md.
|
||||
context = ./CLAUDE.md;
|
||||
home-manager.users.${user} = {
|
||||
# jq parses the tool input handed to the sudo guard hook.
|
||||
home.packages = [ pkgs.jq ];
|
||||
|
||||
# One directory per skill, symlinked under ~/.claude/skills.
|
||||
skills = ./skills;
|
||||
programs.claude-code = {
|
||||
enable = true;
|
||||
|
||||
# Installed at ~/.claude/hooks/attention-bell.sh, referenced by the settings below.
|
||||
hooks."attention-bell.sh" = builtins.readFile ./hooks/attention-bell.sh;
|
||||
# Global agent instructions, rendered to ~/.claude/CLAUDE.md.
|
||||
context = ./CLAUDE.md;
|
||||
|
||||
settings = {
|
||||
model = "opus";
|
||||
hooks = {
|
||||
Stop = bellHook;
|
||||
Notification = bellHook;
|
||||
SessionStart = [
|
||||
{
|
||||
matcher = "";
|
||||
hooks = [
|
||||
{
|
||||
type = "command";
|
||||
command = "gitea-axi";
|
||||
timeout = 10;
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
# One directory per skill, symlinked under ~/.claude/skills.
|
||||
skills = ./skills;
|
||||
|
||||
# Installed under ~/.claude/hooks, referenced by the settings below.
|
||||
hooks."attention-bell.sh" = builtins.readFile ./hooks/attention-bell.sh;
|
||||
hooks."agent-sudo-guard.sh" = builtins.readFile ./hooks/agent-sudo-guard.sh;
|
||||
|
||||
settings = {
|
||||
model = "opus";
|
||||
hooks = {
|
||||
Stop = bellHook;
|
||||
Notification = bellHook;
|
||||
PreToolUse = [
|
||||
{
|
||||
matcher = "Bash";
|
||||
hooks = [
|
||||
{
|
||||
type = "command";
|
||||
command = "~/.claude/hooks/agent-sudo-guard.sh";
|
||||
timeout = 10;
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
SessionStart = [
|
||||
{
|
||||
matcher = "";
|
||||
hooks = [
|
||||
{
|
||||
type = "command";
|
||||
command = "gitea-axi";
|
||||
timeout = 10;
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user