Antra
How it worksStar1Get Started
Star1
Antra
How it worksStar1Get Started
Star1
Documentation
  • Introduction
  • Installation
  • Quick start
  • Configuration basics
  • Monorepos
  • Trust boundaries
  • Findings and severity
  • Schema providers
  • Suppressions and baselines
  • antra init
  • antra scan
  • antra sync
  • antra doctor
  • antra baseline
  • antra trace
  • antra watch
  • antra fix
  • antra query
  • antra studio
  • Studio
  • Launching Studio
  • Reading the graph
  • Configuration reference
  • BG-001: Server-to-client leak
  • BG-002: Unvalidated input
  • BG-003: Opaque object pass
  • BG-004: Secret in markup
  • GitHub Actions
  • Introduction
  • Installation
  • Quick start
  • Configuration basics
  • Monorepos
  • Trust boundaries
  • Findings and severity
  • Schema providers
  • Suppressions and baselines
  • antra init
  • antra scan
  • antra sync
  • antra doctor
  • antra baseline
  • antra trace
  • antra watch
  • antra fix
  • antra query
  • antra studio
  • Studio
  • Launching Studio
  • Reading the graph
  • Configuration reference
  • BG-001: Server-to-client leak
  • BG-002: Unvalidated input
  • BG-003: Opaque object pass
  • BG-004: Secret in markup
  • GitHub Actions

Configuration reference

Every field in antra.config.json, with its type, default, and what it does.

antra.config.json, read from your project root. It is validated on load against a schema, so a malformed file is reported rather than silently half-applied.

antra init writes it. For most projects the only fields worth editing are sensitiveFields, sanitizers, and rules.

Fields

FieldTypeRequiredDefaultWhat it holds
version1yesnoneSchema version. The literal 1.
frameworkAdapterstringyesnoneWhich framework adapter to analyze with. v1 ships one: nextjs-app-router. Non-empty.
providersobject[]yesnoneSchema providers to read sensitive fields from.
keywordsobjectyesnoneName patterns used to spot sensitive fields.
sensitiveFieldsobjectno{ "include": [], "exclude": [] }The explicit sensitive-field list.
sanitizersstring[]yesnoneFunction names that clear taint.
rulesobjectyesnoneRule id to boolean, enabling or disabling each rule.

keywords

"keywords": {
  "include": ["password", "iban", "ssn"],
  "exclude": ["password_reset_token"]
}

include holds name patterns, matched against names with case and separators ignored (passwordHash, password_hash, PASSWORD-HASH). Most patterns match as substrings, so password catches passwordhash and motdepasse catches mot_de_passe. Patterns of three characters or fewer, and the common English words token, secret, salt, hash, key and pin, match whole words only: accessToken matches token, totalTokens and secretaryName do not.

The default list no longer contains hash, which matched commit and content hashes. A password or token hash is still caught through password or token. antra doctor warns when an older config still has it.

keywords.exclude is accepted, but it is a legacy alias for sensitiveFields.exclude. Prefer the latter.

sensitiveFields

"sensitiveFields": {
  "include": ["supabase:public.users.iban", "internal_risk_score"],
  "exclude": ["public_uuid"]
}

Entries are matched either by exact origin or by exact field name. An origin looks like supabase:public.users.iban, meaning the provider, then the path, then the field.

  • include: always sensitive.
  • exclude: never sensitive. It wins over everything else, including include and the keyword patterns.

antra init seeds include with the fields the keyword scan found, and you edit from there. That is why the file is worth reading once after init: it is a proposal, not a verdict.

providers

Each provider entry has an id selecting the provider; every other key in that object is the provider's own settings.

"providers": [
  { "id": "prisma", "schemaPath": "prisma/schema.prisma" },
  { "id": "openapi", "spec": "openapi.json" }
]

The entry is deliberately loose. Each provider validates its own shape when it runs, so the config file does not need to know every provider's settings. See Schema providers for what each one reads.

Warning

Provider settings are not validated at load time, only when the provider runs. A typo in schemaPath shows up as a provider that extracts nothing, not as a config error. If a scan stops finding schema-derived fields, run antra doctor and check the snapshot.

rules

"rules": {
  "BG-001": true,
  "BG-002": true,
  "BG-003": true,
  "BG-004": true
}

Each key is a rule id and the boolean turns it on or off. Turning a rule off here is a project-level decision: it applies to everyone, stays out of the diff, and is the honest way to say "this rule is wrong for this codebase". Prefer it to a pile of per-line suppressions. The rules are documented at BG-001, BG-002, BG-003, and BG-004.

sanitizers

"sanitizers": ["zod", "validateEmail", "parseUser"]

These are the functions and schema libraries Antra counts as validation. When a value passes through a call to one of these names, Antra stops tracking it as tainted. The call is assumed to have checked the value, so nothing downstream of it is reported.

  • BG-002. A Server Action or route handler that calls a configured validator counts as validated, and the rule stays quiet.
  • BG-003. A sanitized value carries no taint, so it is not reported when it crosses to a client component.

Libraries and your own functions

Antra knows the parse and validate call shapes of zod, valibot, yup, joi, arktype, and next-safe-action without any configuration.

Every other name is matched as a function or method name, so a validator of your own works the same way. Add its name to the list ("validateInput"), and each call to validateInput(data) is treated as validation. No extra package needed.

A complete example

{
  "version": 1,
  "frameworkAdapter": "nextjs-app-router",
  "providers": [{ "id": "prisma", "schemaPath": "prisma/schema.prisma" }],
  "keywords": {
    "include": ["password", "iban", "ssn", "secret", "token"]
  },
  "sensitiveFields": {
    "include": ["supabase:public.users.iban"],
    "exclude": ["public_uuid"]
  },
  "sanitizers": ["parseUser", "CreateUserSchema.parse"],
  "rules": {
    "BG-001": true,
    "BG-002": true,
    "BG-003": true,
    "BG-004": true
  }
}

Validating changes

antra doctor

Checks that the file parses and validates, that the rules load, and that the parser is ready. Run it after editing rather than drawing conclusions from a scan that behaves oddly.

State written beside your project

Antra keeps its own state under .antra/:

PathWritten byHolds
.antra/antra-findings.sqliteantra scanScan history; read by antra query and Studio.
.antra/contract-snapshot.jsonantra init, antra syncThe extracted taint sources: a generation timestamp and a list of field/origin pairs.

Add .antra/ to .gitignore. It is derived state, regenerated from your code and your data layer.

Previous
Reading the graph
Next
BG-001: Server-to-client leak
On this page
  • Fields
  • keywords
  • sensitiveFields
  • providers
  • rules
  • sanitizers
  • Libraries and your own functions
  • A complete example
  • Validating changes
  • State written beside your project