appsec-advisor includes prompt-time guidance, an interactive change review, and a CI review command.
All tools use the same active standard: a configured company requirements catalog, or the bundled best-practices baseline when no catalog is configured.
- Quick start
- Tool overview
- Setup and prerequisites
- Security Coach hook
- appsec-reviewer agent
- verify-requirements skill
- appsec-reviewer-cli
- Requirements source
- Diff behavior
- Outputs and gates
- CI security notes
- Troubleshooting
- Flag reference
Use the hook while writing code:
APPSEC_COACH=1 claude --plugin-dir /path/to/appsec-advisorReview the change you just made from a Claude Code session:
/appsec-advisor:verify-requirementsReview staged changes before commit:
/appsec-advisor:verify-requirements --stagedWrite an advisory CI report:
export CLAUDE_PLUGIN_ROOT="/path/to/appsec-advisor"
export PATH="$CLAUDE_PLUGIN_ROOT/scripts:$PATH"
appsec-reviewer-cli review --diff origin/main --output security-review.mdMake CI fail on blocking findings:
appsec-reviewer-cli review --diff origin/main --output security-review.md --fail-on must| Tool | Type | What it does | When to use it |
|---|---|---|---|
| Security Coach hook | Hook | Adds relevant security guidance to Claude's context while you write. It advises before code exists; it does not review finished code or block prompts. | You want automatic reminders as you write security-sensitive code. |
| appsec-reviewer | Agent | Reads a change, determines which security expectations apply, and grades the post-change code with evidence and a suggested fix. It produces findings only. | You want to embed the reviewer into your own Claude Code or Agent SDK workflow. |
| verify-requirements | Skill | Interactive wrapper for Claude Code sessions. It resolves the requirements source, builds the diff, dispatches appsec-reviewer, and can enforce the result with --gate. |
You want to review the change you just made in your session. |
| appsec-reviewer-cli | CLI | CI wrapper around the same review. It runs headlessly, writes a Markdown report, and can fail the build with --fail-on. |
You want the review to run automatically in CI on every change. |
The Security Coach acts before code is written. The skill and CLI use appsec-reviewer to inspect a completed change.
Interactive use needs Claude Code with the plugin loaded:
claude --plugin-dir /path/to/appsec-advisorCLI use needs:
appsec-reviewer-clionPATH, usually by adding the plugin'sscripts/directory.CLAUDE_PLUGIN_ROOTpointing at the plugin root when the wrapper cannot resolve it from its own path.- Claude Code CLI on
PATH. python3andgitonPATH.ANTHROPIC_API_KEYor Claude Code subscription authentication.- A fetched base ref when using
--diffin CI, such asorigin/main.
Minimal shell setup:
export CLAUDE_PLUGIN_ROOT="/path/to/appsec-advisor"
export PATH="$CLAUDE_PLUGIN_ROOT/scripts:$PATH"Set CLAUDE_PLUGIN_ROOT to the plugin's location in the CI runner.
The Security Coach checks prompts for topics such as authentication, injection, cryptography, secrets, IaC, and LLM security. On a match, it adds relevant guidance and requirements before Claude answers.
Enable per session:
APPSEC_COACH=1 claude --plugin-dir /path/to/appsec-advisorEnable for all team members via org profile:
# org-profile.yaml
security_coach:
enabled_by_default: trueThe org profile enables the hook for the team; APPSEC_COACH=1 enables it for one session.
Example prompt:
implement the OAuth refresh-token endpoint
Example injected context:
[auth] short-lived tokens with rotation on refresh; validate
issuer/audience/signature/expiry on every JWT check; MFA for admin paths.
Applicable requirements:
- BP-AUTH-SESSION-COOKIE (MUST): Issue session cookies with HttpOnly, Secure...
Operational notes:
- The hook does not call the reviewer agent.
- The hook does not block prompts.
- Matching and telemetry are documented in security-coach-skill.md.
appsec-reviewer is the core reviewer. It reads a diff, determines which requirements or best-practice rules are in scope, and grades the post-change code.
Each finding includes:
- status:
PASS,PARTIAL,FAIL,UNVERIFIABLE, orNOT_APPLICABLE - rule or requirement ID
file:lineevidence where available- code-aware fix
- effort estimate
Direct use:
Use the appsec-reviewer agent to review my staged changes.
Output (in its configured output directory):
<output-dir>/.requirements-verification.json
The agent writes findings. The skill and CLI apply the gate when requested.
The skill is the interactive entry point for developers using Claude Code.
Run:
/appsec-advisor:verify-requirementsBy default, the skill:
- resolves the active requirements source
- builds a three-dot diff against the upstream default branch
- dispatches
appsec-reviewer - writes
.requirements-verification.jsonto the application's private directory (<data dir>/appsec-advisor/assessments/<repo-name>-<hash8>) outside the repository, or to--output <dir> - exits
0unless--gateis set and the gate fails
Common runs:
# Review staged changes.
/appsec-advisor:verify-requirements --staged
# Compare against a specific base ref.
/appsec-advisor:verify-requirements --base origin/main
# Enforce locally or in a scripted Claude Code run.
/appsec-advisor:verify-requirements --gate
# Enforce and also block PARTIAL findings.
/appsec-advisor:verify-requirements --gate --gate-on partialSaved reports:
/appsec-advisor:verify-requirements --save--save writes:
appsec-requirements-change-report.mdappsec-requirements-change-report.json
in the same directory as the verdict.
The CLI runs the same review in CI and other automation.
Run:
appsec-reviewer-cli review --diff origin/main --output security-review.mdBy default, the CLI:
- invokes
/appsec-advisor:verify-requirementsheadlessly - writes
.requirements-verification.jsonto the application's private directory (<data dir>/appsec-advisor/assessments/<repo-name>-<hash8>) - renders the requested Markdown report
- exits
0unless--fail-onis set and the gate fails
Before using this in CI, read CI security notes. Pull-request code is untrusted input, and the wrapper bypasses interactive permission prompts.
GitLab CI:
security_review:
stage: test
script:
- export CLAUDE_PLUGIN_ROOT="$CI_PROJECT_DIR/appsec-advisor"
- export PATH="$CLAUDE_PLUGIN_ROOT/scripts:$PATH"
- git fetch origin main
- appsec-reviewer-cli review --diff origin/main --output security-review.md
artifacts:
paths:
- security-review.mdGitHub Actions:
permissions:
contents: read
jobs:
security_review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@<commit-sha>
with:
fetch-depth: 0
- name: Security review
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
CLAUDE_PLUGIN_ROOT: ${{ github.workspace }}/appsec-advisor
BASE_REF: ${{ github.base_ref }}
run: |
export PATH="$CLAUDE_PLUGIN_ROOT/scripts:$PATH"
git fetch origin "$BASE_REF"
appsec-reviewer-cli review --diff "origin/$BASE_REF" --output security-review.md
- uses: actions/upload-artifact@<commit-sha>
with:
name: security-review
path: security-review.mdReport excerpt:
# Security Review — change verification
| Field | Value |
|-------|-------|
| Base ref | `origin/main` |
| Checked against | built-in best-practices baseline |
| In-scope requirements | 2 of 6 candidates |
| Result | 🔴 1 fail · 🟡 1 partial · 🟢 0 pass · ⚪ 0 unverifiable |
## What to fix
### 🔴 FAIL · MUST · BP-INJ-SQL-PARAM
Raw request input reaches `sequelize.query()` at `src/routes/search.ts:23`.
**Fix:** Bind the term via replacements.The active requirements source is selected in this order:
- Explicit
--requirements <src>for the current run. - Configured organization requirements catalog.
- Bundled best-practices baseline.
<src> can be an http(s):// URL or a local file path. A path without an http(s) scheme is read relative to the current working directory. If an explicit source cannot be loaded, the run exits with an error instead of silently falling back.
Examples:
/appsec-advisor:verify-requirements --requirements ./security/requirements.yaml
appsec-reviewer-cli review --diff origin/main --output security-review.md --requirements ./security/requirements.yamlMinimal catalog:
source: acme-appsec
categories:
- id: ACME-AUTH
title: Authentication
requirements:
- id: ACME-AUTH-01
priority: MUST
text: Passwords must be stored with Argon2id or bcrypt.
url: https://appsec.int.example.com/authRequirement IDs are organization-defined. No fixed prefix is required. For org-wide defaults, use org-profiles.md.
verify-requirements --base <ref> and appsec-reviewer-cli review --diff <ref> both review the changes on HEAD since the merge-base with <ref>:
git diff <ref>...HEAD
Default interactive behavior uses the upstream default branch when it can be resolved, then common fallbacks such as origin/main or origin/master.
--stagedreviews onlygit diff --cached.--stagedand--baseare mutually exclusive.- CI jobs must fetch the base ref before running the CLI.
- An empty diff is valid and exits
0without dispatching the reviewer.
Outputs:
- Hook: no review artifact; optional hook telemetry as described in security-coach-skill.md.
- Agent:
.requirements-verification.jsonin its configured output directory. - Skill:
.requirements-verification.jsonand optional saved reports in the application's private directory, or in--output <dir>. - CLI: requested Markdown report and
.requirements-verification.jsonin the application's private directory.
Exit codes:
0: review completed; advisory mode or no gate-violating finding.1: gate failed.2: usage, requirements-load, diff-build, or verdict error.
Gate behavior:
| Front-end | Advisory by default | Blocking flag | What blocks |
|---|---|---|---|
| Skill | yes | --gate |
in-scope FAIL findings at or above --priority-floor |
| Skill | yes | --gate --gate-on partial |
in-scope FAIL or PARTIAL findings at or above --priority-floor |
| CLI | yes | --fail-on must |
in-scope FAIL findings at or above --priority-floor |
| CLI | yes | --fail-on partial |
in-scope FAIL or PARTIAL findings at or above --priority-floor |
--priority-floor defaults to MUST. Lower it to SHOULD or MAY only when the team intentionally wants lower-priority findings to block.
Pre-push example:
# .git/hooks/pre-push (chmod +x)
#!/usr/bin/env bash
appsec-reviewer-cli review --diff origin/main --output /tmp/security-review.md --fail-on mustPull-request code is untrusted input. A CI job that runs the reviewer may expose an API key to attacker-controlled repository content.
The CLI invokes Claude Code in headless mode and bypasses interactive permission prompts so it can run unattended. Use it only where that is an acceptable trust boundary.
Use the CI reviewer with:
- private repositories
- trusted same-repository pull requests
- ephemeral runners
- dedicated, low-limit CI API keys
Do not use it with:
- public fork pull requests with secrets
pull_request_targetworkflows that bypass secret withholding- shared runners that retain sensitive state
- long-lived developer credentials in the CI environment
See SECURITY.md.
appsec-reviewer-cli: CLAUDE_PLUGIN_ROOT could not be resolved: setCLAUDE_PLUGIN_ROOTto the plugin root and add$CLAUDE_PLUGIN_ROOT/scriptstoPATH.Claude Code CLI not found: install Claude Code and make sureclaudeis onPATH.no verdict produced: the headless Claude run did not complete or did not write.requirements-verification.jsonto the application's private directory. Re-run the equivalent/appsec-advisor:verify-requirements --base <ref>interactively to see the underlying error.build-verify-diff: git diff failed: fetch the base ref and verify thatgit diff <ref>...HEADworks locally.- Explicit requirements source cannot be loaded: fix the URL/path or remove
--requirements. Explicit sources fail closed; only the zero-config path falls back to the bundled best-practices baseline. No changes to verify.: the resolved diff is empty. Use--stagedfor staged-only checks or pass a different--base/--diffref.
| Flag | Meaning |
|---|---|
--base <ref> |
Review git diff <ref>...HEAD; default is the merge-base with the upstream default branch. |
--staged |
Review staged changes only (git diff --cached); mutually exclusive with --base. |
--gate |
Exit non-zero on a gating failure; default is advisory. |
--gate-on <fail|partial> |
Select what counts as gating; default is fail. |
--priority-floor <MUST|SHOULD|MAY> |
Lowest priority allowed to gate; default is MUST. |
--requirements <src> |
Use an http(s):// URL or local file path; unreadable explicit sources abort. |
--org-profile <path> |
Use this org profile for source resolution. |
--preset <name> |
Use a preset from the active org profile. |
--no-org-profile |
Ignore packaged or environment-pointed org profiles. |
--md |
Also save appsec-requirements-change-report.md. |
--json |
Also save appsec-requirements-change-report.json. |
--save |
Save both Markdown and JSON reports. |
--output <dir> |
Write reports and the verdict to <dir> instead of the application's private directory outside the repository. |
| Flag | Meaning |
|---|---|
--diff <ref> |
Required base ref for git diff <ref>...HEAD. |
--output <file> |
Markdown report path; default is security-review.md. |
--requirements <src> |
Use an http(s):// URL or local file path; unreadable explicit sources abort. |
--fail-on <must|partial> |
Make CI fail; omit for advisory mode. must gates FAIL findings, partial gates FAIL and PARTIAL findings. |
--priority-floor <MUST|SHOULD|MAY> |
Lowest priority allowed to gate; default is MUST. |