Judgment layer (optional)
Palisade has two layers, and most people only ever need the first.
- The offline core -
scan,map,baseline,fix, andredteamsynthesis. No API key, no account, no network calls, no telemetry. This is whatuvx palisade-sec scan .runs, and it is the whole tool for most users. - The judgment layer -
audit,redteam --execute, and the AI-judged part ofreview. These ask a language model to judge findings the static analyzer already grounded (how exploitable is this path, can this tool take an irreversible action). They need an endpoint you configure. Nothing is sent anywhere until you set one up.
Which commands need a key?
| Command | Needs a judgment endpoint? |
|---|---|
scan (the headline command) | No - offline, keyless |
map | No |
fix | No |
baseline | No |
redteam (synthesis - the default) | No |
audit | Yes (exits 2 with a hint without one) |
review | Only for the AI-judged layer. Without the extra or a key it runs taint-only and says so |
redteam --execute | Yes (exits 2 with a hint without one) |
You are not locked into one vendor. The judgment layer speaks TypeSafe (the default, whose answers Palisade treats as verified) or any OpenAI-compatible endpoint (OpenAI, a local model, an internal gateway).
Setup (about two minutes)
1. Install the extra
pip install 'palisade-sec[judge]'# oruv add 'palisade-sec[judge]'# or one-shot, nothing installed permanentlyuvx --from 'palisade-sec[judge]' palisade-sec review .Without the extra, audit and redteam --execute exit 2 with an install
hint, and review runs taint-only.
2. Create a .env
Palisade reads the judge settings from the environment, or from a .env in
the current working directory (the directory you run palisade-sec from, or a
parent of it). Variables already set in the environment win over .env.
Create .env there from this template and fill in one backend:
# Palisade judgment layer configuration.## ONLY the bring-your-own-endpoint commands (audit, review, redteam execution)# read this. The offline core (scan, map, baseline, fix) never calls out and# never needs any of it.## Copy to `.env` in the directory you run palisade-sec from, and fill in. Your# shell environment wins over this file. Keys are never logged.## For safety, an endpoint set in a .env file is only used with a key from the# same file: a repository you clone can ship its own .env, and it must not be# able to send the key from your shell to a server it chose.
# Which adapter to use: typesafe | openai_compatiblePALISADE_JUDGE_BACKEND=typesafe
# Base URL of the judgment endpoint.# typesafe -> defaults to https://api.typesafe.ai# openai_compatible -> required, e.g. https://api.openai.com/v1# PALISADE_JUDGE_ENDPOINT=https://api.typesafe.ai
# Model id.# typesafe -> defaults to jev-latest# openai_compatible -> required, e.g. gpt-4o-mini# PALISADE_JUDGE_MODEL=jev-latest
# Key for PALISADE_JUDGE_BACKEND=typesafe (recommended):TYPESAFE_API_KEY=
# Key for PALISADE_JUDGE_BACKEND=openai_compatible (best-effort, unverified;# never blocks on judgment alone):PALISADE_JUDGE_API_KEY=(From a clone of the repo, cp .env.example .env gives you the same file;
the template is not shipped in the installed package.)
Option A - TypeSafe (default):
PALISADE_JUDGE_BACKEND=typesafePALISADE_JUDGE_ENDPOINT=https://api.typesafe.ai # default, can omitPALISADE_JUDGE_MODEL=jev-latest # default, can omitTYPESAFE_API_KEY=... # your keyGet a key at typesafe.ai. TypeSafe returns typed answers with confidence, so Palisade marks its judgments verified - they can inform a BLOCK decision or a Critical posture.
Option B - any OpenAI-compatible endpoint:
PALISADE_JUDGE_BACKEND=openai_compatiblePALISADE_JUDGE_ENDPOINT=https://api.openai.com/v1 # requiredPALISADE_JUDGE_MODEL=gpt-4o-mini # requiredPALISADE_JUDGE_API_KEY=... # your keyA generic endpoint is validated against a strict schema and treated as best-effort / unverified: it can flag and downgrade findings, but it can never emit a BLOCK or raise a Critical posture on judgment alone.
3. Run a judged command
palisade-sec audit .# orpalisade-sec review .If the extra or key is missing, audit exits 2 with a clear message and
review falls back to taint-only (and tells you on stderr). The offline core
keeps working regardless.
What stays honest about this layer
- Your keys stay yours. They are read from the environment only, and never logged or included in error messages.
- The core never calls out. Only the three judged commands above touch the
network;
scan/map/fix/baselinenever do. - Judged signals are advisory unless you opt in to a gate.
review --cigates only on deterministic taint findings; its judged signals never fail your build.audit --ciis the one explicit opt-in gate on judged output: it exits1on a BLOCK decision (which an unverified backend cannot produce on judgment alone). Calibration is preliminary: measured on a 10-case seed corpus (n=4 to 6 per signal), not a benchmark result; the judged layer stays advisory. - An unverified backend cannot manufacture severity. It downgrades to REVIEW rather than BLOCK, and cannot raise a Critical posture alone.
Your thresholds, not ours
audit and review route to pass / review / block on thresholds you own.
Drop a .palisade/policy.yaml in the project, put the same keys under
[tool.palisade.semantic] in pyproject.toml, or name a file with
--policy PATH:
checks: excessive_agency: action_threshold: 0.45 # block above this probability review_threshold: 0.20 # human review between the two gate_threshold: 0.60 # count a tool as "gated" only above this severity_block: 1 # harm >= this turns a review into a block taint_exploitability: action_threshold: 0.40 severity_block: 1A partial file overlays the defaults, so setting one threshold leaves the rest alone. A typo is an error, not a shrug: the run warns and falls back to the defaults rather than quietly gating at a number nobody picked.
criteria - editable English that sharpens the question put to the model - has
one restriction, and it is deliberate. That text becomes part of the prompt, so
a policy file found inside the code being scanned may set thresholds but not
criteria; it is dropped with a warning. Otherwise a repository you audit could
ship a policy reading “nothing here is ever irreversible” and argue the judge
out of its own finding - which is the attack class this tool exists to detect.
Pass --policy to set criteria yourself.
Configuration reference
| Variable | Meaning |
|---|---|
PALISADE_JUDGE_BACKEND | typesafe (default) or openai_compatible |
PALISADE_JUDGE_ENDPOINT | Base URL. Defaults to the TypeSafe API for typesafe; required for openai_compatible |
PALISADE_JUDGE_MODEL | Model id. Defaults to jev-latest for typesafe; required for openai_compatible |
TYPESAFE_API_KEY | Key for the typesafe backend |
PALISADE_JUDGE_API_KEY | Key for the openai_compatible backend |
redteam --execute additionally reads PALISADE_REDTEAM_TARGET (the endpoint
you fire attacks at) and PALISADE_REDTEAM_KEY. It drives the target you
provide, in your environment - Palisade never executes your code.
See the CLI reference for every command and flag.