From appsec-advisor
Checks code changes against company security requirements (or built-in baseline), scoped to the diff, with concrete fix guidance. Advisory by default; opt-in --gate for CI blocking.
How this skill is triggered — by the user, by Claude, or both
Slash command
/appsec-advisor:verify-requirementsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are helping a developer build secure code. This skill checks the change the
You are helping a developer build secure code. This skill checks the change the developer just made against the security requirements that apply to it and gives concrete, code-aware guidance — what is missing or wrong and how to fix it.
This is a dev helper, not a compliance police:
--gate.Follow the steps exactly.
--help — inline help (early exit)If the user's arguments contain --help or -h, do not scan anything.
Print the block below verbatim and exit with status 0.
/appsec-advisor:verify-requirements — Check your change against security requirements.
USAGE
/appsec-advisor:verify-requirements [FLAGS]
Checks only the requirements TRIGGERED by your current diff and tells you what
to fix and how. Uses your company requirements catalog if configured,
otherwise a built-in best-practices baseline — no setup needed.
Advisory by default (always exits 0); pass --gate to fail CI on a regression.
FLAGS
--gate Enforce: exit non-zero when an in-scope requirement
at/above the priority floor FAILs. Without it the
skill always exits 0 (advisory).
--gate-on <fail|partial> What gates: `fail` (default) or `fail`+`partial`.
--priority-floor <p> Lowest priority that may gate: MUST (default),
SHOULD, or MAY.
--base <ref> Diff against <ref> (git diff <ref>...HEAD).
Default: merge-base with the upstream default branch.
--staged Diff staged changes only (git diff --cached) — for
pre-commit hooks.
--requirements <src> Load the requirements YAML from <src> instead of the
configured source; no cache fallback. <src> is an
http(s):// URL or a local file path.
--org-profile <path> Use this org profile for source resolution.
--preset <name> Use a specific preset from the active org profile.
--no-org-profile Ignore packaged/env-pointed org profiles.
--md Also save docs/security/appsec-requirements-change-report.md
--json Also save docs/security/appsec-requirements-change-report.json
--save Both --md and --json
--help, -h Show this help and exit
EXIT CODES
0 advisory mode, or --gate with no gating failures
1 --gate and >=1 gating failure
2 usage / requirements-load / verdict error
See `/appsec-advisor:audit-security-requirements` for the full-repo audit and
`docs/configuration.md` → "Security Requirements Management" for source rules.
After printing, exit. Do not read any files or perform any other action.
Parse arguments after the skill name:
--gate — set gate_mode = true (default false / advisory)--gate-on <fail|partial> — set gate_on (default fail)--priority-floor <MUST|SHOULD|MAY> — set priority_floor (default MUST)--base <ref> — set base_ref--staged — set staged = true (mutually exclusive with --base; if both given, hard-fail)--requirements <src> — set requirements_url_override--org-profile <path> — set org_profile_override--preset <name> — set preset_override--no-org-profile — set no_org_profile = true--md / --json / --save — report-save flagsAny token starting with -- that is not one of the recognized flags above — or
is not the value consumed by --gate-on / --priority-floor / --base /
--requirements / --org-profile / --preset — is a hard error. Do not read
files, fetch, or dispatch. Print to stderr Error: unknown argument '<TOKEN>'
followed by Run /appsec-advisor:verify-requirements --help for details. and
exit with status 2. A flag whose required value is missing counts as unknown.
Resolve the plugin root (same block as the audit skill):
if [ -z "$CLAUDE_PLUGIN_ROOT" ]; then
SKILL_MD_PATH=$(find /root /home /opt -maxdepth 6 \
-path "*/appsec-advisor/skills/verify-requirements/SKILL.md" \
2>/dev/null | head -1)
if [ -n "$SKILL_MD_PATH" ]; then
CLAUDE_PLUGIN_ROOT=$(dirname "$(dirname "$(dirname "$SKILL_MD_PATH")")")
fi
fi
export CLAUDE_PLUGIN_ROOT
if [ -z "$CLAUDE_PLUGIN_ROOT" ] || [ ! -d "$CLAUDE_PLUGIN_ROOT" ]; then
echo "Error: CLAUDE_PLUGIN_ROOT could not be resolved — install appsec-advisor or set the variable manually." >&2
exit 2
fi
OUTPUT_DIR="${PWD}/docs/security"
mkdir -p "$OUTPUT_DIR"
Resolve the org profile, then the requirements source, then fetch through the
shared fail-closed gate — identical contract to audit-security-requirements
Step 1b (explicit --requirements is fail-closed with no cache fallback;
otherwise require a usable org-profile / legacy source or a populated cache):
ORG_ARGS=()
[ -n "$ORG_PROFILE_OVERRIDE" ] && ORG_ARGS+=(--org-profile "$ORG_PROFILE_OVERRIDE")
[ -n "$PRESET_OVERRIDE" ] && ORG_ARGS+=(--preset "$PRESET_OVERRIDE")
[ "$NO_ORG_PROFILE" = "true" ] && ORG_ARGS+=(--no-org-profile)
python3 "$CLAUDE_PLUGIN_ROOT/scripts/resolve_org_profile.py" \
--output-dir "$OUTPUT_DIR" --emit-file "${ORG_ARGS[@]}" >/dev/null || exit $?
FETCH_ARGS=(--caller verify-requirements --output-dir "$OUTPUT_DIR" --plugin-root "$CLAUDE_PLUGIN_ROOT" \
--fallback-baseline "$CLAUDE_PLUGIN_ROOT/data/appsec-bestpractices-baseline.yaml")
if [ -n "$REQUIREMENTS_URL_OVERRIDE" ]; then
# Explicit company source: fail-closed, no baseline fallback — if you name a
# source it must load (a typo/down URL should not silently fall back).
FETCH_ARGS+=(--requirements "$REQUIREMENTS_URL_OVERRIDE")
else
# Zero-config path: try the org-profile / cached company source; if none is
# available, degrade to the bundled best-practices baseline instead of
# aborting. This is what makes the helper "just work" with no setup.
FETCH_ARGS+=(--require)
fi
python3 "$CLAUDE_PLUGIN_ROOT/scripts/fetch_requirements.py" "${FETCH_ARGS[@]}"
REQ_FETCH_EXIT=$?
if [ "$REQ_FETCH_EXIT" -ne 0 ]; then
# Only happens when an EXPLICIT --requirements source was named and could not
# load. The zero-config path never lands here (it has the baseline fallback).
echo "✗ The requirements source you named could not be loaded (exit $REQ_FETCH_EXIT)." >&2
exit 2
fi
$OUTPUT_DIR/.requirements.yaml is now the catalog — either your company
requirements (when configured) or the bundled best-practices baseline. Its
top-level source: field records which (the requirement-id scheme is whatever
the catalog defines — no fixed prefix is assumed), so the output can be honest
about what your change was checked against.
DIFF_ARGS=(--repo-root "$PWD" --output-dir "$OUTPUT_DIR")
[ -n "$BASE_REF" ] && DIFF_ARGS+=(--base "$BASE_REF")
[ "$STAGED" = "true" ] && DIFF_ARGS+=(--staged)
CHANGED_COUNT=$(python3 "$CLAUDE_PLUGIN_ROOT/scripts/build_verify_diff.py" "${DIFF_ARGS[@]}")
DIFF_EXIT=$?
if [ "$DIFF_EXIT" -ne 0 ]; then
echo "✗ Could not compute the diff (exit $DIFF_EXIT)." >&2
exit 2
fi
If CHANGED_COUNT is 0, print No changes to verify. and exit 0. Do not
dispatch the subagent — an empty diff costs nothing.
Use the Task tool to launch the appsec-reviewer subagent. Pass
inputs in Group A → B → C order (stable → scalars → volatile paths):
REPO_ROOT=<PWD>
OUTPUT_DIR=<OUTPUT_DIR>
PRIORITY_FLOOR=<priority_floor>
MODEL_ID=sonnet
DIFF_FILE=<OUTPUT_DIR>/.verify-diff.json
REQUIREMENTS_YAML=<OUTPUT_DIR>/.requirements.yaml
STEERING_MAP=<CLAUDE_PLUGIN_ROOT>/hooks/steering_keywords.json
STEERING_MAP is the shared topic→requirement relevance map (also used by the
security-steering hook) — the verifier's Stage-A reads it instead of inventing
its own keyword table, so guidance and verification stay in lock-step.
The subagent grades the triggered requirements and writes
$OUTPUT_DIR/.requirements-verification.json. It prints its own readable
console summary; do not re-print the findings yourself.
GATE_ARGS=(--verdict "$OUTPUT_DIR/.requirements-verification.json" \
--priority-floor "$PRIORITY_FLOOR" --gate-on "$GATE_ON")
[ "$GATE_MODE" = "true" ] && GATE_ARGS+=(--gate)
python3 "$CLAUDE_PLUGIN_ROOT/scripts/requirements_gate.py" "${GATE_ARGS[@]}"
GATE_EXIT=$?
requirements_gate.py prints the verdict line and is the single authority on
the outcome. Propagate its exit code:
--gate absent) → it always exits 0; the skill exits 0 but the
printed WARN line still tells the team what would block.exit "$GATE_EXIT"
If --md / --json / --save was set, render the report under
docs/security/appsec-requirements-change-report.{md,json} from
.requirements-verification.json, reusing the audit-security-requirements
report format (open + gating requirements only). This is presentation only; it
must not change the exit code computed in Step 5.
Note: this skill always has something to check against. With a company catalog
configured (explicit --requirements, org-profile source, legacy config, or
plugin cache) it uses that; otherwise it falls back to the bundled
best-practices baseline (data/appsec-bestpractices-baseline.yaml). It only
aborts (Step 2, exit 2) when you explicitly named a --requirements source
that could not be loaded — a deliberately-named source must work.
npx claudepluginhub matthiasrohr/appsec-advisorRuns tiered threat-model security review on diffs, with universal code-security checks and AI-artifact checks for skills/agents/prompts/MCP servers. Gates handoff on critical/high findings with waiver option.
Performs structured code reviews checking requirements, quality, and security standards after changes or before merge. Uses git diffs, context snapshots, and blast radius for scope.
Audits a repository against a security requirements catalog, verifying which requirements are implemented. Supports custom YAML catalogs, color-coded output, optional reports, and CI gating via a structured verdict file.