feat(nix): improve Nextcloud Claude Bot security and user setup

- Set `User` and `Group` for the bot service to enhance security and isolation.
- Added system user and group for `claude-bot` with defined home directory.
- Modified secrets ownership to align with the new bot user.
This commit is contained in:
Harald Hoyer 2026-02-03 16:14:21 +01:00
parent b1370b5fc6
commit d5967cf392
2 changed files with 16 additions and 5 deletions

View file

@ -12,6 +12,7 @@
sops.secrets."nextcloud-claude-bot/secret" = { sops.secrets."nextcloud-claude-bot/secret" = {
sopsFile = ../../../../.secrets/hetzner/nextcloud-claude-bot.yaml; sopsFile = ../../../../.secrets/hetzner/nextcloud-claude-bot.yaml;
restartUnits = [ "nextcloud-claude-bot.service" ]; restartUnits = [ "nextcloud-claude-bot.service" ];
owner = "claude-bot";
}; };
# Nginx location for Nextcloud to send webhooks to the bot # Nginx location for Nextcloud to send webhooks to the bot

View file

@ -83,6 +83,7 @@ in {
after = [ "network.target" ]; after = [ "network.target" ];
environment = { environment = {
HOME = "/var/lib/nextcloud-claude-bot";
BOT_HOST = cfg.host; BOT_HOST = cfg.host;
BOT_PORT = toString cfg.port; BOT_PORT = toString cfg.port;
NEXTCLOUD_URL = cfg.nextcloudUrl; NEXTCLOUD_URL = cfg.nextcloudUrl;
@ -99,9 +100,11 @@ in {
ExecStart = "${pythonEnv}/bin/uvicorn nextcloud_claude_bot:app --host ${cfg.host} --port ${toString cfg.port}"; ExecStart = "${pythonEnv}/bin/uvicorn nextcloud_claude_bot:app --host ${cfg.host} --port ${toString cfg.port}";
Restart = "always"; Restart = "always";
RestartSec = 5; RestartSec = 5;
User = "claude-bot";
Group = "claude-bot";
# Security hardening # Security hardening
DynamicUser = true;
NoNewPrivileges = true; NoNewPrivileges = true;
ProtectSystem = "strict"; ProtectSystem = "strict";
ProtectHome = "read-only"; ProtectHome = "read-only";
@ -115,15 +118,22 @@ in {
RestrictSUIDSGID = true; RestrictSUIDSGID = true;
MemoryDenyWriteExecute = false; # Python needs this MemoryDenyWriteExecute = false; # Python needs this
LockPersonality = true; LockPersonality = true;
# Bot secret # Bot secret
LoadCredential = "bot-secret:${cfg.botSecretFile}"; LoadCredential = "bot-secret:${cfg.botSecretFile}";
# Claude CLI needs home for config # Claude CLI needs home for config
StateDirectory = "nextcloud-claude-bot"; StateDirectory = "nextcloud-claude-bot";
Environment = "HOME=/var/lib/nextcloud-claude-bot";
}; };
}; };
users.users.claude-bot = {
isSystemUser = true;
group = "claude-bot";
home = "/var/lib/nextcloud-claude-bot";
};
users.groups.claude-bot = {};
# Nginx reverse proxy config (optional, if you want external access) # Nginx reverse proxy config (optional, if you want external access)
# services.nginx.virtualHosts."cloud.example.com".locations."/claude-bot/" = { # services.nginx.virtualHosts."cloud.example.com".locations."/claude-bot/" = {