Skills Define skills in Markdown.
security-review
api-design-review
architecture-review
dependency-review
test-coverage
auth-hardening
performance-guardrails
error-handling
Run before you push Compose them into agents.
$ warden
Every pull request Compose them into agents that review every change.
warden bot commented now
SQL injection via unsanitized input

User input is interpolated directly into a SQL query. Use parameterized queries to prevent SQL injection attacks.

Suggested fix: Use parameterized query

Suggested change
- db.query(`SELECT * FROM users WHERE id = ${id}`)
+ db.query("SELECT * FROM users WHERE id = $1", [id])

Your Code Is Under New Management

Define skills in Markdown. Compose them into agents that review every change.

Every Pull Request

Open a PR and Warden reviews it automatically. Findings appear as suggested changes you can apply with one click.

warden bot commented now
SQL injection via unsanitized input

User input is interpolated directly into a SQL query. Use parameterized queries to prevent SQL injection attacks.

Suggested fix: Use parameterized query

Suggested change
db.query(`SELECT * FROM users WHERE id = ${id}`)
+ db.query("SELECT * FROM users WHERE id = $1", [id])

Warden ensures issues missed locally are still caught during review.

Its Just Skills

The PR feedback above comes from skills. Warden ships with a baseline security-review skill. It is a first pass, not a complete security audit, and it is still just a SKILL.md file telling Warden what to look for.

built-in security-review/SKILL.md
---
name: security-review
description: Finds exploitable application security vulnerabilities in code changes.
allowed-tools: Read Grep Glob
---

You are a senior application security reviewer finding real, exploitable
vulnerabilities in code changes for Warden's baseline security skill.

## Finding Requirements
- Report only when you can show attacker-controlled input,
  the vulnerable sink or missing guard, the security boundary,
  and concrete impact.
- Treat pattern matches as leads. A dangerous API is not a
  vulnerability unless untrusted data can reach it.
- Prefer no finding over speculative hardening advice.

Use it by name. No local skill file, build step, schema, or SDK required.

Real skills can include detailed reference material, code examples, style guides, architectural constraints, or anything else you'd put in a design doc. The prompt is the skill.

Install Warden

Install the CLI globally.

$ npm install -g @sentry/warden

Wire It In

Scaffold your project with config and GitHub workflow.

$ warden init

Created warden.toml
Created .github/workflows/warden.yml

Next steps:
  1. Add a skill: warden add security-review
  2. export WARDEN_ANTHROPIC_API_KEY=sk-ant-...
  3. Add WARDEN_ANTHROPIC_API_KEY to repository secrets
     https://github.com/your-org/your-repo/settings/secrets/actions
  4. Commit and open a PR to test

Load Skills

Start with the baseline security check. Add custom or remote skills when your codebase needs deeper coverage.

$ warden add security-review

Create your own skills or find ones driven by the community at skills.sh.

Run Before You Push

Catch issues before you push. Multiple skills run together, each covering its own concern.

warden
$ warden

Analyzing changes from origin/main to HEAD...

FILES  4 files · 6 chunks
  ~ src/api/users.ts (2 chunks)
  ~ src/db/queries.ts (2 chunks)
  + src/auth/session.ts (1 chunk)
  ~ src/middleware/cors.ts (1 chunk)

┌─ security-review ──────────────────────────────────────── 6.1s ─┐
│ 2 findings:  1 high   1 medium                                │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  SQL injection via unsanitized input                           │
│   src/db/queries.ts:42                                          │
│   42 │ db.query(`SELECT * FROM users WHERE id = ${id}`)         │
│                                                                 │
│   User input is interpolated directly into a SQL query.         │
│   Use parameterized queries instead.                            │
│                                                                 │
│  Hardcoded JWT secret                                          │
│   src/auth/session.ts:8                                         │
│    8 │ const SECRET = "sk_live_a1b2c3d4e5f6"                    │
│                                                                 │
│   Secrets should be loaded from environment variables,          │
│   not committed to source.                                      │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

┌─ api-design-review ────────────────────────────────────── 4.3s ─┐
│ 1 finding:  1 low                                              │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Missing pagination on list endpoint                           │
│   src/api/users.ts:15                                           │
│   15 │ app.get("/users", async (req, res) => {                  │
│                                                                 │
│   Unbounded list endpoints can return excessive data.           │
│   Add limit/offset or cursor-based pagination.                  │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

SUMMARY
3 findings:  1 high   1 medium   1 low
Analysis completed in 6.1s

Keep Going