Files

1 line
9.2 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"repo": "canyonroad/agentsh-runloop", "files": {"config.yaml": {"6c2a69a532673dd37a5f7541bf396d25fd99f477": {"t": 1785674471.1911724, "n": 8841, "h": "8851aa0d73be227e", "c": "# agentsh server configuration for Runloop Devboxes\n# Based on: agentsh detect (v0.20.3) | Security Mode: minimal (65/100)\n# Platform: linux | Kernel: 6.18.5 | Runloop harness: 70 pass / 3 platform-limited\n#\n# Detected capabilities on Runloop (agentsh detect, v0.20.3):\n# ✓ seccomp_user_notify + seccomp-execve + seccomp-notify (file) — ONLY with\n# the unix_sockets wrapper DISABLED (see seccomp section); the wrapper and\n# agentsh's own NEW_LISTENER fight over the single listener slot (EBUSY).\n# ✓ seccomp BPF (basic), capabilities_drop (41/41)\n# ✗ fuse (not mounting, /dev/fuse 0600), cgroups-v2 (no pids controller)\n# ✗ ebpf (no BTF), landlock-network, ptrace (no CAP_SYS_PTRACE)\n#\n# Enforcement: agentsh installs the seccomp_user_notify listener itself, giving\n# real execve + openat interception for SERVER-routed commands — so network\n# policy (exfil/SSRF/metadata) and command policy are genuinely enforced.\n# Combined with seccomp BPF (signals/syscalls), chmod'd priv-esc binaries,\n# BASH_ENV builtin disabling, capability drop, and the shell shim.\n# NOTE: Runloop launches the shim directly, so the shim's OWN process is not\n# under the listener — shell-RC writes via redirect and sh-builtin signals are\n# not seccomp-policed (see README \"Known limitations on Runloop\").\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: \"text\"\n output: \"stderr\"\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 storage:\n sqlite_path: \"/var/lib/agentsh/events.db\"\n\nsandbox:\n enabled: true\n allow_degraded: true\n\n limits:\n max_memory_mb: 4096\n max_cpu_percent: 100\n max_processes: 256\n\n # FUSE: /dev/fuse exists on Runloop Devboxes but has root-only permissions\n # (crw------- 0600). Since the agent user has passwordless sudo, deferred\n # mode chmod's the device to world-accessible on first session start.\n # This enables VFS-level file interception, soft-delete, and redirect.\n fuse:\n enabled: true\n deferred: true\n deferred_enable_command: [\"sudo\", \"/bin/chmod\", \"666\", \"/dev/fuse\"]\n\n network:\n enabled: true\n intercept_mode: \"all\"\n proxy_listen_addr: \"127.0.0.1:0\"\n\n # cgroups_v2: DISABLED on Runloop (v0.18.0+).\n # The v0.18.0 capability probe is stricter and requires proper cgroup\n # delegation (subtree_control writable, leaf-move on EBUSY). Runloop's\n # cgroup setup doesn't satisfy this, so enforcement is unavailable and\n # the probe fails closed. Resource limits are still enforced by Runloop.\n cgroups:\n enabled: false\n\n # Seccomp: BPF filter + seccomp_user_notify both work on Runloop — but ONLY\n # when agentsh installs the user-notify listener itself. Do NOT enable the\n # unix_sockets wrapper (see below): it grabs the single NEW_LISTENER slot so\n # agentsh's own install fails with EBUSY, dropping to minimal mode (15/100).\n # With unix_sockets disabled, detect reports seccomp-notify + seccomp-execve\n # active (65/100): real openat/stat and execve interception.\n seccomp:\n enabled: true\n # shellc.opaque (v0.20.2, #386): how the shell shim treats an unparseable\n # `bash -c`/`sh -c` script body. Runloop's execute_sync spawns the shim as\n # `/bin/bash -lc \"<cmd>\"` DIRECTLY, so the shim's own process is not under\n # the agentsh server's user-notify filter — it cannot police the execs\n # inside an opaque script (anything with a pipe, redirect, `&&`, `$()`, or\n # nested `bash -c`).\n # deny — always reject (rule=shellc-opaque-script)\n # enforce — police-if-interception-active, else fail closed. On Runloop\n # this denies EVERY opaque command (curl ... | head, echo > f,\n # `agentsh detect 2>&1`, etc.) because the shim isn't traced.\n # allow — run opaque scripts. REQUIRED here. Parseable single commands\n # are still routed through policy by the shim; the inner execs\n # of opaque scripts fall back to the kernel/chmod/BASH_ENV/DAC\n # layers. (file_monitor/network proxy only cover server-spawned\n # processes, which the directly-launched shim children are not.)\n shellc:\n opaque: allow\n file_monitor:\n enabled: true\n enforce_without_fuse: true\n syscalls:\n on_block: \"errno\"\n block:\n # Default dangerous syscalls\n - ptrace\n - process_vm_readv\n - process_vm_writev\n - personality\n - mount\n - umount2\n - pivot_root\n - reboot\n - kexec_load\n - init_module\n - finit_module\n - delete_module\n - sethostname\n - setdomainname\n # Signal syscalls — blocks dash builtin kill at kernel level\n - kill\n - tgkill\n - tkill\n\n # unix_sockets wrapper (agentsh-unixwrap): DISABLED on the v0.20.x line.\n # On v0.16–v0.18 this wrapper was the mechanism that made seccomp_user_notify\n # work. Since v0.20.2 agentsh installs the user-notify NEW_LISTENER itself,\n # and the wrapper now CONFLICTS: it occupies the single listener slot, so\n # agentsh's install fails with \"device or resource busy (errno 16)\" and the\n # server falls back to minimal mode. Disabling it lets agentsh own the\n # listener directly — restoring seccomp-notify (file) + seccomp-execve\n # (command) interception.\n unix_sockets:\n enabled: false\n\n # Ptrace: disabled. ptrace enforcement needs CAP_SYS_PTRACE, which Runloop\n # does not grant (raw PTRACE_TRACEME returns EPERM; the agentsh ptrace backend\n # stays inactive). Not needed — seccomp_user_notify is the active backend.\n ptrace:\n enabled: false\n\n # env_inject: Inject environment variables into spawned commands.\n # BASH_ENV disables dangerous bash builtins (kill, enable, ulimit, etc.) as a\n # defense-in-depth layer alongside the seccomp_user_notify interception.\n env_inject:\n BASH_ENV: \"/usr/lib/agentsh/bash_startup.sh\"\n\nproxy:\n mode: \"embedded\"\n port: 0\n rate_limits:\n enabled: true\n requests_per_minute: 60\n tokens_per_minute: 90000\n providers:\n anthropic: \"https://api.anthropic.com\"\n openai: \"https://api.openai.com\"\n\n# DLP: Redact sensitive data before it reaches AI models\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 # Runloop API keys\n - name: runloop_key\n display: RUNLOOP_KEY\n regex: \"rl_[a-zA-Z0-9]{32,}\"\n # OpenAI keys\n - name: openai_key\n display: OPENAI_KEY\n regex: \"sk-[a-zA-Z0-9]{48,}\"\n # Anthropic keys\n - name: anthropic_key\n display: ANTHROPIC_KEY\n regex: \"sk-ant-[a-zA-Z0-9-]{95,}\"\n # AWS access keys\n - name: aws_access_key\n display: AWS_KEY\n regex: \"AKIA[0-9A-Z]{16}\"\n # GitHub tokens\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 # JWT tokens\n - name: jwt_token\n display: JWT\n regex: \"eyJ[a-zA-Z0-9_-]*\\\\.eyJ[a-zA-Z0-9_-]*\\\\.[a-zA-Z0-9_-]*\"\n # Private keys\n - name: private_key\n display: PRIVATE_KEY\n regex: \"-----BEGIN [A-Z]+ PRIVATE KEY-----\"\n # Slack tokens\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\nthreat_feeds:\n enabled: true\n action: deny\n feeds:\n - name: urlhaus\n url: https://urlhaus.abuse.ch/downloads/hostfile/\n format: hostfile\n sync_interval: 6h\n\npackage_checks:\n enabled: true\n scope: new_packages_only\n providers:\n osv:\n enabled: true\n timeout: 10s\n on_failure: warn\n\npolicies:\n dir: \"/etc/agentsh/policies\"\n default_policy: \"default\"\n\n# Capability drop: Remove dangerous capabilities from spawned commands.\n# Uses allowlist approach — only listed capabilities are kept, all others\n# are dropped from the bounding set via prctl(PR_CAPBSET_DROP).\n# Always dropped (cannot be allowed): CAP_SYS_ADMIN, CAP_SYS_PTRACE,\n# CAP_SYS_MODULE, CAP_DAC_OVERRIDE, CAP_SETUID, CAP_SETGID, CAP_CHOWN,\n# CAP_FOWNER, CAP_MKNOD, CAP_NET_ADMIN, CAP_SYS_CHROOT, etc.\n# Default dropped (can be allowed): CAP_KILL, CAP_NET_RAW, CAP_NET_BIND_SERVICE.\n# This is a kernel-level safety net — even if ptrace races and sudo executes,\n# it can't escalate privileges without CAP_SETUID.\ncapabilities:\n allow: []\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"}}}}