Run Scans in CI/CD
Run Scans in CI/CD
Run a scan from your pipeline to test each version of your agent before it ships. The SDK makes only outbound HTTPS requests, so it runs on ordinary CI runners with no inbound access (see Deployment for proxy and CA details).
This page covers the gate script and the pipeline wiring. For SDK installation, client
setup, and session handling, see the Quickstart. Provide the
API key through your CI provider’s secret store as the LAKERA_RED_API_KEY environment
variable; never hardcode or commit it.
The gate script
The script has two parts: a handler that relays each attack to your agent — this part is always yours to own — and gate logic that runs the scan and decides pass/fail, which is the same for every project and can be reused as is. For a complete handler wired to a real agent, see the full example in the Quickstart.
Your script decides what blocks the release: it inspects the per-objective results and
sets the exit code. The script below gates on isSuccessful — the same pass/fail the
dashboard shows, computed server-side at the platform’s default threshold. If your risk
bar is stricter or looser, see Custom pass/fail criteria.
Each ScanResultEntry has an objectiveId, the conversation, an evaluation
(attackSuccessScore 0–5, attackSuccessIndicator, explanation), the isSuccessful
verdict, and an error if the probe failed. The gate also fails closed: errored,
unscored, and never-ready results block the release.
TypeScript
Python
Custom pass/fail criteria
Most teams keep the platform default. If your risk bar differs, gate on
evaluation.attackSuccessScore (0 = no success, 5 = full success) instead of
isSuccessful; the rest of the script stays the same. This example blocks a
customer-facing agent on any partial success:
TypeScript
Python
Evaluation fields can be absent on errored or unscorable probes, so keep the errored
and unscored fail-closed checks from the script above.
Call it from the pipeline
Add the gate where you already block deploys — typically a required job on the release
branch. Both jobs read the API key from CI secrets and upload the results JSON even when
the gate fails, so a blocked release can be reviewed. They assume lakera-red-sdk and
tsx are in your package.json. For Python, replace the Node steps with
pip install lakera-red-sdk and python red_gate.py.
GitHub Actions — store the key as a repository secret named LAKERA_RED_API_KEY:
GitLab CI — define LAKERA_RED_API_KEY as a masked CI/CD variable; it is injected into
the job automatically:
Best practices
- Match scan depth to pipeline stage — run a fast
staticscan with a smallnumberOfProbeson every build, and a deeper adaptive scan (see Strategies) before a release. - Reuse one target per agent —
createOrGetTargetwith a stable name keeps every run scanning the same target, so results stay comparable across builds. See Reuse a Target Across Scans. - Scope objectives to your application — start with a few objectives that map to real risks for the app, including custom objectives, and expand as the gate earns trust; running everything on every build mostly adds noise and minutes.
- Store the results file as an artifact — the gate writes the exact snapshot it
decided on, giving each run a machine-readable record you can diff across builds and
attach to the release. (
writeResultsalso works when you just want the server’s latest copy.) - Gate on the results, review on the dashboard — the pipeline decides pass/fail
from the results JSON;
scan.dashboardLinkis the human review path for the full conversations behind a blocked release.
See Creating a Scan in the SDK Reference for the full parameter list.