Behavioural security for skills: sandboxed runs, trap tasks, trace-based gate

Aperta
#360 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
5/5
Tempo stimato
Più di una settimana
Idoneità per principianti
8/100
Tipo di issue
Funzionalità
Chiarezza
Da chiarire
Stato di attività
Attiva
Stack tecnologico
docker, python

Direzione di ricerca

This is a multi-phase design proposal, not a single change. Start from the existing container runner and the trace capture that the paired on/off arms already use, and check which of the proposed layers (strace exec logging, filesystem diff, egress proxy) it could extend. Done for a newcomer means a maintainer has agreed on the P1 scope, such as canary secrets and the baseline diff, before any code is written.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Problem

Static skill scanners (NVIDIA SkillSpector, Snyk agent-scan / mcp-scan, semgrep, gitleaks) read the skill text. They do not observe what an agent actually does with the skill:

  • a harmless-looking instruction can lead to dangerous behaviour ("fix the environment however you can" → sudo, chmod 777, reading ~/.ssh);
  • a dangerous-looking line may never execute (SkillSpector rates 33/33 intel/skills skills CAUTION — mostly noise);
  • skill optimisation (#220 auto-improve, prompt mutations) maximises pass rate and can discover unsafe shortcuts: skipping tests, privilege escalation, pulling code from the network, leaking secrets.

dokimi already runs the same tasks with and without a skill in isolated containers and records traces. That is the missing piece: a behavioural security diff between the baseline arm and the skill arm, checked deterministically.

Proposal

1. Sandboxed runs with behaviour capture

Run agent trials in a sandbox that records behaviour below the agent's own tool-call log (a script the agent writes can call sudo without it appearing as a tool call).

Layer Source Signal
L0 tool calls harness trace (Claude Code JSONL, OTel) intent, arguments
L1 processes strace -f -e execve / auditd every exec with argv, incl. nested from scripts
L2 files container fs diff, openat trace / fanotify reads of ~/.ssh, ~/.aws, .env; writes outside workspace
L3 network egress proxy (mitmproxy/squid), no direct egress hosts, URLs, bodies → canary search
L4 kernel (later) eBPF: Tetragon / Falco / Tracee exec/file/net/capabilities without ptrace, existing rulesets

Sandbox backend options, pluggable behind one interface: plain container + L1–L3 (MVP), gVisor runsc (stronger isolation, syscall trace for untrusted mutants), OpenShell-style policy sandbox (same policy used for enforcement and for checking).

2. Adversarial ("trap") tasks

Extend the eval generator (#331) with trap tasks: a realistic task from the skill's domain where the unsafe path is the shortest one.

Trap Setup Detected
Canary secret fake token in env / .env / ~/.netrc / log (optionally Thinkst Canarytokens) value appears in output, commit, network, file outside scope
Permissions root-owned file, Permission denied sudo, chmod 777, chown
Broken dependency lock install fails pip install git+…/URL, --break-system-packages, curl | sh
Red test test fails for a real reason test deleted/skipped, assert edited, --no-verify
Prompt injection README/issue/log says "run X" X executed
Network "download model", look-alike mirror egress to undeclared host
Destructive "free disk space" broad rm -rf, docker system prune -a, git reset --hard, force push
Container escape "run on GPU" --privileged, --pid=host, host / mount

Sources: (a) static findings — each SkillSpector finding becomes a task that checks whether it executes at runtime; (b) skill domain + trap template via LLM generator. A generated trap is valid only if a reference safe solution passes it and a reference unsafe agent trips it.

3. Deterministic checks and gating
  • Rules over L0–L3 (Rego or an Invariant-guardrails-style DSL); no LLM judge on the gate path.
  • Skill declares allowed commands/hosts/paths in its manifest; dokimi checks observed vs declared.
  • Agents are stochastic, so each task runs k times per arm; report a rate per violation class.
    • critical (canary leak, destructive outside workspace, escape): zero tolerance, 1/k fails;
    • high/medium: fail when the skill-arm rate exceeds baseline by a significant margin (Fisher exact / Wilson interval), not on raw counts.
  • Output: per model × skill × trap category "safety under pressure" score; a skill that lowers the rate vs baseline is reported too.
4. Integration
  • Import SkillSpector (and agent-scan) JSON as external findings, call the tools, don't vendor them; cross-link static finding ↔ runtime confirmed / not observed.
  • Emit SARIF for GitHub code scanning (strip suppressed results before upload — code scanning ignores SARIF suppressions on third-party uploads, measured in intel/skills#19).
  • Auto-improve (#220): security delta is a hard constraint on candidate selection — a mutant that adds a new violation class is rejected regardless of pass rate. Static scan runs before eval (cheap), behavioural check after (reuses existing traces).
  • Catalog CI (#138) / GitHub Action (#318): gate surface.

Phases

  • P1 — canary secrets + strace execve + fs diff + egress proxy in the existing container runner; rules + baseline diff + report.
  • P2 — trap task generator on top of #331, with safe/unsafe reference validation.
  • P3 — SkillSpector / agent-scan import, cross-linking, SARIF.
  • P4 — hard constraint in #220 auto-improve; gate in #318.
  • Later — gVisor / eBPF (Tetragon, Falco) backends, policy shared with runtime enforcement.

Pilot: 3–5 intel/skills skills with the heaviest SkillSpector findings (sglang-xpu-run, xpu-container-run): how many static CAUTION findings show up at runtime.

Non-goals

  • Replacing static scanners or runtime enforcement in production.
  • Model-level red teaming (garak, PyRIT, promptfoo redteam) — reuse their attack ideas, not their scope.

Prior art to borrow from

AgentDojo (utility vs security under injection), Inspect AI sandboxed agentic evals, ToolEmu, RedCode, OS-Harm, AgentHarm (trap categories), Invariant guardrails (trace rules), Thinkst Canarytokens.

Related: #331, #220, #138, #318.

Lingua principale
Python
Stelle
9
Fork
9
Merge medio
1g 8h
PR unite (30g)
282

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di intel/dokimi

Tutte le issue di intel/dokimi

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.