Skip to content

Latest commit

 

History

2,562 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

appsec-analyzer

Version Status Python Codecov License SARIF

Note

Alpha. Early version, actively developed. Feedback from real-world projects welcome.

AppSec Analyzer reviews application security from source code. It maps components, data flows, and trust boundaries, checks the security controls it finds, and reports findings with code references and suggested fixes. It works on one Git repository or directory, or on several that form one system.

It does not scan dependencies for known CVEs, search comprehensively for secrets, or test the running application. Review deployment controls and business assumptions yourself.

In Claude Code, use it as the plugin AppSec Advisor.

Quick start · Reports · Data use · Install · Commands · Options · Cost limits · Abuse cases · Documentation

Quick start

This example assesses the intentionally vulnerable OWASP Juice Shop. You need Python 3.10+, Git, pipx, and a set-up model provider.

  1. Install Analyzer from GitHub (preview):

    pipx install git+https://github.com/appsec-foundry/appsec-analyzer.git
  2. Run a full assessment. Analyzer creates the output directory, readable only by you, and writes the report to security-assessment.md there:

    appsec-analyzer assess --repo https://github.com/juice-shop/juice-shop.git \
      --output ~/assessments/juice-shop

    For your own code, pass its Git URL or local path to --repo.

    While assess runs, the console shows the run settings, the scope, and the progress of each phase with elapsed and remaining time:

    Console output of appsec-analyzer assess: run settings, scope, and a progress table per phase

  3. Review the findings with your coding agent. Discuss the results and plan fixes in Claude Code or Codex:

    appsec-analyzer review ~/assessments/juice-shop

To update Analyzer later, run appsec-analyzer update. See Install for details.

Note

With API billing, the Juice Shop assessment costs about USD 15 and takes about 40 minutes. Analyzer asks before it exceeds the default limit of USD 20 for standard depth. Costs of the other depths are listed under Assessment options.

Reports and exports

Each assessment writes security-assessment.md for reading and security-assessment.yaml for further processing. The report includes diagrams of the analyzed system. The two details below come from an assessment of OWASP Juice Shop; click a diagram to open it in full.

The run-statistics appendix compares the recorded contributions of survey, verification, evidence review, and abuse cases with their attributable model costs. Additional source locations are not necessarily new weaknesses; semantic novelty or missing comparison data is shown as unknown. This overview makes no additional model calls.

Example: Thorough assessment of OWASP Juice Shop. The examples repository also has the quick and standard assessments of the same commit, their data files, and all diagrams.

The runtime architecture with its data flows and attack paths:

Detail of the runtime architecture and attack paths in the Juice Shop assessment

The build pipeline and the most severe supply-chain attacks on it:

Detail of the build pipeline and supply-chain attack paths in the Juice Shop assessment

Request more formats when you start the assessment, for example assess --repo /path/to/project --sarif --html:

Flag Output
--sarif SARIF 2.1.0 findings for code-scanning tools.
--html HTML report. Requires Pandoc.
--pdf PDF report. Requires Pandoc and WeasyPrint; diagrams may also need Mermaid CLI and Chrome.
--threatdragon OWASP Threat Dragon model.
--pentest-tasks Tasks for follow-up penetration testing.

To convert a finished assessment later, use export.

For findings that a request or other input reaches, the analysis records verification_context in security-assessment.yaml where the source supports it, with source-cited query construction, input processing and filter order, existing controls, prerequisites, and expected observations with control experiments. Missing facts stay explicit. If a survey, investigation or open-review response omits the context, its finding receives an empty variant list and an unresolved reason; this does not mean the finding is untestable. Each route or input variant keeps its own context, including in pentest-task exports. This helps a separate authorized runtime test; Analyzer does not contact the target, and these hypotheses do not establish exploitation or grant permission. Older assessments remain readable without it.

Security and data use

Important

Model-backed commands send source excerpts and context to the selected provider. Check your organization's rules and the provider's data-handling terms before you analyze confidential code.

score and scan-sources send no source to a model. They still need network access when you pass a Git URL.

Analyzed repositories are untrusted input: their content cannot authorize tools or select provider credentials. Reports show HTML from a repository or a model as text, and opening a report requests nothing from other hosts. Keep credentials out of repository files and Git URLs, and treat reports and intermediate files as sensitive. See the security policy.

Install

pipx install git+https://github.com/appsec-foundry/appsec-analyzer.git

pipx puts appsec-analyzer on your PATH in its own virtual environment. The repository must be reachable for your GitHub account. The package is not yet on PyPI.

Update

appsec-analyzer update
  • Reinstalls Analyzer from the source you installed it from, such as GitHub or a local checkout.
  • Shows the installed version, the source, and asks [Y/n]. Enter or y confirms, n stops.
  • Runs pipx upgrade --pip-args=--force-reinstall appsec-analyzer, which you can also run yourself. The extra option reinstalls even if the version number is unchanged, as is usual for GitHub installations.
  • Hides the pipx output and shows it only if the update fails.
  • After the update, shows the newly installed version, in the format of appsec-analyzer --version: a release version, or the commit and its date. (unchanged) means the source had no newer version.
  • Needs an interactive terminal outside CI. No option skips the question.
  • For installations that do not use pipx, it tells you to update the way you installed Analyzer.
  • Organization commands do not have it.

To switch the source, run pipx install --force with the new source.

Version

  • appsec-analyzer --version prints the release version. A build counts as a release when its commit has a tag like v0.2.0. Other builds print the commit and its date.
  • The assessment start message shows the same build version, including in plain terminal output.
  • A modified checkout adds +local changes. A build without Git data prints commit unknown.
  • appsec-analyzer version prints the engine and interface versions as JSON.
Install with pip or from a local checkout

With pip, inside an activated virtual environment:

python -m pip install \
  "git+https://github.com/appsec-foundry/appsec-analyzer.git"

From a local checkout, for example to install local changes:

git clone https://github.com/appsec-foundry/appsec-analyzer.git
cd appsec-analyzer
python3 -m venv .venv
. .venv/bin/activate
python -m pip install .
appsec-analyzer version

If the appsec-analyzer command is not on your PATH, python -m appsec_analyzer starts the same command from the environment where you installed the package.

With pipx:

  • Run pipx install --force . in the checkout. --force replaces an existing installation.
  • pipx installs the checkout as it is, including uncommitted changes, and keeps it as the source.
  • To update, change the checkout, for example with git pull, and run appsec-analyzer update. It reinstalls from the checkout instead of GitHub.
  • To return to the GitHub version, run pipx install --force git+https://github.com/appsec-foundry/appsec-analyzer.git.

Pulling or merging changes in a checkout does not update an installed copy. Before retrying a local fix, compare appsec-analyzer --version with python3 -m appsec_analyzer --version run in that checkout. Reinstall from the checkout if the installed version is older. The update command's version check reads the installation even when you run it inside a checkout.

Local release preparation explains how to build a wheel.

Run from a checkout without installing

Install the runtime dependencies listed in setup.py first (PyYAML, jsonschema, and Jinja2).

cd /path/to/appsec-analyzer
python3 -m appsec_analyzer scan-sources --repo /path/to/project

Replace appsec-analyzer with python3 -m appsec_analyzer in all examples. assess and scan-sources need --repo; pass --repo . for the current directory.

Container

The Dockerfile builds an image that runs one appsec-analyzer command, locally with Docker or as a Job in OpenShift. It contains Claude CLI and HTML export but no PDF export. See Run Analyzer in a container.

Commands

appsec-analyzer --help shows the commands in the same groups as the lists below. appsec-analyzer <command> --help lists the options of each command.

assess and the focused analysis commands make model calls. They send source excerpts to your provider (see Security and data use) and stop at a cost limit. review starts your coding assistant, which uses its own account.

Start here

  • assess: Full security assessment of a repository or a system of repositories.
  • review: Discuss a finished assessment and plan fixes with Claude Code or Codex.

Quick checks without model calls

  • score: Quick security score from 0 to 100.
  • scan-sources: Raw scanner observations without a score. It runs other checks than score.
  • repo-profile: Size, languages, and build manifests of a local directory before an assessment.

Focused analysis with model calls

  • analyze-threats: Answer one security question about the code, a planned design, or a change.
  • authnz-review: Review authentication and authorization only.
  • audit-requirements: Check a repository against a security requirements catalog.

Work with an assessment

  • status, progress, results, stop: Follow, inspect, or stop a running assessment.
  • export: Convert a finished assessment to SARIF, HTML, PDF, and other formats.
  • abuse-cases: List the defined abuse cases, or show one with the result a saved assessment records.

Setup and integration

  • preflight: Check repository access and provider setup before you spend budget.
  • profiles: List and validate scan and model profiles.
  • platform-settings: Security settings of a GitHub or GitLab repository, such as branch protection.
  • distribution: Create the files for your organization's own command, and align its engine pins after an engine update.
  • update: Update a pipx installation of Analyzer after your yes.
  • capabilities: List the available commands and provider qualification as JSON.

assess: full security assessment

assess analyzes one repository, or several repositories as one system, and writes the full assessment report. See Security assessment.

An output directory may already contain recognized Git, assistant, or editor metadata, such as .git, .claude, or .codex. Analyzer leaves it untouched. Other existing files can block a new run to protect your work; see output and continuation.

After an interruption at Management Summary, repeat the command with --resume. If source, context, settings and Analyzer version are unchanged and the saved checkpoint is intact, Analyzer checks its artifacts and continues there without repeating analysis or report preparation. Earlier runs without a checkpoint use the normal replay of accepted steps.

Provider connection failures, server errors and rate limits pause new model calls together. If bounded recovery attempts fail, the run pauses with exit code 3 and retains accepted results, including when an optional check was affected. Check the connection or wait for the provider to recover, then repeat the command with --resume. See connection failures and recovery.

A published report can still have incomplete optional checks. The closing status says so and groups failures by cause, with the affected job and component counts. Use --verbose or the private .run-issues.json file for individual jobs. Before repeating a completed assessment, review its diagnostics and allow for additional model calls; a new output directory keeps the previous report intact.

# Assess a local checkout
appsec-analyzer assess --repo /path/to/project

# Assess a remote repository; Analyzer clones it into a temporary directory
appsec-analyzer assess --repo https://github.com/your-org/your-project.git

# Assess a backend and its web frontend together as one system
appsec-analyzer assess --repo /path/to/backend --repo /path/to/frontend

With --non-interactive, assess requires --repo and an explicit --profile, so a script or CI job never starts on a default provider. See Hosts and models.

# Run in CI with a fixed provider profile and without questions
appsec-analyzer assess --repo /path/to/project \
  --profile claude --non-interactive

How assess finds weaknesses

With scripts and a model, assess splits your system into components, such as the API server and the web frontend. It then runs these steps in order:

Step Reads Produces Done by
1. Scanners Code Unconfirmed hits Scripts only, no model
2. Survey Code, scanner hits Findings Script picks the files, model analyzes them
3. Verification Code, routes, scanner hits, but not the survey's findings Findings and controls Script collects the places, model answers the questions
Evidence review and merge All results so far One list of findings Model reviews the evidence, script merges, model decides unclear merges
4. Abuse cases Merged findings, code New findings, higher severity Script picks the cases, model checks the steps, script records the result

This route shows what each method adds. Any logged-in user can read any order, because the lookup does not check the owner:

app.get('/api/orders/:id', requireLogin, async (req, res) => {
  const order = await Order.findByPk(req.params.id);
  res.json(order);
});
  1. Scanners apply fixed rules without a model. Rule AUTHZ-002 flags this lookup as using a URL parameter without an ownership filter. The hit is unconfirmed, because the check could sit in code the rule cannot see.
  2. Survey: a model reads each component and looks for any weakness, with the six STRIDE threat categories, such as Spoofing and Tampering, as its checklist. It reports weaknesses it can show in the code, not possible threats. It also finds problems no rule covers, such as a password reset without throttling. It does not go route by route, so it often reports only a few examples of a shared weakness.
  3. Verification: a model answers a fixed list of questions at every place they apply. For this route it answers TC-AUTHZ-01: does object access check the owner? A control it finds there contradicts a survey finding. In Juice Shop, the survey reported the problem for PUT /api/BasketItems/:id, and verification also found it for GET and DELETE.
  4. Abuse cases: a model checks one attacker goal step by step. Case AC-T-002 asks whether a normal user can read other users' records and then gain rights through mass assignment. This route is step 1, and the model looks for step 2 in the code. If all steps hold, the case can add a finding or raise the severity of the findings involved.

The evidence review is a separate model job. It checks scanner and survey findings against the source code, and verification findings that no scripted check has confirmed. A script merges findings when its rules decide, such as the same line and the same or a related CWE. A model decides the groups no rule settles. See Survey and verification for details and Assessment options for what runs at each depth.

review: discuss an assessment with your coding agent

review opens a finished assessment in Claude Code or Codex so you can discuss findings and plan fixes. The assistant starts in read-only mode and uses its own account, not the assessment budget. --preview shows what the assistant would receive, without starting it. See Review guide.

# Discuss the findings with the assistant recorded in the assessment
appsec-analyzer review /path/to/assessment

# Use Codex instead
appsec-analyzer review /path/to/assessment --with codex

score: deterministic security score

score gives a local directory or Git URL a score from 0 to 100 and lists findings, coverage, and limits. It sees only what its rules cover and reports undetermined when coverage is too low. It does not replace assess. See Security score.

# Score a local checkout
appsec-analyzer score /path/to/project

# Score a remote repository and print JSON for scripts
appsec-analyzer score https://github.com/your-org/your-project.git --json

scan-sources: raw scanner observations

Spring route and security-rule interpretation has documented coverage and limits. Analysis version 6 keeps unresolved authentication separate from evidenced anonymous access in YAML and reports.

scan-sources lists unverified hits from the source rules (authorization, injection, mobile apps), a per-route authorization check, a Spring mass-assignment check, and the configuration rules. It shows no score and does not replace assess. score runs a different set: it adds architecture rules and leaves out the per-route and mass-assignment checks.

The PHP rules for SQL and command injection report a call only when request input reaches its query or command within the same function or file. They do not follow values through other functions, object properties set elsewhere, included files, or session data.

--assessment-depth only changes the configuration files: quick checks the first 5 files of each type, standard (the default) all of them, and thorough gives the same result as standard. --json prints the complete result, including the scanner list. --output DIR also saves it as scan-result.json.

Configuration files that cannot be parsed, such as Helm templates, are named in the result, because their resource checks do not run.

# Show what the scanners found, without a score
appsec-analyzer scan-sources --repo /path/to/project

repo-profile: size, languages, and layout

repo-profile shows working-tree size, dependency and build-output size, languages by bytes, build manifests, and tracked versus untracked content. It also shows whether manifests belong to one root or several. It reads directory entries only and makes no security judgement.

# Profile the current directory, or print JSON for scripts
appsec-analyzer repo-profile /path/to/project --json

analyze-threats: answer a security question

analyze-threats answers one security question about the current code, a planned design, or a selected change. It needs no prior assessment. See Threat Analyst.

The command reads the files or change you select and uses your requirements and threat model as context. Findings require source evidence. The report lists the documents used.

# Ask about one part of the code
appsec-analyzer analyze-threats \
  "Can a normal user read another tenant's records?" --path src/api

# Use case: before you commit, check whether the staged change breaks
# a requirement or contradicts your threat model
appsec-analyzer analyze-threats \
  "Does this change violate our requirements?" --staged \
  --context requirements.md --context docs/security/threatmodel.md

# Review a GitHub pull request (GitLab: --mr);
# --preview shows the scope without a model call
appsec-analyzer analyze-threats \
  --pr https://github.com/team/app/pull/42 --preview

--design-file, --context, --mr, and --pr take documents or a remote change as input. Documents given with --context add background and do not replace the question or the change under review.

authnz-review: authentication and authorization review

authnz-review checks the routes, login checks, and permission checks of one repository. It needs no prior assessment. See AuthNZ review.

# Review login and permission checks
appsec-analyzer authnz-review --repo /path/to/project

# Save the report and fail a CI job on Critical or High findings
appsec-analyzer authnz-review --repo /path/to/project --save --gate

audit-requirements: requirements audit

audit-requirements checks whether a repository implements each requirement of a local catalog in Analyzer YAML or OSCAL format. The output directory must already exist. See Requirements audit.

# Try the audit with the bundled sample catalog
mkdir /path/to/audit
appsec-analyzer audit-requirements --repo /path/to/project --demo \
  --output /path/to/audit --host claude-cli

# Check your own catalog and write a Markdown report
appsec-analyzer audit-requirements --repo /path/to/project \
  --requirements /path/to/catalog.yaml --output /path/to/audit \
  --host claude-cli --md

Use requirements from a wiki or website

Requirement Harvester reads security requirements from websites and wikis without model calls. It writes them to a YAML file in OSCAL, a standard format for security controls. Analyzer reads this file directly.

# Collect the requirements into the file set in output.catalog of the configuration
requirement-harvester run --config /path/to/harvester.yaml

# Audit a repository against them (model calls)
mkdir /path/to/audit
appsec-analyzer audit-requirements --repo /path/to/project \
  --requirements /path/to/requirements.oscal.yaml \
  --output /path/to/audit --host claude-cli --md

assess, authnz-review, and analyze-threats accept the same file with --requirements. See the catalog limits.

Analyzer does not use all the data the Harvester collects:

  • Reports show a generated ID, not your own ID.
  • Every requirement counts as MUST, so --gate also blocks on a violated SHOULD requirement.
  • Reports do not link to the source page.
  • The model does not see applicability, context, exceptions, or guidance. If a requirement applies only to some systems, say so in its text.

export: other report formats

export writes a finished assessment to other formats. The destination must be a new directory outside any Git checkout. See Reports and exports and export prerequisites and limits.

# Create SARIF for code scanning and HTML for reading
appsec-analyzer export --assessment /path/to/assessment \
  --output /path/to/export --formats sarif html

abuse-cases: list the defined cases

abuse-cases lists the technical and business abuse cases a run in this repository would load, with origin, kind, and title. With an ID it shows that case's definition and what the saved assessment records for it. It is read-only and does not check a case against the code; use analyze-threats --abuse-case <ID> for that.

# List all cases, or show one
appsec-analyzer abuse-cases --repo /path/to/project
appsec-analyzer abuse-cases AC-B-001 --repo /path/to/project

platform-settings: GitHub and GitLab security settings

platform-settings checks security settings of a repository on github.com, gitlab.com, or a self-hosted GitLab, such as required reviews, blocked force pushes, secret scanning, and workflow permissions. It reads the host from the repository URL; GITLAB_HOST is optional. See Platform security settings.

  • Sends read requests to the platform API only. Makes no model calls and sends no source code.
  • Reports each of seven checks as set, not set, or not checkable, with the reason.
  • Without a read-only token only public data is visible, so many results are not checkable.
# Public data only
appsec-analyzer platform-settings https://github.com/your-org/your-project

# With a read-only token held in an environment variable
appsec-analyzer platform-settings https://github.com/your-org/your-project \
  --token-env GITHUB_READ_TOKEN --json

assess runs the same checks for repositories selected as a URL (add --platform-token-env NAME for a read-only token); local checkouts are skipped. Control analysis and the survey use the result as context, and the report shows it in a Platform Security Settings section.

distribution: start your organization's own command

distribution helps an organization ship its own command, such as northstar-appsec, on top of this engine. It reads and writes local files only: no model calls, no network, no build, and nothing existing is overwritten.

# Create the organization repository from the example, under your name
appsec-analyzer distribution init northstar ./northstar-appsec

# After installing a newer engine: set every engine pin in that repository to it
appsec-analyzer distribution update-engine ./northstar-appsec
  • init needs a name of 2 to 30 lowercase letters and digits, and a directory that does not exist or is empty. The profiles, context, abuse cases and requirements it creates are sample content to replace.
  • update-engine changes the engine version in setup.cfg, requirements.lock and organization.yaml, and stops without changes if one is missing.
  • Building the wheels, installing and releasing remain manual. See the organization packaging guide.

Assessment options

These options apply to assess. Command-line options override the defaults from a scan profile.

Option Effect
--profile NAME Model profile. Default: claude.
--budget USD Maximum spend for claude, codex, LiteLLM, and Bedrock; with a Claude subscription, usage at API prices. Default: 12 for quick, 20 for standard, 40 for thorough.
--assessment-depth LEVEL quick, standard (default), or thorough. See below. In an interactive terminal, assess asks for the depth when you give none.
--quick, --standard, --thorough Shortcuts for --assessment-depth with that level. Two different depths in one command are refused.
--repo PATH_OR_URL Repeat to assess several repositories as one system.
--abuse-case-file PATH Check your own business rules from a YAML file. See custom abuse cases.
--abuse-cases Check technical and business abuse cases at any depth, including quick. Adds model calls.
--max-parallel N Components analyzed at once, 1 to 16. Default: 4, or 3 when the default applies and the components divide by three; 2 for Codex and Copilot subscriptions.
--non-interactive For CI. Without it, an interactive terminal may ask for the depth when none is given, and for a higher budget before skipping work.
--verbose Show job and call identities and detailed correction messages.
--show-costs Show costs even with subscription billing; default cost display is API billing only.
--console-log [color|html] Also save the console output as console.log in the output directory, without the live status line. Without colour codes unless you add color; html writes console.html with the colours for a browser. See progress and diagnostics.

--assessment-depth sets how much each method checks:

Method quick standard thorough
Scanners All source rules; first 5 config files per type, AI assistant settings in full All config files Also a check for shared database accounts
Survey Files with routes, scanner hits, or security keywords Same as quick Also all other program files, within the cost limit
Verification None Authentication, authorization, input validation, AI features Also data protection
Abuse cases Only with --abuse-cases or your own cases Cases that fit the code, built-in business rules, your own cases Also up to 3 business rules a model derives from the application

AI features are verified only where the application calls a language model. thorough also requires evidence of exploitation in the evidence review and can exceed the default budget. See choosing a depth.

Typical cost and duration with API billing, measured on OWASP Juice Shop (about 820 source files) with the claude profile:

Depth Cost Duration
quick about USD 8 about 20 minutes
standard about USD 15 about 40 minutes
thorough about USD 40 about 1.5 hours

Larger repositories cost more and take longer. The thorough run was continued with --resume, so its time includes earlier attempts. The figures are one run per depth, not guarantees.

Each verified aspect adds model calls. A scan or organization profile can change what each depth does.

Scan and model profiles explains how to store settings and choose models per role.

Model provider

score and scan-sources need no provider. assess selects its provider with --profile; without it, assess uses your scan profile default if you created one, otherwise claude. analyze-threats, authnz-review, and audit-requirements always use the Claude CLI.

The Claude profile uses Sonnet for reconnaissance at every depth. Explicit model selections still apply; see models and cost for overrides and limits.

--profile Provider Requirement
claude (default) Claude CLI claude on your PATH with a working login or externally configured Anthropic API credentials.
codex (experimental) OpenAI API OPENAI_API_KEY.
codex-cli (experimental) Codex CLI with your ChatGPT plan Codex CLI 0.163.0 or newer, signed in with codex login. See Codex CLI setup and limits.
copilot-cli (experimental) GitHub Copilot CLI Copilot CLI 1.0.101 and its separately configured login. See Copilot CLI setup and limits.
lite (experimental) LiteLLM gateway LITELLM_API_KEY and a gateway entry in providers.yaml with verified prices. See LiteLLM setup.
bedrock (experimental) Amazon Bedrock Converse API AWS_BEARER_TOKEN_BEDROCK and a Bedrock entry in providers.yaml with verified prices. See Bedrock setup.

The experimental profiles have not yet been qualified in live assessments. appsec-analyzer profiles list shows all built-in and user profiles.

# Check the provider setup without model calls
appsec-analyzer preflight --repo /path/to/project --profile codex

# OpenAI API
appsec-analyzer assess --repo /path/to/project --profile codex

# Codex CLI with a ChatGPT plan: counts model exchanges instead of USD
codex login
appsec-analyzer assess --repo /path/to/project \
  --profile codex-cli --max-calls 1000

# GitHub Copilot CLI: model use is limited by calls/time
# and a per-session soft credit limit
copilot login
appsec-analyzer assess --repo /path/to/project \
  --profile copilot-cli --max-calls 1000

# LiteLLM gateway: "claude" names the model entry in providers.yaml
appsec-analyzer assess --repo /path/to/project \
  --profile "lite claude" --budget 20

# Amazon Bedrock
appsec-analyzer assess --repo /path/to/project --profile bedrock --budget 20

codex-cli and copilot-cli reject USD budget options; limit them with --max-calls and optionally --max-duration SECONDS. Copilot also applies a per-session 30-AI-credit soft limit that can be exceeded by an in-progress response and is not an account-wide cap. All other profiles use the USD budget from --budget.

Configuration describes provider setup in detail. Organizations can ship preconfigured profiles; see the organization packaging guide.

Cost limits

Each model-backed command stops at a spending limit. The values are default upper limits, not expected costs. With a Claude subscription, that is Claude CLI without ANTHROPIC_API_KEY, the limit counts subscription usage at the API prices that Claude CLI reports.

Command Default limit Change with
assess USD 12, 20, or 40 per assessment (quick, standard, thorough) --budget USD
analyze-threats USD 1 per model call --max-budget-usd USD
authnz-review USD 5 per review --budget USD
audit-requirements USD 5 per audit --budget USD
  • In an interactive terminal, assess may ask for a higher limit before it skips work.
  • analyze-threats limits each model call, not the whole question. One question takes up to four calls.
  • With the codex-cli or copilot-cli profile, assess has no USD limit and counts model exchanges instead, 1000 by default (--max-calls). See Model provider.
  • review uses the assistant's own account and usage limits.

By default, assess shows monetary costs only with API billing. Subscription runs, including Claude CLI without ANTHROPIC_API_KEY, show usage without costs. --show-costs shows the available costs in any mode. It changes no accounting or limits.

Abuse cases

An abuse case is something an attacker or a user must not be able to do. Analyzer comes with two sets:

  • business.yaml has seven business rules. A user must not see other users' data, give themselves a higher role, approve their own request, or redeem a coupon twice.
  • technical.yaml has attack chains, such as account takeover through XSS or admin access through a forged JWT.

Verification checks a general property wherever it applies, such as whether routes check who owns the requested data. An abuse case asks whether an attacker can reach one goal, possibly across several steps or components. Add your own cases for rules specific to your application.

How assess uses them

  • Checks the cases that fit the code. quick depth skips them unless you pass --abuse-cases.
  • By default, checks all built-in business rules at standard and thorough depth, up to 16 rules in total. Rules that a verified aspect already covers come last.
  • Always checks rules you supply or request.
  • Lets a scan profile change these numbers and name cases that every run checks or skips; see what each depth does.
  • Reports a case the code allows as a new finding or links it to an existing one. A confirmed attack chain can also raise the severity of its findings. The results are in section 9 of the report.
  • Leaves a case open when the code does not answer the question. An open case is not counted as safe.

Add your own rules

Put them in a YAML file in the repository and pass it to assess:

appsec-analyzer assess --repo /path/to/project \
  --abuse-case-file abuse-cases.yaml

For example, abuse-cases.yaml:

schema_version: 2
abuse_cases:
  - id: REPO-AC-001
    kind: descriptive
    title: Customer lowers the order total with a negative quantity
    check: >-
      Check whether a customer can put a negative quantity of a product
      into the basket and so lower the order total.
    scope_qualifier: {path_patterns: ["*cart*", "*order*"]}
  • The path is relative to the repository root.
  • Rules passed this way are also checked at quick depth.
  • Limits and further fields are described under custom abuse cases.
  • To use the same rules in several repositories, put them in an organization profile.
  • To check a single built-in or organization case without a full assessment, run analyze-threats --abuse-case <ID>.

Documentation

Contributing

See CONTRIBUTING.md for development setup and tests, and product requirements for intended behavior. Read AGENTS.md before changing runtime behavior or report contracts.

The coverage setup explains the offline CI checks and how to add the Codecov token through GitHub's settings.

AppSec Analyzer grew out of AppSec Advisor and is distributed under the Apache 2.0 license.

Releases

Packages

Contributors

Languages