[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-94967":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":13,"contributorsCount":13,"subscribersCount":13,"size":13,"stars1d":13,"stars7d":15,"stars30d":15,"stars90d":13,"forks30d":13,"starsTrendScore":13,"compositeScore":16,"rankGlobal":10,"rankLanguage":10,"license":17,"archived":18,"fork":18,"defaultBranch":19,"hasWiki":20,"hasPages":18,"topics":21,"createdAt":10,"pushedAt":10,"updatedAt":22,"readmeContent":23,"aiSummary":24,"trendingCount":13,"starSnapshotCount":13,"syncStatus":14,"lastSyncTime":25,"discoverSource":26},94967,"Airsec","bas3line\u002FAirsec","bas3line","Find Security Issues in your code by using coding CLIs like Claude, Codex & CommandCode","",null,"TypeScript",127,0,2,16,49.6,"MIT License",false,"main",true,[],"2026-08-24 04:01:23","\u003Cdiv align=\"center\">\n\n# airsec\n\n**State-of-the-art security review, driven by the coding CLI you already have.**\n\nClaude Code · Codex · OpenCode · Command Code\n\n[![ci](https:\u002F\u002Fgithub.com\u002Fbas3line\u002FAirsec\u002Factions\u002Fworkflows\u002Fci.yml\u002Fbadge.svg)](https:\u002F\u002Fgithub.com\u002Fbas3line\u002FAirsec\u002Factions\u002Fworkflows\u002Fci.yml)\n[![license: MIT](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Flicense-MIT-blue.svg)](LICENSE)\n[![node](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fnode-%E2%89%A520-brightgreen.svg)](#requirements)\n\n\u003C\u002Fdiv>\n\nNo new API key. No cloud upload. No third-party scanner. airsec drives the agent already installed on\nyour machine through a structured, multi-pass security audit, then turns the result into a report you\ncan act on.\n\n---\n\n## Quick start\n\n```bash\nnpx airsec@latest init\n```\n\nThat is the whole thing. `init` walks you through it: pick the folder, pick your coding CLI, pick the\nmodel, choose review-or-fix, and it runs.\n\n\u003Cdetails>\n\u003Csummary>\u003Cb>Other ways to install\u003C\u002Fb>\u003C\u002Fsummary>\n\n```bash\nnpm  install -g airsec      # global\npnpm add    -g airsec\nbun  add    -g airsec\nyarn global add airsec\n\nairsec init                 # then run it anywhere\n```\n\nNo `curl | sh` installer, deliberately: a tool that audits your code for supply-chain risk should not\nask you to pipe a URL into a shell.\n\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>\u003Cb>Getting \u003Ccode>ETARGET · No matching version found\u003C\u002Fcode>?\u003C\u002Fb>\u003C\u002Fsummary>\n\nYour npm is pointed at a mirror that has not synced the release yet. Check with `npm config get\nregistry` — if it is anything other than `https:\u002F\u002Fregistry.npmjs.org`, either wait for the mirror to\ncatch up or bypass it:\n\n```bash\nnpx --registry=https:\u002F\u002Fregistry.npmjs.org airsec@latest init   # one-off\nnpm config set registry https:\u002F\u002Fregistry.npmjs.org             # permanently\n```\n\n\u003C\u002Fdetails>\n\n### Requirements\n\n- **Node ≥ 20** (the published bundle has zero runtime dependencies)\n- **At least one supported coding CLI** on your `PATH` — check with `npx airsec harness`\n\n### 60 seconds, end to end\n\n```bash\nnpx airsec harness            # 1. what coding CLIs can airsec see?\nnpx airsec@latest init        # 2. guided setup — writes .airsec\u002Fconfig.json, then runs\nnpx airsec report --format html > report.html   # 3. share the result\nnpx airsec fix --severity high                  # 4. remediate the worst of it\n```\n\n## Why this instead of a scanner\n\nPattern scanners find what patterns catch. An agent that reads your code can follow a tainted value\nthrough three helpers and a middleware layer and tell you whether the sink is actually reachable.\nairsec supplies the missing part: a rigorous process around that agent.\n\n- **Reconnaissance first.** The attack surface is mapped — entrypoints, trust boundaries, sensitive\n  assets — before any vulnerability hunting starts, and that map is fed into every later pass.\n- **Fourteen focused audit modules** instead of one \"find bugs\" prompt, so injection analysis is not\n  competing for attention with IaC review.\n- **Multiple search strategies per module.** Forward taint analysis, reverse sink analysis,\n  goal-oriented attack, and invariant enforcement each find things the others miss.\n- **Adversarial verification.** Every finding is handed to independent reviewers whose job is to\n  refute it. Findings that lose the vote are dropped, and you see how many were.\n- **Deterministic scoring and merge.** Deduplication, severity weighting, and the aggregate risk\n  score are plain code, not another model call.\n\n## Supported coding CLIs\n\nRun `airsec harness` to see which of these are installed and what models each offers.\n\n| Harness | id | Install |\n|---|---|---|\n| Claude Code | `claude` | `npm i -g @anthropic-ai\u002Fclaude-code` |\n| Codex | `codex` | `npm i -g @openai\u002Fcodex` |\n| OpenCode | `opencode` | `npm i -g opencode-ai` |\n| Command Code | `commandcode` | `npm i -g command-code` |\n| Gemini CLI | `gemini` | `npm i -g @google\u002Fgemini-cli` — experimental adapter |\n| Cursor Agent | `cursor` | `curl https:\u002F\u002Fcursor.com\u002Finstall -fsS \\| bash` — experimental adapter |\n| Crush | `crush` | `npm i -g @charmland\u002Fcrush` — experimental adapter |\n\nThe first four are built against headless flags verified against the real CLIs, and each is tested\nend to end in both directions — audit (read-only) and fix (write). The ones marked experimental are\nbest-effort: they are [overridable](#overriding-a-harness) from config without touching the source.\n\n### Models are discovered, not hardcoded\n\nModel ids change every few months. airsec never ships a versioned id that can rot into a wrong\ndefault, so `airsec harness --models \u003Cid>` asks your machine instead:\n\n| Harness | Where the list comes from |\n|---|---|\n| OpenCode | `opencode models` — the live list, hundreds of entries |\n| Command Code | `cmd --list-models` — the live list with descriptions |\n| Claude Code | your `~\u002F.claude\u002Fsettings.json` model, plus the `opus`\u002F`sonnet`\u002F`haiku` aliases, which resolve to the current model by design |\n| Codex | the `model` in your `~\u002F.codex\u002Fconfig.toml`, including profiles |\n\nA probe command is only ever one verified to list models. Guessing is unsafe: several of these CLIs\ntreat an unrecognised subcommand as a *prompt*, so a wrong guess would bill you for a model call\ninstead of printing a list. Where no list exists, the wizard offers \"harness default\" plus free-text\nentry — always correct, never stale.\n\n## Usage\n\n### Guided\n\n```bash\nnpx airsec init          # asks: which folder, which CLI, which model, review or fix\nnpx airsec init ..\u002Fapi   # start on a specific path\n```\n\nThe wizard writes `.airsec\u002Fconfig.json`, so every later run is a bare `airsec scan`.\n\n### Non-interactive\n\n```bash\nairsec scan                                      # uses .airsec\u002Fconfig.json, or sensible defaults\nairsec scan ..\u002Fapi --depth paranoid\nairsec scan --harness codex --model gpt-5.1-codex-max\nairsec scan --modules injection,authn-authz,secrets --min-severity medium\nairsec scan --quiet --reports sarif --fail-on high --require-complete   # CI shape\n```\n\nExit codes only matter when something automated is watching — a CI pipeline decides pass or fail\nfrom this number. Running airsec yourself, you can ignore them; the wizard does not ask about them\nfor that reason.\n\n| Exit | Meaning |\n|---|---|\n| `0` | No finding at or above `--fail-on` |\n| `1` | airsec itself failed — bad config, harness missing, unreadable target |\n| `2` | A finding at or above `--fail-on` (default `high`) survived verification |\n| `3` | An audit pass did not finish, and `--require-complete` was set |\n\n`--fail-on` sets the bar: `--fail-on critical` fails a build only on critical findings,\n`--fail-on none` never fails it. It changes nothing about the scan or the report.\n\n**Coverage can be partial, and that is not the same as clean.** If a harness invocation times out or\nerrors, airsec records it, finishes the remaining passes, and reports the run — but the areas that\npass covered were never reviewed. Both the terminal output and `report.md` lead with a warning when\nthis happens, `summary.incompletePasses` carries it in JSON, and `--require-complete` turns it into\na build failure. Never read a partial run as a clean bill of health.\n\nParallel sessions of the same coding CLI contend for one rate limit, and a stalled session burns the\nfull `--timeout` (default 900s) before giving up. Concurrency 5 against Claude Code lost 5 of 14\npasses to timeouts in testing; the default of 3 is deliberately conservative. If you see timeouts,\nlower `--concurrency` before raising `--timeout`.\n\n### Fixing\n\n```bash\nairsec fix                        # pick findings from the last review interactively\nairsec fix --all --severity high  # remediate everything high and above\n```\n\nFixes are applied to your working tree, one finding at a time — sequentially on purpose, because\nparallel agents editing overlapping files produce conflicting writes. Review the diff before you\ncommit; airsec never commits for you.\n\nEach fix is scoped to one finding, so a change that alters a function's contract can leave a caller\nin another file out of step. The remediation prompt tells the agent to follow the change across file\nboundaries, but weaker models do not always manage it — run your tests after `fix`, always.\n\n### Reports\n\nEvery run is stored under `.airsec\u002Fruns\u002F\u003Ctimestamp>-\u003Cid>\u002F` with the formats you configured.\n\n```bash\nairsec report                        # re-print the last review\nairsec report --format html > out.html\nairsec report --format sarif > out.sarif\n```\n\nSARIF uploads straight to GitHub code scanning.\n\n## Depth\n\n| Depth | Lenses per module | Verifiers per finding | File budget |\n|---|---|---|---|\n| `quick` | 1 | 0 | 600 |\n| `standard` | 1 | 1 | 2,000 |\n| `deep` *(default)* | 2 | 2 | 6,000 |\n| `paranoid` | 3 | 3 | 20,000 |\n\nCost scales roughly with `modules × lenses`, plus one verification call per finding per verifier.\nStart at `quick` on a new codebase to calibrate before committing to `paranoid`.\n\n## Audit modules\n\n`airsec modules` prints these with their CWE and OWASP mappings.\n\n**Core (default):** `injection` · `authn-authz` · `secrets` · `crypto` · `input-validation` ·\n`ssrf-network` · `xss-frontend` · `path-file` · `supply-chain` · `infra-config`\n\n**Extended (opt in):** `api-surface` · `logic-race` · `llm-agentic` · `privacy-compliance`\n\n## Configuration\n\n`.airsec\u002Fconfig.json`:\n\n```json\n{\n  \"version\": 1,\n  \"target\": \"\u002Fabs\u002Fpath\u002Fto\u002Frepo\",\n  \"harness\": \"claude\",\n  \"model\": \"opus\",\n  \"depth\": \"deep\",\n  \"modules\": [\"injection\", \"authn-authz\", \"secrets\"],\n  \"concurrency\": 3,\n  \"timeoutMs\": 900000,\n  \"retries\": 1,\n  \"verify\": true,\n  \"minSeverity\": \"low\",\n  \"exclude\": [\"fixtures\u002F\", \"generated\u002F\"],\n  \"reports\": [\"markdown\", \"json\", \"sarif\"],\n  \"failOn\": \"high\",\n  \"harnesses\": {}\n}\n```\n\n`exclude` entries are case-insensitive substring matches against each path relative to the target —\nnot globs. `\"generated\u002F\"` drops the directory; `\".test.\"` drops test files anywhere.\n\n### Overriding a harness\n\nWhen a CLI changes its headless flags, fix it in config rather than waiting for a release. Tokens\n`{{prompt}}`, `{{system}}`, `{{model}}` and `{{cwd}}` are substituted per invocation; an argument\nwhose token has no value is dropped along with its flag.\n\n```json\n{\n  \"harnesses\": {\n    \"gemini\": {\n      \"bin\": \"gemini\",\n      \"promptVia\": \"stdin\",\n      \"args\": {\n        \"read\": [\"--model\", \"{{model}}\", \"--output-format\", \"text\"],\n        \"write\": [\"--model\", \"{{model}}\", \"--yolo\"]\n      }\n    }\n  }\n}\n```\n\n## How a run works\n\n```\ninventory   walk the tree, detect stack, rank security-relevant paths   (deterministic)\n    ↓\nrecon       one pass: entrypoints, trust boundaries, sensitive assets   (1 call)\n    ↓\naudit       modules × lenses, run concurrently                          (m × l calls)\n    ↓\nmerge       fingerprint by location, corroborate by title overlap       (deterministic)\n    ↓\nverify      independent reviewers try to refute each finding            (f × v calls)\n    ↓\nscore       severity × confidence × verdict × corroboration             (deterministic)\n    ↓\nreport      terminal · markdown · json · sarif · html\n```\n\n## Development\n\n```bash\nbun install\nbun run dev -- scan .\u002Ffixture --depth quick   # run from source\nbun run check                                 # lint + typecheck + test, what CI runs\nbun run format                                # apply Biome fixes\nbun run build                                 # bundle to dist\u002Fcli.js, node-compatible\n```\n\nBun is the toolchain; the published bundle targets Node ≥ 20 so `npx airsec` works anywhere. Biome\nenforces formatting and lint, `tsc --strict` enforces types, and CI runs all three plus the packaged\nbinary on every push.\n\n**Extending it.** A new harness is one file in `src\u002Fharness\u002Fadapters\u002F` plus a line in `registry.ts` —\nor zero code, via a [config override](#overriding-a-harness). A new audit module is one entry in\n`src\u002Faudit\u002Fcatalog.ts`. A new report format is one entry in `src\u002Freport\u002Findex.ts`.\n\n```\nsrc\u002F\n  audit\u002F      what to look for — module catalog, search lenses, prompts, output schema\n  core\u002F       the pipeline — inventory, recon, fan-out, merge, verify, score, trust boundary\n  harness\u002F    how to talk to each coding CLI — adapters, process exec, JSON extraction\n  report\u002F     terminal · markdown · json · sarif · html\n  ui\u002F         wizard prompts, progress, banner\n  util\u002F       fs, json recovery, hashing, redaction, logging\n```\n\n## Security model\n\nairsec is pointed at code you may not trust, so it treats the target directory as hostile input.\n\n**Config from the target is not trusted to decide what runs.** `.airsec\u002Fconfig.json` lives inside\nthe directory under review. Its `harnesses` block names an executable and its argv, so honouring it\nfrom a repository you just cloned would be remote code execution. That block is ignored by default,\nwith a warning, and applied only when you pass `--trust-config` on the command line — somewhere the\nrepository cannot reach. Everything else in the file only decides what gets read, and is applied\nnormally.\n\n**Audit passes cannot execute commands or reach the network.** The repository under review is\nattacker-controlled input to a model, so injected instructions in a README or a code comment must\nnot be able to reach a shell (remote code execution) or the network (exfiltration of the source\nbeing reviewed). Reconnaissance, auditing and verification run with only the tools an audit needs —\nopen a file, search, list.\n\nFor Claude Code that means `Bash`, `WebFetch`, `WebSearch` and `Task` are denied alongside the\nediting tools; `Task` because a subagent could otherwise be spawned with the tools just removed.\nCodex runs under `--sandbox read-only`, OpenCode under its `plan` agent, Command Code under\n`--permission-mode plan`. Write access is granted only by `airsec fix`, and even then network tools\nstay denied.\n\nThis is verified rather than assumed: a fixture repository carrying prompt-injection text in its\nREADME and source is scanned as part of testing, and the injected command does not run.\n\n**Discovered credentials are masked in stored output.** A secrets finding would otherwise copy a\nlive credential into `report.md`, `report.json` and `report.sarif` — files that get committed and\npasted into tickets. High-entropy tokens are masked to `sk_l…redacted…4c` across every text field of\na finding, not just the code snippet: models routinely spell the same credential out again in the\nexploit narrative as a URL parameter. The credential stays identifiable, and the file, line, and\nexploit path are untouched. Add `.airsec\u002F` to your `.gitignore` regardless.\n\nThese properties are covered by `test\u002Fsecurity.test.ts`.\n\n## Caveats\n\n- airsec runs your coding CLI, so it spends that CLI's quota and inherits its permissions. Audit\n  passes are launched read-only; `fix` is the only mode that grants write access.\n- Findings are produced by a language model. Verification removes a lot of noise, but treat the\n  output as a strong prioritised lead list, not a proof.\n- A clean report is not a security guarantee. It is one pass by one reviewer.\n- Findings are stored under `.airsec\u002Fruns\u002F`. Keep that directory out of version control.\n\n## License\n\nMIT\n","Airsec 是一个本地化代码安全审计工具，通过调用用户本机已安装的编程类大模型 CLI（如 Claude Code、Codex、Command Code）执行结构化、多阶段的安全审查。其核心特点是无需上传代码、不依赖云端 API 或第三方扫描器，支持攻击面测绘、14 个专注模块（如注入分析、IaC 审查）及前向污点追踪等深度分析策略，并可生成可操作报告或自动修复高危问题。适用于开发人员在 CI\u002FCD 前、代码提交后或安全自查等轻量级、隐私敏感的本地安全评审场景。","2026-08-19 02:30:03","CREATED_QUERY"]