Pitangus

Plate I·Pitangus sulphuratus

Watch every change.Prove every fix.

Self-hosted application security for small teams and for anyone who builds with an AI assistant. Pitangus scans your code, dependencies and secrets on your own machine, tells you what each change introduces and what it fixes, and keeps the evidence an auditor can check.

  • Open source · AGPL-3.0
  • Runs on your server
  • No telemetry
Fig. 1 — Pitangus sulphuratus (Linnaeus, 1766)Habitat: your repositories. Diet: bugs.

Field guide

Every bug, catalogued like a specimen.

Open engines you already trust look at your code, dependencies, secrets, infrastructure and images, with rules for what AI-written code gets wrong: keys shipped to the browser, Supabase tables without row level security, open Firebase rules. Pitangus merges what they find, removes duplicates and files each finding with where it lives, how to fix it in the tool’s own words and the OWASP pages that apply.

Pitangus doesn’t invent fixes

Opengrep · Betterleaks · Trivy · OSV-Scanner · zizmor

Optional: Checkov · Grype

Passive, on domains you verify: httpx · testssl.sh · nuclei · ZAP and katana (experimental)

  1. № 01Code

    CWE-89

    SQL injection

    app/db.py:14

    Request input reaches a query built as text.

  2. № 02Dependency

    CVE-2021-23337

    lodash 4.17.15

    package-lock.json

    Update to 4.18.0: it closes all six advisories.

  3. № 03Secret

    CWE-798

    Supabase service_role key

    src/lib/supabase.ts:3

    It skips row level security, and the bundle hands it to every visitor. Rotate it.

  4. № 04Access rules

    pitangus.firebase.open

    Open Firestore rules

    firestore.rules:6

    No condition on reads or writes: anyone can read and change the data.

Pull requests

Only what your change brings. And what it fixes.

In CI or before every push, Pitangus scans the starting point and your change with the same engines, so a change is judged only by what it adds, copies included: a second copy of a problem is new, a moved one isn’t. It also says what the change fixed, and credits it only when both scans finished and the file really changed.

One step in your workflow

- uses: actions/checkout@v4
  with: { fetch-depth: 0 }
- uses: Pitangus-Dev/pitangus@v0.15.1

The official GitHub Action runs the published image: no build, no Docker socket.

$ pitangus scan --base main
Pitangus · api · changes since main (merge-base 4f2a9c1e, 1 file) No new findings. Fixed by this change (1): it was in the starting point, it’s gone, and its file changed.  HIGH     app/db.py:14  SQL injection from request input PASS · threshold: high or above · No new findings in the code that changes

The ledger

Fixed means verified. Not assumed.

Each finding keeps its history: when it appeared, who triaged it and why, its deadline from your policy, and the scan that proved it gone. Decisions are recorded, not overwritten.

FindingStatusDeadline
SQL injection · app/db.py:14FixedOct 20
lodash 4.17.15 · 6 vulnerabilitiesOpenOct 30
Public bucket · infra/s3.tfAccepted riskUntil Dec 1
  • i

    Deterministic

    The same code, engines and advisory data give the same result. An auditor can repeat it.

  • ii

    Compliance

    SBOM and VEX, audit evidence for SOC 2, ISO 27001 or the EU CRA, an opt-in kit for the CRA’s reporting deadlines, and a threat model of your design next to the scans.

  • iii

    Honest about gaps

    If an engine fails or is turned off, the scan says so, and nothing that engine looks at counts as fixed. It never reads as “no findings”.

Any tool, one ledger

Bring what other tools find.

Import SARIF from any scanner or AI reviewer. Its findings join the same registry, with triage, deadlines and tickets. Only a new full import from that same tool can mark them fixed: each tool vouches for what it looks at.

  • SARIFSemgrep
  • SARIFCodeQL
  • SARIFSnyk
  • SARIFTrivy
  • SARIFGrype
  • SARIFBandit
  • SARIFESLint
  • SARIFStrix
  • SARIFAny SARIF 2.1.0

Jira

Tickets a developer can act on.

Issues go to the right project for each repository, with your custom fields. They say what is wrong, where, how to fix it, how to verify it and by when. When the fix is verified, Pitangus comments on the issue.

SEC-142

High: update lodash 4.17.15 to 4.18.0 (6 vulnerabilities)

The problem
lodash 4.17.15 has 6 known vulnerabilities. Version 4.18.0 fixes all of them.
Where
acme/web · package-lock.json
How to fix it
npm install lodash@4.18.0
Due date
Oct 30, from your security policy
VERIFIED

Verified as fixed by Pitangus in scan 9f3c… on Oct 2.

Yours

Runs on your server. Speaks your language.

  • i

    Self-hosted

    Docker on your laptop, or one server with 4 GB of memory for the team. Your code and findings stay with you.

  • ii

    Open source

    AGPL-3.0. Read every line, change it, run it without asking.

  • iii

    English and Spanish

    Written for each language, not machine-translated. Reports, PR comments and tickets included.

  • iv

    No telemetry

    Nothing phones home. It downloads public advisory data; anything else is your choice: the domains you verify, GitHub and Jira if you connect them, OSV or a secret’s own provider if you turn them on.

Install

One command, or one server.

  1. 1Scan a project from its folder. All you need is Docker.

    docker run --rm -v "$PWD":/src:ro -v pitangus-cache:/data \
      ghcr.io/pitangus-dev/pitangus-worker:0.15 \
      python -m pitangus --data-dir /data scan /src
  2. 2For the team: the panel on one server, with Docker, make and git.

    git clone --branch v0.15.1 https://github.com/Pitangus-Dev/pitangus.git
    cd pitangus
    make setup PREBUILT=1
    make up
  3. 3Or add the Action to your workflow.

    - uses: Pitangus-Dev/pitangus@v0.15.1

Read the docs Free and open source (AGPL-3.0): no account, no telemetry. The first one-command scan downloads the engines’ advisory databases into the pitangus-cache volume, and later scans reuse them. The full web scan is experimental: set PITANGUS_DAST_ENABLED=1 and run make engines.

Questions

What people ask before installing it.

  1. What is Pitangus?

    Pitangus is a self-hosted, open-source application security platform for small teams and for people who build with AI assistants. It scans code, dependencies, secrets, infrastructure as code, CI workflows and container images with open-source engines, checks what a domain you verify shows anyone, merges what they find without duplicates, verifies each fix with a later scan and keeps the evidence an auditor can check. It is made in Colombia by Arodium and is in beta (current release v0.15.1).

  2. Is Pitangus free and open source?

    Yes: Pitangus is free software under the GNU Affero General Public License v3.0 (AGPL-3.0-only), with no account and no fee. You can use, study, change and run it on your own servers; if you offer a modified version to other people over a network, you must share that version’s source code under the same license. Its SAST rules are MIT-licensed, so other tools can reuse them.

  3. What does Pitangus scan?

    Pitangus scans source code with Opengrep and 66 rules of its own for JavaScript/TypeScript, Python, Java, Go, PHP, Ruby and C#, plus a reader of Supabase migrations and Firebase security rules; dependencies and malicious packages with Trivy and OSV-Scanner, prioritized with CISA KEV and EPSS; secrets with Betterleaks and Trivy, credential files such as .env and .npmrc included; infrastructure as code and GitHub Actions workflows with Trivy and zizmor; and container images with Trivy. Checkov and Grype are optional. For a domain you verify, the exposure check reads each host’s root and known paths with httpx, testssl.sh and nuclei (detection-only templates), without crawling; a full crawl with ZAP and katana is experimental and off by default. Your code is never executed. Findings from other scanners can be imported as SARIF 2.1.0.

  4. Does Pitangus help if I code with an AI assistant?

    Yes: Pitangus has rules for what AI-written code often gets wrong. They catch a Supabase service_role key in the code or read in browser code, secrets in variables the bundler makes public (NEXT_PUBLIC_, VITE_, REACT_APP_…), CORS open to any origin with credentials, routes without the authentication their siblings have and JWTs decoded without checking the signature. A reader of its own flags Supabase tables without row level security and open or test-mode Firebase rules. They are specific patterns: beyond them, Pitangus doesn’t review your app’s logic or authorization. Each finding can be copied as a prompt for Claude, Cursor or Copilot with the rule, the place, the matched code and the fix, never a secret’s value. Pitangus itself calls no AI.

  5. Does Pitangus attack my site?

    No: Pitangus only reads what a site shows, and only on domains you prove you control (a DNS record, a file or a meta tag). The exposure check requests each host’s root and a list of known paths (exposed files, debug and status consoles, TLS, headers), without crawling. The full web scan, experimental and off until you turn it on, also browses the hosts of your saved scope like a visitor, with ZAP and katana. Neither sends injections or fuzzing, nor submits forms (only the full scan signs in, as a test user you chose), nor sends an API anything but GET and HEAD requests. Each tool sends at most 10 requests a second and stops at a hard time limit. Active testing is not part of Pitangus today, and a Pitangus scan is not a pentest.

  6. What doesn’t Pitangus do?

    Pitangus does not attack your applications (its web scans are passive: no active DAST, no pentest), does not follow data flows across files the way CodeQL or a commercial engine like Snyk Code does, and does not tell you whether a vulnerable dependency is actually reachable from your code. For the first two, run an active scanner, CodeQL or Semgrep yourself and import their SARIF: imported findings get the same triage, evidence and verified-fix lifecycle as its own. Scanning scales by adding workers, on one machine or several; one worker runs one scan at a time.

  7. How does Pitangus run, and what does it need?

    Pitangus runs on your own machine with Docker. To scan one project, one docker run of the published worker image is enough: the first run downloads the engines’ advisory databases into a Docker volume, and later runs reuse them. For a team, the panel needs Docker Engine 24 or later with Compose v2.24 or later, make, git, 4 GB of memory and 8 GB of disk, and installing the published, signed images takes four commands: git clone, cd, make setup PREBUILT=1 and make up. For CI and before every push there is an official GitHub Action and a pre-commit hook, which don’t need a running Pitangus server.

  8. Does my code leave my server?

    No: with Pitangus your code is analyzed on your own machine or server and never sent to any service of ours, and there is no telemetry. By default it only downloads public advisory data and the engines’ databases, and pulls the images you ask it to scan. Everything else is your choice: the domains you verify and check; GitHub, Jira and your notification channels, if you connect them; your dependency names and versions to OSV, only if you allow it for a scan; and each secret found to its own provider (GitHub, Slack, AWS…), only with PITANGUS_SECRET_VALIDATION=1, to ask whether it still works. AI plays no part in the analysis.

  9. What does “verified fix” mean in Pitangus?

    In Pitangus a verified fix is one that a later scan proved: the finding was there before, it no longer appears, and the engines that look at it finished. If an engine fails or is turned off, the scan says so and nothing that engine covers counts as fixed. On a pull request a fix is credited only when both scans finished and the file really changed, and Verify again rescans on demand and answers “Fixed” or “Still present”.

  10. What compliance evidence does Pitangus produce?

    Pitangus produces an SBOM (CycloneDX), VEX (OpenVEX), SARIF, JSON and Markdown exports, SLA reports, an audit trail of every triage decision and PDF audit evidence for SOC 2 Type II, ISO/IEC 27001:2022, PCI DSS 4.0.1, the EU CRA, NIS2, DORA and GDPR Art. 32, NIST SSDF, CSF 2.0 and SP 800-53, the HIPAA Security Rule, and regulations in Brazil, Chile, Colombia and Mexico. For the EU CRA it also has an opt-in kit that tracks the 24-hour, 72-hour and 14-day reporting stages and prepares a draft, but never reports for you. Threat models (STRIDE, LINDDUN, PASTA, attack trees, ATT&CK) with their diagram and PDF report add design evidence next to the scans. It is evidence for an audit, not a certification.

  11. Is Pitangus available in Spanish?

    Yes: Pitangus is written in English and Spanish, not machine-translated. The panel, findings, fix guides, reports, pull request comments, notifications and Jira issues come in both languages, and each person reads findings in their own language without rescanning. Advisory text from NVD, OSV or GHSA is shown as published.