Skip to content

Security: RightNow-AI/autoevolve

SECURITY.md

Security policy

Reporting a vulnerability

Report privately through GitHub Security Advisories on this repository: https://github.com/RightNow-AI/autoevolve/security/advisories/new

Do not open a public issue for a vulnerability. Expect an acknowledgement within a few days.

What this project's threat model actually covers

autoevolve executes generated code by design, so the boundaries matter more than usual. Be precise about what is and is not defended.

Defended. Candidate and evaluator code runs only in a subprocess with a fresh temporary working directory, a wall clock kill, an environment scrubbed to an allowlist so secrets cannot reach it, and Python level networking blocked before any evaluator module loads. Memory and CPU limits apply on POSIX. Every run requires a budget bound. Nothing derived from a public GitHub issue executes before a maintainer applies the evolve:approved label, and the label applier must have write access.

Verdict integrity. The result the engine records is decided by the evaluator and is unreachable from candidate code. File descriptor 1 carries the verdict, and it is the null device for the whole time evaluator and candidate code runs, so nothing they write can appear on it, including writes through sys.__stdout__ or a raw os.write. The descriptor is restored only after the payload is decided, written with a raw write that ignores tampering with sys.stdout, and the process leaves through os._exit so no atexit handler can append a second verdict. The parent reads the first verdict line and rejects a nonzero exit code. This is the property every measured number in this project depends on, so it carries regression tests for both forging after and forging before the real verdict. Reports of a way to influence a recorded verdict are the highest severity issue this project can receive.

The environment allowlist additionally passes AUTOEVOLVE_ prefixed workload configuration, because campaign cells select their workload through it. AUTOEVOLVE_HOME is excluded, since the run database path would let a candidate edit its own scores, as are endpoint, model, and credential shaped names.

Not defended, by design. The sandbox is a containment boundary for accidental damage and runaway resource use, not a hostile code jail. A native extension making raw syscalls can bypass the Python level network block. On Windows the wall clock timeout is the enforced bound because resource limits are not available. Do not run untrusted adversarial code and rely on this alone. For hostile input, run autoevolve inside a container or a virtual machine.

Candidate code also shares an interpreter with the evaluator that judges it. The verdict channel is protected, but an evaluator that trusts an object a candidate hands back can still be misled about its own computation, for example by a container subclass whose __getitem__ is candidate code and answers differently on each read. Evaluator authors must recompute every quantity that reaches a metric and normalize candidate output into immutable primitives in a single pass before checking anything. docs/CONTRACT.md section 4a and docs/FRONTIER.md section 5 state the rules.

These limits are documented in docs/CONTRACT.md section 4 rather than hidden, because a sandbox people misjudge is worse than one they understand.

The agentic operator runs code, and that is deliberate

The agentic operator spawns a headless Claude Code or Codex session to produce one mutation. That session can run commands. It has to: on a search problem an agent that cannot execute anything has nothing to reason from, and a probe on Golomb order 29 spent every turn having Bash calls denied and never made an edit.

Two things follow, and both matter.

The agent cannot certify its own work. It is engine side, like the model operators, and it returns files. The engine re-runs the whole evaluation cascade in the sandbox on those files, so the agent's own measurements are a note in the record and never a score. Giving it execution does not widen any path to a forged verdict.

What execution does widen is prompt injection. A campaign pack's goal and spec text reach the agent's prompt, so with a shell available, text written by whoever authored that pack becomes text an agent may act on. Run packs you trust. AUTOEVOLVE_AGENTIC_TOOLS narrows the tool list, for example to Read,Edit,Write, and the operator still works, it just gets much weaker at anything that needs measurement.

Scope

In scope: sandbox escapes reachable from ordinary evaluator or candidate code, the GitHub issue mode consent gate, secret leakage into the database, events, reports, or dashboards, and anything that lets a run exceed its declared budget.

Out of scope: resource exhaustion by code you wrote and ran yourself, and the native syscall bypass documented above.

There aren't any published security advisories