OrthoSec
The AI Security Architect · Open source

Find the AI-specific risk in your product — deterministically.

OrthoSec traces untrusted input and model output through your code across nine languages, maps what it finds to the OWASP LLM Top-10, and writes an executive briefing on top. A reproducible, benchmark-gated core — not a probabilistic guesser.

$ pip install orthosec  &&  orthosec scan ./my-ai-app
10 / 10OWASP LLM Top-10 categories
9languages, dataflow-analyzed
100% / 0benchmark recall / false positives
~4×faster on large trees (parallel)

01Why OrthoSec

Generic SAST wasn't built for AI risk. It doesn't know that model output is untrusted, that a system prompt is a trust boundary, or that an agent tool that shells out is one injection away from RCE. OrthoSec is built around exactly those facts.

Deterministic core

Zero false positives, by design

Dataflow taint analysis — not line-proximity regex. It fires only when the actual untrusted data reaches the actual sink. Benchmark-gated at 100% precision.

Reachability, not keywords

Intra → interproc → cross-module

Traces taint across function calls and import boundaries (including re-export chains), respecting sanitizers and trust boundaries.

Grounded LLM layer

Executive briefing on top

An optional model layer explains business impact and drafts fixes — grounded on the deterministic findings, never the source of one.

02Quickstart

The core scanner needs no API key and no configuration.

# install (add language extras you use)
pip install "orthosec[intel,ts,go,java,kotlin,csharp,ruby,php,rust]"

# scan a local path — writes a self-contained HTML report
orthosec scan ./my-ai-app

# scan across cores, gate CI on HIGH+, emit SARIF
orthosec scan . --jobs auto --fail-on high --sarif orthosec.sarif

# clone & scan a remote or private repo (credentials stay off argv/logs)
orthosec scan owner/repo --git-token-stdin
Every scan writes an HTML report — a self-contained, theme-aware file with a built-in engineer / appsec / ciso / product toggle, taint paths, and a severity summary. See a live one →

03One scan, four lenses

The same findings, re-framed for the reader. Pass --profile, or flip it live in the HTML report.

engineer

Fix it

File, line, taint path, and the concrete remediation.

appsec

Triage it

OWASP LLM + MITRE ATLAS mapping, severity, confidence tier.

ciso

Report it

Business risk, posture score, annualized loss exposure bands.

product

Ship it

What blocks release and what's acceptable, in plain language.

04What it detects

Full OWASP LLM Top-10 (2025) coverage — 11 built-in detectors, plus an optional deterministic Semgrep engine for general code-security rules.

DetectorOWASPCatches
prompt-hardeningLLM01 / 07Untrusted input concatenated into prompts; secrets in system prompts
secretsLLM02Hardcoded provider / model API keys
unsafe-model-loadLLM03 / 04pickle / torch.load / unsafe deserialization; unpinned model fetches
dependency-auditLLM03Unpinned / untrusted-source AI deps; known CVEs via OSV.dev
data-poisoningLLM04Fine-tuning / training on untrusted data
output-handlingLLM05Model output into eval / shell / SQL / HTML sinks
tool-exposureLLM06Over-privileged agent tools with no confirmation gate
prompt-leakageLLM07System prompt written to logs / stdout
rag-trustLLM08Untrusted content ingested into a retrieval corpus
misinformationLLM09Ungrounded output in a high-stakes domain (advisory)
unbounded-consumptionLLM10Uncapped LLM calls; unbounded agent loops (denial-of-wallet)

05Nine languages, same discipline

Python uses the stdlib ast; every other language uses tree-sitter (JS also esprima). Each is an optional extra — without it, that language falls back to regex automatically, never a crash. AST = precise dataflow · pattern = scoped pattern-match.

LanguageLLM01LLM05LLM06LLM10
Python built-inASTASTASTAST
TypeScript / JSX [ts]ASTASTpatternAST
JavaScript [js]ASTpatternAST
Go [go]ASTASTpatternAST
Java [java]ASTASTpatternpattern
Kotlin [kotlin]ASTASTpatternpattern
C# / .NET [csharp]ASTASTpatternpattern
Ruby [ruby]ASTASTpatternpattern
PHP [php]ASTASTpatternpattern
Rust [rust]ASTASTpatternpattern

The AST paths (LLM01 untrusted→prompt, LLM05 output→sink) trace taint intra-function → interprocedural → cross-module, framework-aware of LangChain, LlamaIndex, OpenAI, Anthropic, Flask/FastAPI/Django and each language's popular SDKs.

06The trust model

Models make OrthoSec smarter without making it a guesser. The rule is directional:

Finding · stack UP

Deterministic is the arbiter

The 0-FP deterministic engine is the floor. Optional model passes corroborate (raise to confirmed) or discover extra advisory issues — deduped and excluded from the score/gate. A model never removes or invents a finding.

Fixing · cascade DOWN

Strongest first, re-scan verified

remediate --auto tries a deterministic codemod, then a local model, then a cloud model — and re-scans after each. A fix that doesn't verify is reverted, not shipped.

Every model integration is opt-in (env-gated), fail-open (degrades to deterministic, never crashes), and additive (never removes a deterministic signal).

07CLI & configuration

CommandWhat it does
scan <path | url | owner/repo>Scan a local path or clone & scan a remote/private repo. --jobs, --profile, --fail-on, --sarif/--json/--html, --diff, --baseline
ask <path> "<question>"Grounded Q&A over the findings (needs a model backend)
remediate <path> --autoVerify-gated auto-fix cascade (deterministic → local → cloud)
watch / scheduleContinuous or cron-scheduled scans with report output

Key environment variables

VariableEffect
ORTHOSEC_JOBSWorker processes (same as --jobs). Findings are byte-identical to a serial scan; ~4× on large trees
ORTHOSEC_SEMGREP=1Enable the bundled deterministic Semgrep engine (opt-in, off by default)
ORTHOSEC_OSV=1Enrich pinned AI/ML deps with known CVEs from OSV.dev
ORTHOSEC_CONFIDENCE=1Model corroboration → confidence tiers (needs a model backend)
ORTHOSEC_DISCOVER=1Model-led discovery of extra advisory findings (excluded from the gate)
ANTHROPIC_API_KEY · ORTHOSEC_LOCAL_MODEL_URLEnable the executive briefing / Q&A / auto-fix (cloud or a local OpenAI-compatible model)

08CI / CD

Gate pull requests on AI-security risk. Drop in the GitHub Action, or run the CLI / Docker anywhere.

# .github/workflows/orthosec.yml — scan changed files, upload SARIF
- uses: cloudivian-org/OrthoSec@main
  with:
    profile: appsec
    fail-on: high
    diff-ref: ${{ github.event.pull_request.base.sha }}
# any CI, or locally — via the published container
docker run --rm -v "$PWD:/scan" ghcr.io/cloudivian-org/orthosec \
  scan /scan --sarif /scan/orthosec.sarif --fail-on high
Adopting on an existing repo? Write a baseline once (--write-baseline) and gate on new findings only, so day-one noise never blocks CI.

09Private & remote repos

Scan a repo you don't have checked out. The host (GitHub / GitLab / Bitbucket) is auto-detected, and credentials are handled safely — passed via an askpass helper and child-process env, never on the command line or in logs.

# token read from stdin, never argv
orthosec scan owner/private-repo --git-token-stdin --branch main

# or use your SSH agent / git credential helper transparently
orthosec scan git@github.com:owner/private-repo.git