* Add secure mount allowlist validation Addresses arbitrary host mount vulnerability by validating additional mounts against an external allowlist stored at ~/.config/nanoclaw/. This location is never mounted into containers, making it tamper-proof. Security measures: - Allowlist cached in memory (edits require process restart) - Real path resolution (blocks symlink and .. traversal attacks) - Blocked patterns for sensitive paths (.ssh, .gnupg, .aws, etc.) - Non-main groups forced to read-only when nonMainReadOnly is true - Container path validation prevents /workspace/extra escape https://claude.ai/code/session_01BPqdNy4EAHHJcdtZ27TXkh * Add mount allowlist setup to /setup skill Interactive walkthrough that asks users: - Whether they want agents to access external directories - Which directories to allow (with paths) - Read-write vs read-only for each - Whether non-main groups should be restricted to read-only Creates ~/.config/nanoclaw/mount-allowlist.json based on answers. https://claude.ai/code/session_01BPqdNy4EAHHJcdtZ27TXkh --------- Co-authored-by: Claude <noreply@anthropic.com>
80 lines
2.1 KiB
TypeScript
80 lines
2.1 KiB
TypeScript
export interface AdditionalMount {
|
|
hostPath: string; // Absolute path on host (supports ~ for home)
|
|
containerPath: string; // Path inside container (under /workspace/extra/)
|
|
readonly?: boolean; // Default: true for safety
|
|
}
|
|
|
|
/**
|
|
* Mount Allowlist - Security configuration for additional mounts
|
|
* This file should be stored at ~/.config/nanoclaw/mount-allowlist.json
|
|
* and is NOT mounted into any container, making it tamper-proof from agents.
|
|
*/
|
|
export interface MountAllowlist {
|
|
// Directories that can be mounted into containers
|
|
allowedRoots: AllowedRoot[];
|
|
// Glob patterns for paths that should never be mounted (e.g., ".ssh", ".gnupg")
|
|
blockedPatterns: string[];
|
|
// If true, non-main groups can only mount read-only regardless of config
|
|
nonMainReadOnly: boolean;
|
|
}
|
|
|
|
export interface AllowedRoot {
|
|
// Absolute path or ~ for home (e.g., "~/projects", "/var/repos")
|
|
path: string;
|
|
// Whether read-write mounts are allowed under this root
|
|
allowReadWrite: boolean;
|
|
// Optional description for documentation
|
|
description?: string;
|
|
}
|
|
|
|
export interface ContainerConfig {
|
|
additionalMounts?: AdditionalMount[];
|
|
timeout?: number; // Default: 300000 (5 minutes)
|
|
env?: Record<string, string>;
|
|
}
|
|
|
|
export interface RegisteredGroup {
|
|
name: string;
|
|
folder: string;
|
|
trigger: string;
|
|
added_at: string;
|
|
containerConfig?: ContainerConfig;
|
|
}
|
|
|
|
export interface Session {
|
|
[folder: string]: string;
|
|
}
|
|
|
|
export interface NewMessage {
|
|
id: string;
|
|
chat_jid: string;
|
|
sender: string;
|
|
sender_name: string;
|
|
content: string;
|
|
timestamp: string;
|
|
}
|
|
|
|
export interface ScheduledTask {
|
|
id: string;
|
|
group_folder: string;
|
|
chat_jid: string;
|
|
prompt: string;
|
|
schedule_type: 'cron' | 'interval' | 'once';
|
|
schedule_value: string;
|
|
context_mode: 'group' | 'isolated';
|
|
next_run: string | null;
|
|
last_run: string | null;
|
|
last_result: string | null;
|
|
status: 'active' | 'paused' | 'completed';
|
|
created_at: string;
|
|
}
|
|
|
|
export interface TaskRunLog {
|
|
task_id: string;
|
|
run_at: string;
|
|
duration_ms: number;
|
|
status: 'success' | 'error';
|
|
result: string | null;
|
|
error: string | null;
|
|
}
|