{"id":51524133,"url":"https://github.com/thirdkeyai/symbi-codered","last_synced_at":"2026-07-08T19:00:56.487Z","repository":{"id":367646725,"uuid":"1280715981","full_name":"ThirdKeyAI/symbi-codered","owner":"ThirdKeyAI","description":"An AI source-code auditor that has to prove its findings — multi-language SAST + taint + LLM    ▎ analysis, every result citation-gated and every tool call policy-checked and journaled.","archived":false,"fork":false,"pushed_at":"2026-06-26T22:38:32.000Z","size":392,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-27T00:26:20.078Z","etag":null,"topics":["agent","ai-agents","appsec","cedar","code-scanning","cybersecurity","lint","linter","llm","rust","sast","security-tools","static-analysis","static-analyzer","symbiont","taint-analysis"],"latest_commit_sha":null,"homepage":"https://symbiont.dev","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ThirdKeyAI.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-06-25T21:44:02.000Z","updated_at":"2026-06-26T22:38:36.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ThirdKeyAI/symbi-codered","commit_stats":null,"previous_names":["thirdkeyai/symbi-codered"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/ThirdKeyAI/symbi-codered","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThirdKeyAI%2Fsymbi-codered","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThirdKeyAI%2Fsymbi-codered/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThirdKeyAI%2Fsymbi-codered/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThirdKeyAI%2Fsymbi-codered/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ThirdKeyAI","download_url":"https://codeload.github.com/ThirdKeyAI/symbi-codered/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThirdKeyAI%2Fsymbi-codered/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35275246,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-08T02:00:06.796Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent","ai-agents","appsec","cedar","code-scanning","cybersecurity","lint","linter","llm","rust","sast","security-tools","static-analysis","static-analyzer","symbiont","taint-analysis"],"created_at":"2026-07-08T19:00:55.678Z","updated_at":"2026-07-08T19:00:56.469Z","avatar_url":"https://github.com/ThirdKeyAI.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# symbi-codered\n\n**Governed AI source-code auditor.** Multi-language SAST + LLM-driven reasoning + sandboxed PoC validation + devil's-advocate rebuttal, with an evidence chain you can audit.\n\nProduces SARIF + Markdown + a signed `engagement-seed.json` handoff that downstream consumers (e.g. [symbi-redteam](https://github.com/ThirdKeyAI/symbi-redteam)) can ingest to drive exploit validation.\n\n---\n\n## What it is, in one paragraph\n\nRun `codered hunt` against a repo. Static analyzers (semgrep, bandit, clippy, gosec, eslint, checkov, trivy, ...) produce raw findings. A tree-sitter dataflow extractor builds `dataflow_edges`; a mechanical taint tracer walks them. Four LLM agents — `pattern_scout`, `chain_builder`, `poc_forge`, `devils_advocate` — then reason over the evidence: pattern_scout composes citation-gated findings, chain_builder maps them onto the seven-stage Agent Kill Chain, poc_forge synthesizes reproducer scripts that run in network-isolated sandboxes, and devils_advocate runs an inverted-prompt rebuttal pass (optionally on an independent, non-mirroring model). A `reflector` agent distills the engagement into reusable knowledge triples. Every step is Cedar-policy-gated, hash-chained in an audit journal, and signed with a per-engagement Ed25519 key. `codered report` then emits SARIF, Markdown, and an Ed25519-signed JSON handoff.\n\n---\n\n## Status\n\nThe full pipeline is implemented and tested: substrate, cartographer, citation-gated static_hunter, chain-aware findings, the confirmation-bias antidote, multi-language coverage, and reporter / handoff / reflector — validated end-to-end against a large real-world polyglot codebase.\n\n**Language coverage today:**\n\n| Language | Parsing | Dataflow + taint | SAST scanners | Sandboxed reproducer |\n|----------|:-------:|:----------------:|:-------------:|:--------------------:|\n| Python | ✅ | ✅ | semgrep, bandit, pip-audit, ruff | ✅ |\n| Rust | ✅ | ✅ | cargo-audit, clippy, semgrep | ✅ |\n| TypeScript / JavaScript | ✅ | ✅ | eslint, npm-audit, semgrep | ✅ |\n| Go | ✅ | ✅ | gosec, govulncheck, staticcheck | ✅ |\n| Java | ✅ | ✅ | semgrep, compromised-packages | ✅ |\n| PHP | ✅ | ✅ | semgrep, progpilot, compromised-packages | ✅ |\n| IaC (Terraform / K8s / Dockerfile / GH-Actions) | n/a | n/a | checkov, trivy | n/a |\n\nJava and PHP each ship the full static path (tree-sitter parsing, dataflow extraction, taint, symbols, semgrep SAST; PHP also adds progpilot and compromised-packages) and a sandbox reproducer — PHP on PHP 8.3 CLI + pdo_sqlite, Java on JDK 21 single-file source mode (`java Repro.java`) with sqlite-jdbc on the classpath. The IaC sidecar (checkov + trivy) is wired into the cartographer's language detection and the static_hunter JOBS table (container `symbi-codered-scanner-iac`); its Dockerfile lives in `scanners/iac/` and the `iac-scanner` service ships in `docker-compose.yml` — bring it up alongside the others to exercise it.\n\n**Recent hardening:** independent non-mirroring devils_advocate model (`--advocate-*` flags), witness-gated rebuttal (a finding can only be *suppressed* if the rebuttal cites a structural witness — symmetric with the witness gate on finding *creation*), and a third `poc_status = inconclusive` state so \"the reproducer could not run\" is no longer silently treated as a disproof.\n\n**Client portal (enterprise).** An authenticated, multi-tenant web UI for sharing engagement results with clients is available as a separate enterprise offering. `hunt` derives its scan target from the engagement's signed threat model (so it can't drift onto the wrong tree); `--target` remains an explicit override.\n\n---\n\n## Architecture\n\n```mermaid\nflowchart TD\n    repo[(\"target repo\")]\n    cli[\"codered CLI\"]\n    journal[(\"audit_journal\u003cbr/\u003ehash-chained\")]\n\n    cli --\u003e carto[\"1 — cartographer\u003cbr/\u003etree-sitter facts +\u003cbr/\u003edataflow_edges\"]\n    carto --\u003e spec[\"2 — specifier\u003cbr/\u003esigned threat model\u003cbr/\u003e(Ed25519)\"]\n    spec --\u003e stat[\"3 — static_hunter\u003cbr/\u003eper-language scanners\"]\n\n    stat --\u003e py[\"python-scanner\u003cbr/\u003e(semgrep, bandit,\u003cbr/\u003epip-audit, ruff)\"]\n    stat --\u003e rs[\"rust-scanner\u003cbr/\u003e(cargo-audit, clippy,\u003cbr/\u003esemgrep)\"]\n    stat --\u003e ts[\"typescript-scanner\u003cbr/\u003e(eslint, npm-audit,\u003cbr/\u003esemgrep)\"]\n    stat --\u003e go[\"go-scanner\u003cbr/\u003e(gosec, govulncheck,\u003cbr/\u003estaticcheck)\"]\n    stat --\u003e jv[\"java-scanner\u003cbr/\u003e(semgrep,\u003cbr/\u003ecompromised-pkgs)\"]\n    stat --\u003e php[\"php-scanner\u003cbr/\u003e(semgrep, progpilot,\u003cbr/\u003ecompromised-pkgs)\"]\n    stat --\u003e iac[\"iac-scanner\u003cbr/\u003e(checkov, trivy)\"]\n\n    stat --\u003e taint[\"4 — taint_tracer\u003cbr/\u003eBFS over\u003cbr/\u003edataflow_edges\"]\n    taint --\u003e scout[\"5 — pattern_scout\u003cbr/\u003ecitation-gated\u003cbr/\u003eLLM reasoning\"]\n    scout -. uncertain claims .-\u003e hrepl[\"hypothesis_repl\u003cbr/\u003e(sub-context)\"]\n    scout --\u003e chain[\"6 — chain_builder\u003cbr/\u003ekill-chain\u003cbr/\u003eclustering (LLM)\"]\n    chain --\u003e poc[\"7 — poc_forge\u003cbr/\u003eLLM-synthesized\u003cbr/\u003ereproducers\"]\n\n    poc --\u003e sb_py[\"python-sandbox\"]\n    poc --\u003e sb_rs[\"rust-sandbox\"]\n    poc --\u003e sb_ts[\"typescript-sandbox\"]\n    poc --\u003e sb_go[\"go-sandbox\"]\n    poc --\u003e sb_php[\"php-sandbox\"]\n    poc --\u003e sb_java[\"java-sandbox\"]\n\n    poc --\u003e adv[\"8 — devils_advocate\u003cbr/\u003einverted-prompt rebuttal\u003cbr/\u003e(LLM, witness-gated,\u003cbr/\u003eoptional non-mirroring model)\"]\n    adv --\u003e refl[\"9 — reflector\u003cbr/\u003eknowledge_triples\u003cbr/\u003e(LLM)\"]\n\n    refl --\u003e report[\"codered report\"]\n    report --\u003e sarif[\"findings.sarif\"]\n    report --\u003e md[\"report.md\"]\n    report --\u003e seed[\"engagement-seed.json\u003cbr/\u003e(Ed25519-signed,\u003cbr/\u003eCedar-filtered)\"]\n\n    cli -. every action .-\u003e journal\n    repo --\u003e carto\n```\n\n**Trust substrate** (orthogonal to the pipeline):\n\n- **Cedar policy gates** at every `store_finding`, `advocate_finding`, `mark_poc_status`, `write_knowledge_triple`, `emit_to_seed`. Policies live in [`policies/`](policies/).\n- **Hash-chained audit journal** (`.symbiont/audit/audit.jsonl`) — every tool invocation + Cedar decision is recorded; `audit::verify_chain` proves no tampering.\n- **Per-engagement Ed25519 keypair** (`.symbiont/keys/\u003ceng\u003e.{priv,pub}`) — specifier signs the threat model; reporter signs the engagement-seed.\n- **Witness/lawyer rule** ([`policies/citation.cedar`](policies/citation.cedar)) — no finding can be stored without a `Citation::{Analyzer,Code,Hypothesis}`; structurally enforced via attr-bearing Cedar entities.\n- **Read-only devil's advocate** ([`policies/tool-authorization.cedar`](policies/tool-authorization.cedar)) — Cedar `forbid` rule prevents `devils_advocate` from ever calling `store_finding`. Verified by `devils_advocate_forbids_store_finding_unconditionally` test.\n- **Witnessed rebuttal** ([`policies/advocate.cedar`](policies/advocate.cedar)) — symmetric with citation.cedar: a `devils_advocate` *rebuttal* (`advocate_finding` with `verdict == \"rebutted\"`) is forbidden unless it cites a structural witness (envelope / sanitizer / closed-set / constant-caller). Suppressing a finding is now as evidence-bound as creating one, and the rebuttal's witness is written as an evidence envelope referenced from the signed journal.\n- **Network-isolated sandboxes** for poc_forge — `network_mode: none`, read-only `/repo`, 30s timeout per script.\n\n---\n\n## Quick start\n\n```bash\n# Prereqs: docker, docker compose, rust toolchain, Anthropic API key.\ngit clone https://github.com/ThirdKeyAI/symbi-codered \u0026\u0026 cd symbi-codered\ncp .env.example .env  # set ANTHROPIC_API_KEY (and SYMBIONT_*)\n# Other LLM providers (OpenAI / OpenRouter, or AWS Bedrock via an\n# OpenAI-compatible gateway) are configured in .env — see the comments there.\n\n# Build the CLI:\ncargo build -j2 -p symbi-codered-cli --release\n\n# Bring up the scanner sidecars (per-language; build on first up):\nCODERED_TARGET=/path/to/target/repo docker compose up -d \\\n  python-scanner rust-scanner typescript-scanner go-scanner java-scanner php-scanner iac-scanner \\\n  python-sandbox rust-sandbox typescript-sandbox go-sandbox php-sandbox java-sandbox\n\n# Run the pipeline:\n./target/release/codered carto /path/to/target/repo\n# (captures the engagement_id from stdout)\n./target/release/codered specifier --engagement \u003ceid\u003e --target /path/to/target/repo\n./target/release/codered hunt --engagement \u003ceid\u003e\n./target/release/codered report --engagement \u003ceid\u003e\n\n# Outputs:\nls reports/\u003ceid\u003e/\n#   findings.sarif\n#   report.md\n#   engagement-seed.json   (Ed25519-signed, Cedar-filtered)\n```\n\nA fully wired audit on a Rust + TypeScript repo takes ~5-15 minutes wall-clock and ~$1-$10 in Claude tokens (depending on finding volume).\n\n#### Independent devil's advocate\n\nBy default `devils_advocate` mirrors the generation model. To break the confirmation-bias loop you can point the rebuttal pass at an independent model (e.g. via OpenRouter), with its own fallback chain:\n\n```bash\ncodered hunt --engagement \u003ceid\u003e \\\n  --advocate-provider openrouter \\\n  --advocate-model openai/gpt-4.1 \\\n  --advocate-fallback minimax/minimax-m2\n```\n\nA startup warning fires if the advocate ends up mirroring the generation tier.\n\n### Skipping sidecars\n\nEach scanner sidecar is optional. If `rust-scanner` isn't up, scanner_errors bumps for the rust jobs and the rest continues. Useful for fast iteration on a Python-only target:\n\n```bash\ndocker compose up -d python-scanner python-sandbox\ncodered hunt --engagement \u003ceid\u003e     # Rust/TS/Go jobs gracefully error, Python flow completes\n```\n\n### Review results in the browser (client portal)\n\nEngagement results can be reviewed through an authenticated, multi-tenant web\nUI, available as a separate enterprise offering. Contact ThirdKey for access.\n\n---\n\n## Pipeline stages\n\n| # | Stage | Type | Output |\n|---|-------|------|--------|\n| 1 | `cartographer` | tree-sitter | `repo_facts`, `symbol_index`, `routes`, `dataflow_edges`, code-chunk LanceDB index |\n| 2 | `specifier` | canonical JSON + Ed25519 | `threat_models` row (sources, sinks, scope, signature) |\n| 3 | `static_hunter` | docker exec into sidecars | `findings` rows with `Citation::Analyzer` per scanner |\n| 4 | `taint_tracer` | mechanical BFS (no LLM) | `taint_chains` rows (source→sink paths) |\n| 5 | `pattern_scout` | LLM (Symbiont ORGA loop) | `findings` rows with `Citation::Code` / `Citation::Hypothesis` |\n| 6 | `chain_builder` | LLM | `attack_chains` rows mapping to 7-stage Agent Kill Chain |\n| 7 | `poc_forge` | LLM + language-specific sandbox | `findings.poc_status` ∈ {reproduced, refuted, inconclusive, reproduced_by_citation} |\n| 8 | `devils_advocate` | LLM (inverted prompt, read-only, witness-gated) | `findings.advocate_verdict` ∈ {confirmed, rebutted, uncertain} — rebuttals require a structural witness |\n| 9 | `reflector` | LLM | `knowledge_triples` rows (cross-engagement recall substrate) |\n\nFollowed by `codered report` (deterministic Rust; no LLM) which renders SARIF + Markdown + signed seed.\n\n**Taint, in context.** A *source* is where untrusted input enters (HTTP params, request bodies, CLI args, env, file reads); a *sink* is an operation that's dangerous with untrusted input (SQL query, shell exec, file path, deserializer, HTML output). The `taint_tracer` does a mechanical BFS over the cartographer's `dataflow_edges` from each source to each sink the specifier pinned — an unsanitized source→sink path becomes a `TaintChain` (SQLi, command injection, path traversal, SSRF, XSS, …). Those chains are the structural *witness* a finding must cite: reachability proof, not just a risky-looking code shape.\n\n---\n\n## Development\n\n```bash\n# Build + test:\ncargo build  -j2 --workspace\ncargo test   -j2 --workspace\ncargo clippy -j2 --workspace --all-targets -- -D warnings\n\n# Boot test (builds + smokes orchestrator + python sidecars):\n./tests/boot_test.sh\n\n# Boot test with all multi-lang sidecar builds (slow, ~20min):\nSYMBI_BOOT_TEST_MULTILANG=1 ./tests/boot_test.sh\n\n# Live e2e (requires ANTHROPIC_API_KEY + running sidecars):\ncargo test -j2 -p symbi-codered-cli --test plan_g_e2e -- --ignored\n```\n\n### Adding a new scanner\n\n1. Drop a Dockerfile + scanner-runner.py in `scanners/\u003cname\u003e/`\n2. Add a service to `docker-compose.yml`\n3. Add output parser at `crates/symbi-codered-tools/src/scanner_parsers/\u003cname\u003e.rs`\n4. Add ToolClad manifest at `tools/\u003cname\u003e.clad.toml` + bump `toolclad_load` count\n5. Add a `ScannerJob` entry in `crates/symbi-codered-tools/src/static_hunter.rs`\n\n### Adding a new language\n\nSame as new scanner, plus:\n\n6. Add the language to `SupportedLanguage` in `crates/symbi-codered-tools/src/tree_sitter_loader.rs`\n7. (optional) Extend `dataflow.rs` with `extract_\u003clang\u003e_edges`\n8. Add per-language source/sink defaults to `crates/symbi-codered-tools/src/specifier.rs`\n9. Add a per-language sandbox in `scanners/\u003clang\u003e-sandbox/` and wire poc_forge dispatch\n\n---\n\n## Governance + trust\n\nEverything that touches a finding or a tool call is policy-gated and audited. See:\n\n- [`policies/citation.cedar`](policies/citation.cedar) — every store_finding requires ≥1 citation\n- [`policies/evidence.cedar`](policies/evidence.cedar) — every store_finding requires a specifier_hash + non-empty envelope_id\n- [`policies/tool-authorization.cedar`](policies/tool-authorization.cedar) — per-agent permits + the `devils-advocate-forbids-store` invariant\n- [`policies/advocate.cedar`](policies/advocate.cedar) — a `rebutted` advocate verdict requires a structural witness (suppression is witness-bound, symmetric with finding creation)\n- [`policies/handoff.cedar`](policies/handoff.cedar) — which findings are eligible for the redteam handoff (advocate-confirmed/uncertain, citation-bearing, severity ≥ medium, poc not refuted; `inconclusive` is **not** dropped — a non-test is not a disproof)\n- [`policies/step-up.cedar`](policies/step-up.cedar) — actions requiring out-of-band approval\n- [`policies/phase-gates.cedar`](policies/phase-gates.cedar) — ordering constraints between stages\n- [`policies/reflector.cedar`](policies/reflector.cedar) — reflector's capability surface\n\nThe audit journal at `.symbiont/audit/audit.jsonl` records every tool invocation with its Cedar decision and chains entries via SHA-256. `audit::verify_chain` proves the journal hasn't been tampered with.\n\n---\n\n## License\n\nThe codered **core** — the analysis engine and CLI (`carto`, `hunt`, `audit`,\n`specifier`, `advocate`, `report`, `export-grc`) plus the `agents/`, `policies/`,\n`tools/`, and `scanners/` definitions — is licensed under the\n[Apache License 2.0](LICENSE). Copyright © ThirdKey.\n\nSome additional features, including the multi-tenant **client portal**, are a\nseparate **enterprise** offering and are **not** covered by this license.\nContact ThirdKey for enterprise licensing.\n\n### Building\n\nThe core depends on the [Symbiont](https://github.com/ThirdKeyAI/Symbiont)\nruntime (`symbi-runtime`), pulled from crates.io — no extra setup required:\n\n```bash\ncargo build -j2\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthirdkeyai%2Fsymbi-codered","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthirdkeyai%2Fsymbi-codered","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthirdkeyai%2Fsymbi-codered/lists"}