Files

1 line
9.3 KiB
JSON

{"repo": "canyonroad/agentsh-daytona", "files": {"config.yaml": {"9611f77228698876b3742fb3b59537692394fb79": {"t": 1785674479.0370154, "n": 9000, "h": "176a1f9807d4c866", "c": "# agentsh server configuration for Daytona sandbox\n# Updated for agentsh v0.20.2\n# Policy-based security mode (relies on default.yaml for enforcement)\n\nserver:\n http:\n addr: \"127.0.0.1:18080\"\n read_timeout: \"30s\"\n write_timeout: \"60s\"\n max_request_size: \"10MB\"\n grpc:\n enabled: true\n addr: \"127.0.0.1:9090\"\n\nauth:\n type: \"none\"\n\nlogging:\n level: \"info\"\n format: \"json\"\n output: \"stderr\"\n rotation:\n max_size_mb: 100\n max_age_days: 7\n compress: true\n\nsessions:\n base_dir: \"/var/lib/agentsh/sessions\"\n max_sessions: 100\n default_timeout: \"1h\"\n default_idle_timeout: \"15m\"\n cleanup_interval: \"5m\"\n\naudit:\n enabled: true\n format: \"jsonl\"\n storage:\n sqlite_path: \"/var/lib/agentsh/events.db\"\n retention:\n max_age_days: 90\n\n# =============================================================================\n# SECURITY CONFIGURATION (v0.20.2)\n# =============================================================================\n\n# Simplified security - rely on policy rules in default.yaml\n# v0.8.1: Added execve interception with depth-aware policies\n# v0.8.9: Added env_inject for operator-controlled variable injection\n# v0.9.0: Added dns_redirect and connect_redirect capabilities\n# v0.9.3: Agent wrap, cross-platform exec interception\n# v0.9.5: Landlock filesystem enforcement (kernel 5.13+)\n# v0.9.9: FUSE filesystem interception with deferred mounting\n# v0.10.0: BASH_ENV injection for builtin disabling, Landlock execution paths\n# v0.17.0: Declared http_services with /svc routing, secret providers\n# v0.18.0: Unified http_services declaration, HMAC chain tamper-evidence\n# v0.19.0: Per-AF_* socket family blocking (seccomp-bpf with ptrace fallback)\n# v0.19.1: Shim-installed kernel enforcement (seccomp wrapper at the kernel layer)\n# v0.19.3: Dirty Frag mitigation_sets, protocol-aware socket tuple rules\n# (NOTE: sandbox.seccomp.hardening_profiles was removed -> mitigation_sets)\n# v0.20.0: PostgreSQL access proxy, attach-only cgroup mode, eBPF hardening\n# v0.20.1: FUSE symlink venv fix + policies.symlink_escape knob, Watchtower PolicyPush\n# v0.20.2: opaque shell-c is interception-aware (runs under ptrace/seccomp-execve\n# instead of being pre-denied) + sandbox.seccomp.shellc.opaque knob;\n# config validate hardened; command -v allowed; symlink_escape=deny no\n# longer blanket-denies a symlinked cwd\n\nsandbox:\n enabled: true\n allow_degraded: true\n\n # v0.20.2: disable the unix-socket exec wrapper. With unix_sockets enabled the\n # v0.19+ shim routes every exec through agentsh-unixwrap, which loads a seccomp\n # filter; in Daytona that load fails (no-new-privileges) and EVERY command exits\n # 1 (\"seccomp: filter Load failed ... agentsh-unixwrap\"). Disabling it bypasses\n # the wrapper so commands run under the shim + FUSE/Landlock without seccomp.\n unix_sockets:\n enabled: false\n\n limits:\n max_memory_mb: 4096\n max_cpu_percent: 100\n max_processes: 256\n\n network:\n enabled: true\n intercept_mode: \"all\"\n proxy_listen_addr: \"127.0.0.1:0\"\n\n # v0.8.1: Seccomp file_monitor can enforce file_rules on ALL paths (including\n # /proc, /sys) via openat/stat interception. However, installing seccomp filters\n # requires privileges that Daytona's container runtime does not grant (the\n # no-new-privileges flag blocks seccomp() syscalls). If Daytona relaxes this,\n # enable the following to block /proc/1/environ reads at the syscall level:\n # seccomp:\n # file_monitor:\n # enabled: true\n # enforce_without_fuse: true\n # intercept_metadata: true\n\n # v0.9.9: FUSE filesystem interception with deferred mounting for containers\n # Use /dev/fuse as marker (daytona user is in fuse group, no sudo needed)\n fuse:\n enabled: true\n deferred: true\n deferred_marker_file: \"/dev/fuse\"\n audit:\n enabled: true\n mode: \"soft_delete\"\n trash_path: \"/home/daytona/.agentsh_trash\"\n\n # v0.9.5: Landlock filesystem enforcement - restrict binary execution paths\n landlock:\n enabled: true\n allow_execute:\n - /usr/bin\n - /bin\n - /usr/local/bin\n - /usr/sbin\n - /sbin\n - /usr/lib\n - /lib\n network:\n allow_connect_tcp: true\n allow_bind_tcp: true\n\n # v0.20.2: opaque shell-c handling (issue #375 fix).\n # The v0.19+ shim, by default (shellc.opaque=enforce), pre-denies any `bash -c`\n # script it can't statically prove safe (anything with a pipe/redirect/$VAR/etc.)\n # unless runtime execve interception is active. In Daytona we CANNOT enable that\n # interception: seccomp filters can't be installed (no-new-privileges), and the\n # ptrace path also fails because agentsh-unixwrap loads a seccomp prefilter\n # (observed at runtime: \"seccomp: filter Load failed ... agentsh-unixwrap\").\n # So we permit opaque shell-c to RUN without per-exec enforcement. Still enforced:\n # FUSE file rules, Landlock exec paths, the network proxy, and shim pre-checks on\n # non-opaque commands (sudo/su -> block-shell-escape). Tradeoff: a blocked command\n # hidden *inside* an opaque script is backstopped by the container\n # (no-new-privileges + capability drop), not by agentsh per-exec policy.\n seccomp:\n shellc:\n opaque: allow\n\n # v0.20.2: ptrace execve enforcement WITH the seccomp prefilter.\n # The prefilter is a basic BPF filter that returns SECCOMP_RET_TRACE only for\n # execve (RET_ERRNO for static denies, RET_ALLOW otherwise), installed with\n # TSYNC -- NOT a NEW_LISTENER user-notify listener. So it does NOT hit the EBUSY\n # listener conflict that blocks the unixwrap seccomp-notify path in Daytona\n # (Daytona's container holds the one allowed user-notify listener; basic filters\n # still stack fine). Benefits over prefilter:false (pure TRACESYSGOOD):\n # - ptrace is woken only on execve, not every syscall -> no perf cliff\n # - the filter is inherited across fork/exec -> covers ALL descendants, which\n # should close the nested-exec leak (xargs/find/python/script -> sudo).\n # unix_sockets stays false to avoid the unixwrap NEW_LISTENER path (which DOES EBUSY).\n ptrace:\n enabled: true\n attach_mode: children\n on_attach_failure: fail_closed\n performance:\n seccomp_prefilter: true\n trace:\n execve: true\n file: false\n network: false\n signal: false\n\n # v0.8.9: Operator-controlled environment variable injection\n # These bypass env_policy filtering since they're operator-controlled\n env_inject:\n # Ensure agentsh server is always reachable\n AGENTSH_SERVER: \"http://127.0.0.1:18080\"\n # Activate bash_startup.sh to disable dangerous builtins (kill, enable, ulimit, etc.)\n BASH_ENV: \"/usr/lib/agentsh/bash_startup.sh\"\n # Daytona workspace variables (operator-controlled)\n # DAYTONA_WS_DIR: \"/home/daytona/workspace\"\n\nproxy:\n mode: \"embedded\"\n port: 0\n providers:\n anthropic: \"https://api.anthropic.com\"\n openai: \"https://api.openai.com\"\n\ndlp:\n mode: \"redact\"\n patterns:\n email: true\n phone: true\n credit_card: true\n ssn: true\n api_keys: true\n custom_patterns:\n - name: openai_key\n display: OPENAI_KEY\n regex: \"sk-[a-zA-Z0-9]{48,}\"\n - name: anthropic_key\n display: ANTHROPIC_KEY\n regex: \"sk-ant-[a-zA-Z0-9-]{95,}\"\n - name: aws_access_key\n display: AWS_KEY\n regex: \"AKIA[0-9A-Z]{16}\"\n - name: github_pat\n display: GITHUB_TOKEN\n regex: \"ghp_[a-zA-Z0-9]{36}\"\n - name: github_oauth\n display: GITHUB_OAUTH\n regex: \"gho_[a-zA-Z0-9]{36}\"\n - name: jwt_token\n display: JWT\n regex: \"eyJ[a-zA-Z0-9_-]*\\\\.eyJ[a-zA-Z0-9_-]*\\\\.[a-zA-Z0-9_-]*\"\n - name: private_key\n display: PRIVATE_KEY\n regex: \"-----BEGIN [A-Z]+ PRIVATE KEY-----\"\n - name: slack_token\n display: SLACK_TOKEN\n regex: \"xox[baprs]-[0-9]{10,13}-[0-9]{10,13}-[a-zA-Z0-9]{24}\"\n - name: daytona_api_key\n display: DAYTONA_KEY\n regex: \"dtn_[a-zA-Z0-9]{64}\"\n - name: google_api_key\n display: GOOGLE_KEY\n regex: \"AIza[0-9A-Za-z\\\\-_]{35}\"\n\npolicies:\n dir: \"/etc/agentsh/policies\"\n default: \"default\"\n # v0.20.1: How to treat symlinks whose targets resolve outside the sandbox root.\n # \"evaluate\" (new default) follows the link and checks the target against\n # file_rules; \"deny\" is a blanket-deny of any such symlink.\n # MUST be \"evaluate\" here: Daytona's /home/daytona working dir is itself reached\n # via a symlink that escapes the FUSE workspace mount, so \"deny\" blocks EVERY\n # command at cwd resolution (rule=workspace-escape). The resolved target is still\n # checked against file_rules, so sensitive reads stay blocked.\n symlink_escape: evaluate\n project_markers:\n - \".git\"\n - \"package.json\"\n - \"Cargo.toml\"\n - \"go.mod\"\n - \"pyproject.toml\"\n - \"requirements.txt\"\n\napprovals:\n enabled: false\n mode: \"async\"\n timeout: \"5m\"\n\nmetrics:\n enabled: true\n path: \"/metrics\"\n\nhealth:\n path: \"/health\"\n readiness_path: \"/ready\"\n\ndevelopment:\n disable_auth: true\n verbose_errors: false\n"}}}}