Repository navigation
feat(evals): Add security-review vs wrdn-* coverage matrix - #568
sentry-junior[bot] wants to merge 11 commits into
Conversation
Run each wrdn-authz scenario under builtin security-review and under wrdn-authz loaded from a pinned getsentry/warden-skills ref, so the results show which bugs only the wrdn skill catches. Seed four scenarios from real getsentry/sentry PR findings that only wrdn-authz posted, and document how the matrix and the vulnerability corpus fit together. Co-Authored-By: David Cramer <23610+dcramer@users.noreply.github.com>
… skills Add scenario categories for wrdn-code-execution, wrdn-data-exfil, and wrdn-dos-review, each run under the skill and under security-review. Bug fixtures come from pre-fix parents of real getsentry/sentry fixes and corpus entries; clean fixtures use the fixed state of the same file to count false positives. Print a per-skill summary after the matrix runs, led by the number of bugs only the wrdn skill caught. Co-Authored-By: David Cramer <23610+dcramer@users.noreply.github.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Replace the vitest matrix in packages/evals and its vendored sentry fixtures with packages/security-evals. Skills now scan corpus and case targets inside a full getsentry/sentry worktree at the pinned SHA, so they can trace callers and permission code the way they do in prod. - one scenario per corpus entry plus 15 hand-picked cases (10 bugs, 5 clean) that record repo, ref, and targets - one Warden pass per SHA with every selected skill on the same context; findings in target files are scored by the corpus rule - per-lane recall, unique catches, misses by security-review, clean flags, cost, and a diffable results JSON - committed security-review baseline from the two published production-config corpus runs - runs only via pnpm evals:security or the manual Security Evals workflow, never from pnpm evals or the PR Evals workflow Co-Authored-By: David Cramer <23610+dcramer@users.noreply.github.com>
The first live run lost the whole wrdn-authz lane: every case cloned getsentry/warden-skills on its own and the clone failed, so the lane recorded nothing. Resolve the pinned ref once at setup instead. - --skills-repo (WARDEN_SECURITY_EVALS_SKILLS_REPO) points at a local clone; the suite makes one worktree at the pinned SHA and loads wrdn-* skills from it by path - a missing clone or a skill that fails to load stops collection once, before any pass, so nothing is scored as a miss - the Security Evals workflow checks out warden-skills at the pin; a unit test keeps the workflow and options.ts pins in sync - git calls drop Roach's proxy variables, and lazy fetch is only disabled for the presence check, so worktrees of blobless clones can fetch their blobs
|
Semgrep found 1 🟠 High severity issue identified in your code: Risk: Affected versions of zod are vulnerable to Allocation of Resources Without Limits or Throttling. Zod parses every element of an array, set or map schema and records one validation issue per invalid element, with no cap or early stop. Upper size bounds ( Fix: Upgrade this library to at least version 4.6.6 at warden/pnpm-lock.yaml:6596. Reference(s): GHSA-mrhx-c7xc-m3w5, CVE-2023-54404 |
Add `pnpm evals:security:add <PR or commit URL> --skill <skill>`, which writes a bug case at the fix's parent and its clean twin at the fix, with targets inferred from the non-test .py/.ts files the fix modified. Add a suite validator to the unit tests: schema, unique ids, no corpus overlap, known skill directory, no TODO summary, a clean twin or noClean reason, and baseline entries that still exist at the same ref. Each wrdn-* lane now gets one verdict (earns-keep, no-unique-catches, insufficient-evidence) from VERDICT_RULES. Failed passes, chunks, and judge calls count as errors, never misses, and block the verdict. Baseline lanes record provenance (model, effort, warden version, skill ref) and are dropped with a warning when it differs from the run. The old imported benchmark lane could never match, so the baseline starts empty; baseline:update folds in a clean run. Replace --sentry-repo with repeatable --repo owner/name=<path>, keeping the old flag as an alias. Co-Authored-By: David Cramer <23610+dcramer@users.noreply.github.com>
Tilde does not expand after = in a plain argument. Co-Authored-By: David Cramer <23610+dcramer@users.noreply.github.com>
Fix commit getsentry/sentry@d714026543 (contributor could demote an org admin's inherited team role). Brings wrdn-authz to 5 bug cases. Co-Authored-By: David Cramer <23610+dcramer@users.noreply.github.com>
Fix commits in getsentry/sentry: - a00270ad6d: unbounded RE2 compile cost for logs regex filters - b61768dc55: unbounded commits list processed under the release lock - 1e21009cb0: full=true issue events page serializes 100 full events Brings wrdn-dos-review to 6 bug cases, each with a clean twin. Co-Authored-By: David Cramer <23610+dcramer@users.noreply.github.com>
Fix commits in getsentry/sentry: - dd85c7170d: f-string SQL in the missing org members query - be42554450: caller-chosen ClickHouse function name in fn_span_count - d84bf17e96: SCIM bearer token rendered in full on the SSO settings page Brings wrdn-data-exfil to 5 bug cases, each with a clean twin. Co-Authored-By: David Cramer <23610+dcramer@users.noreply.github.com>
Fix commits: - getsentry/sentry 58b51b430f: UserSerializer returns other users' secondary emails - getsentry/sentry aedeffac61: activity emails ignore enhanced_privacy - getsentry/sentry 2204fde687: AI suggested fix ignores the org opt-out - getsentry/sentry-python f17dad95f3: ASGI query string sent without send_default_pii - getsentry/sentry-python 5606bb3e58: user attributes on logs and metrics without send_default_pii - getsentry/sentry-python e52c3b117a: LangChain tool calls recorded without include_prompts The sentry-python cases need a second clone, so the manual workflow now prepares both with prepare-clone.sh <owner/name> <dir>. Co-Authored-By: David Cramer <23610+dcramer@users.noreply.github.com>
Fix commits: - getsentry/sentry-wizard 9a4f3c9282: changed file names interpolated into formatter shell commands - getsentry/dotagents 461da846ce: skill source URL and ref passed to git without a -- separator The manual workflow clones both repositories. wrdn-code-execution has 3 bug cases; the README lists why it is still short. Co-Authored-By: David Cramer <23610+dcramer@users.noreply.github.com>
Optional security eval suite: does each
wrdn-*skill catch bugs builtinsecurity-reviewmisses?It runs
security-reviewpluswrdn-authz,wrdn-pii,wrdn-data-exfil,wrdn-code-executionandwrdn-dos-review(warden-skills pinned atdaf01f9) over the same code. Every lane is scored against the same known bugs, and eachwrdn-*lane gets one verdict.What's in it
The suite is a new package,
packages/security-evals. Nothing inpackages/evalsor.github/workflows/evals.ymlchanges, sopnpm evals, therun-evalslabel and the PR Evals workflow never run it.sentry-vulnerability-corpus.json(86), plus 47 cases incases/<skill>/(25 bugs, 22 clean twins). That makes 133 entries in 53 shards. Cases come from real fix commits in getsentry/sentry, getsentry/sentry-python, getsentry/sentry-wizard and getsentry/dotagents. Every entry pins repo, SHA and targets. A hit on a clean case is a false positive.--repo owner/name=<path>, repeatable, with--sentry-repokept as an alias. Each SHA gets onegit worktree add --detach, reused across lanes, entries and repeats. The only network step is a setup-timegit fetchfor a missing SHA. Without a clone, setup stops with an error.--skills-repopoints at a local warden-skills clone. Setup makes one worktree at the pin and loads each skill once. If that fails, the run stops before any pass.Proving a skill
The thresholds are in
VERDICT_RULES(src/verdict.ts) and the README:earns-keep: at least one bug the skill caught in 2 of 3 repeats or more, that security-review caught in none, with both lanes at 3+ repeats.no-unique-catches: no such bug, nothing unsettled, and 5+ owned bug cases with 3+ repeats in both lanes.insufficient-evidence: anything else. That covers any errored entry, too few cases, too few repeats, or a catch that security-review gets only some of the time.The report leads with these verdicts. It never prints a bare "0 caught only by X".
Adding a case
The command writes the bug case at the fix's parent and the clean twin at the fix. Targets come from the non-test
.py/.tsfiles the fix modified. Then fill insummaryand run the free validator,pnpm -C packages/security-evals test, which is part of regular CI. It checks:noCleanreasonAfter that, run
--entries <ids> --repeats 3for real.Baseline
Each lane in
baseline/results.jsonrecords its runtime, model, effort, aux model, judge, warden version and skill ref. If any of that differs from the current run, the lane is dropped with a warning. The baseline starts empty, because the old imported benchmark lane could never match.baseline:update <results.json>folds in a clean run and refuses results that contain errors.Running it
A full pass also needs
--repoclones of getsentry/sentry-python, getsentry/sentry-wizard and getsentry/dotagents (see the README). The workflow prepares all four withscripts/prepare-clone.sh <owner/name> <dir>.Defaults match the production lane: pi,
openrouter/x-ai/grok-4.5at high effort,openrouter/openai/gpt-5.6-lunaat high effort for aux, and maxTurns 100. CI runs it through theworkflow_dispatch-only Security Evals workflow.Not done
insufficient-evidenceuntil it has 5: fixed, attacker-reachable command, template or deserialization bugs are rare in getsentry history, and most "injection" fixes there are workflow YAML or latent hardening.packages/warden'sremote.test.tsfails because the sandbox git hook rejects the test's commit author. This PR doesn't touch that code.via @dcramer.
--
View Session [Sentry]