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

@@ -1,4 +1,4 @@
{ config, lib, ... }:
{ config, lib, pkgs, ... }:
# Container-specific configuration for sandboxed workspaces using systemd-nspawn
# This module is imported by default.nix for workspaces with type = "container"
@@ -47,10 +47,16 @@ in
hostPath = "/home/googlebot/sandboxed/${name}/ssh-host-keys";
isReadOnly = false;
};
# Per-workspace claude config for isolated session data
"/home/googlebot/claude-config" = {
hostPath = "/home/googlebot/sandboxed/${name}/claude-config";
isReadOnly = false;
};
# Share credentials from host (read-only)
"/home/googlebot/claude-config/.credentials.json" = {
hostPath = "/home/googlebot/.claude/.credentials.json";
isReadOnly = true;
};
};
config = { config, lib, pkgs, ... }: {
@@ -65,6 +71,8 @@ in
];
networking.useHostResolvConf = false;
nixpkgs.config.allowUnfree = true;
};
})
containerWorkspaces;

View File

@@ -118,10 +118,42 @@ in
cfg.workspaces);
# Automatically generate SSH host keys and directories for all workspaces
systemd.services = lib.mapAttrs'
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" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
User = "googlebot";
Group = "users";
};
script = ''
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
'';
};
}
# 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}";
@@ -149,9 +181,16 @@ in
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;
cfg.workspaces)
];
};
}