SAST (Static Application Security Testing) reads your source code and reports vulnerabilities without executing it.

What it catches

CategoryExamples
InjectionSQL injection, command injection, NoSQL injection, LDAP injection
Cross-site scriptingReflected XSS, stored XSS, DOM XSS
Path traversal../../etc/passwd-style file access via user input
Insecure deserializationpickle.loads(user_data), Java readObject on untrusted input
SSRFServer-side request forgery from user-controlled URLs
Hardcoded secretsAPI keys, tokens, private keys (overlap with the dedicated Secrets scanner — run both, results de-dupe)
Weak cryptographyMD5, SHA1, ECB, hardcoded IVs, predictable RNG
Missing authenticationEndpoints without an auth check
CWE-mappedAll findings carry the canonical CWE ID for compliance reporting
Every finding carries its CWE and OWASP Top 10 (2021) mapping; reports roll findings up to OWASP Top 10, CWE Top 25, PCI DSS, and SOC 2.

Languages supported

LanguageStatus
JavaScript / TypeScriptFull
PythonFull
GoFull
Java / KotlinFull
RubyFull
PHPFull
C#Full
RustBeta
C / C++Beta
SwiftBeta
ScalaBeta
SAST uses TigerGate’s AST-based pattern-analysis engine, which auto-detects languages from the repo’s file extensions and only runs rule packs that apply. Bundled fallback engines keep a scan producing results if the primary engine is ever unavailable at runtime.

Rule packs

TigerGate ships with three layers of rules, all enabled by default and configurable from Code Security → SAST Rules:
  1. Public security packs — OWASP Top 10, CWE Top 25, security-audit, secrets, SQL injection, XSS, command injection, insecure-transport, JWT, plus per-language packs (Python, Node.js, Go, Java, C#, Ruby, PHP, React).
  2. AI / LLM pack — ~127 rules covering LLM provider key leaks (OpenAI, Anthropic, Cohere, Gemini, Mistral, HuggingFace), prompt injection, MCP tool poisoning and command injection, LangChain dangerous-exec, and AI agent / hook security (DNS exfiltration, path traversal, sensitive file access).
  3. TigerGate catalog — our internal ruleset shipped to the CLI at scan time. Covers SSRF, path traversal, deserialization, weak crypto, and auth-bypass classes.
Configuration is two-tiered:
  • Org-level is the default — applies to every repository unless overridden.
  • Repo-level shadows org-level for that one repo. The dashboard’s Configure for dropdown switches scope.
You can:
  • Toggle whole rule packs on/off in the Configuration tab.
  • Disable individual rules from the Catalog tab (the rule ID flows through to the scanner as a per-rule exclusion).
  • Override severities (e.g., demote a rule from high to medium for quality-gate purposes).

Catalog browser

Code Security → SAST Rules → Catalog lists every rule that ships in the configured rule packs, grouped by language. Each entry shows:
  • Rule ID, severity, CWE/OWASP mapping
  • “Why it matters” with vulnerability context
  • Side-by-side Noncompliant vs Compliant code for the languages we have curated examples for
  • A per-rule Disable button that scopes to your current Configure for selection (org or repo)
Use the catalog to triage rules during initial onboarding — disable noisy rules in one click rather than digging through scanner config files.

Custom rules

Author your own rules under Code Security → SAST Rules → Custom Rules. They’re org-scoped by default; switch the Configure for dropdown to a repository to scope them to one repo. Custom rules ride along on every CI scan automatically — no CLI changes, no commits to a .tigergate-rules/ directory. The dashboard editor takes a single rule body (no wrapper); TigerGate merges enabled rule bodies into the served ruleset at scan time.
# Authored in the dashboard editor — one rule body, no `rules:` wrapper.
id: no-direct-db-access-from-handlers
languages: [typescript]
severity: ERROR
message: |
  HTTP handlers must go through the repository layer.
  Direct DB calls bypass row-level security and audit logging.
pattern-either:
  - pattern: $DB.query(...)
  - pattern: $DB.execute(...)
paths:
  include:
    - src/handlers/

Validation before save

TigerGate validates the rule body server-side before committing it. If the YAML has parse errors, missing required fields (id, message, languages, severity, a pattern), or invalid value shapes, save is blocked and errors are shown inline. The validator checks:
  • YAML parses (line/column reported on parse errors)
  • Required keys present (id, message, languages, severity, plus a pattern form)
  • id matches the allowed character set (1–149 chars of letters, digits, _, -, .)
  • severity is one of ERROR, WARNING, INFO, INVENTORY, EXPERIMENT
  • languages is a non-empty array of strings
  • patterns and pattern-either are lists when present
  • Unknown top-level keys produce warnings (non-blocking)
See the SAST rule writing guide for the full authoring flow, pattern syntax, scoping (per-org / per-repo), and worked examples per language.

Suppressing false positives

In the dashboard — open the finding, click Mark as MUTED, and add a justification. Mutes are scoped per-(rule, file path), so a single mute won’t hide the same rule firing somewhere else. Whole paths — exclude test or vendor directories at scan time with --exclude (e.g. --exclude test,fixtures,vendor), or set the repo’s excluded paths in its dashboard settings.

Performance

Repo sizeTypical scan time
< 50k LOC30–60s
50k – 500k LOC1–3m
500k – 5M LOC3–10m
Mono-repo > 5M LOC10–30m
The CLI parallelises across CPU cores. For mono-repos, scope to PR-changed code in CI:
tigergate scan --type sast --scan-scope diff --upload
--scan-scope diff reports only findings on lines the PR changed, which runs much faster on large repos and keeps PR feedback high-signal.