Configure Claude Code for sandboxed workspaces

- Add credentials bind mount in container.nix
- Create claude-credentials-dir service to copy credentials for VMs
- Generate .claude.json with onboarding skipped and workspace trusted
- Add allowUnfree to container config
This commit is contained in:
2026-02-08 14:53:31 -08:00
parent 87db330e5b
commit 5178ea6835
2 changed files with 75 additions and 28 deletions

View File

@@ -118,40 +118,79 @@ in
cfg.workspaces);
# Automatically generate SSH host keys and directories for all workspaces
systemd.services = lib.mapAttrs'
(name: ws:
let
serviceName = if ws.type == "vm" then "microvm@${name}" else "container@${name}";
in
lib.nameValuePair "workspace-${name}-setup" {
description = "Setup directories and SSH keys for workspace ${name}";
systemd.services = lib.mkMerge [
# Create credentials-only directory for VMs (symlinks to actual credentials)
{
claude-credentials-dir = {
description = "Setup Claude credentials directory for VM workspaces";
wantedBy = [ "multi-user.target" ];
before = [ "${serviceName}.service" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
User = "googlebot";
Group = "users";
};
script = ''
# Create directories if they don't exist
mkdir -p /home/googlebot/sandboxed/${name}/workspace
mkdir -p /home/googlebot/sandboxed/${name}/ssh-host-keys
mkdir -p /home/googlebot/sandboxed/${name}/claude-config
# Fix ownership
chown -R googlebot:users /home/googlebot/sandboxed/${name}
# Generate SSH host key if it doesn't exist
if [ ! -f /home/googlebot/sandboxed/${name}/ssh-host-keys/ssh_host_ed25519_key ]; then
${pkgs.openssh}/bin/ssh-keygen -t ed25519 -N "" \
-f /home/googlebot/sandboxed/${name}/ssh-host-keys/ssh_host_ed25519_key
chown googlebot:users /home/googlebot/sandboxed/${name}/ssh-host-keys/ssh_host_ed25519_key*
echo "Generated SSH host key for workspace ${name}"
mkdir -p /home/googlebot/.claude-credentials
# Copy credentials file (not symlink - virtiofs can't follow host symlinks)
if [ -f /home/googlebot/.claude/.credentials.json ]; then
cp /home/googlebot/.claude/.credentials.json /home/googlebot/.claude-credentials/.credentials.json
chmod 600 /home/googlebot/.claude-credentials/.credentials.json
fi
'';
}
)
cfg.workspaces;
};
}
# Per-workspace setup services
(lib.mapAttrs'
(name: ws:
let
serviceName = if ws.type == "vm" then "microvm@${name}" else "container@${name}";
claudeConfig = builtins.toJSON {
hasCompletedOnboarding = true;
theme = "dark";
projects = {
"/home/googlebot/workspace" = {
hasTrustDialogAccepted = true;
};
};
};
in
lib.nameValuePair "workspace-${name}-setup" {
description = "Setup directories and SSH keys for workspace ${name}";
wantedBy = [ "multi-user.target" ];
before = [ "${serviceName}.service" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
# Create directories if they don't exist
mkdir -p /home/googlebot/sandboxed/${name}/workspace
mkdir -p /home/googlebot/sandboxed/${name}/ssh-host-keys
mkdir -p /home/googlebot/sandboxed/${name}/claude-config
# Fix ownership
chown -R googlebot:users /home/googlebot/sandboxed/${name}
# Generate SSH host key if it doesn't exist
if [ ! -f /home/googlebot/sandboxed/${name}/ssh-host-keys/ssh_host_ed25519_key ]; then
${pkgs.openssh}/bin/ssh-keygen -t ed25519 -N "" \
-f /home/googlebot/sandboxed/${name}/ssh-host-keys/ssh_host_ed25519_key
chown googlebot:users /home/googlebot/sandboxed/${name}/ssh-host-keys/ssh_host_ed25519_key*
echo "Generated SSH host key for workspace ${name}"
fi
# Create claude-code config to skip onboarding and trust ~/workspace
if [ ! -f /home/googlebot/sandboxed/${name}/claude-config/.claude.json ]; then
echo '${claudeConfig}' > /home/googlebot/sandboxed/${name}/claude-config/.claude.json
chown googlebot:users /home/googlebot/sandboxed/${name}/claude-config/.claude.json
fi
'';
}
)
cfg.workspaces)
];
};
}