Stelnyx/apigate
GitHub: Stelnyx/apigate
ApiGate 是静态 API 表面审计工具,通过源代码和规范分析解决端点暴露及认证覆盖问题,生成确定性报告。
Stars: 0 | Forks: 0
**ApiGate** 是 Stelnyx 系列中的第四款表面审计工具 ([LuxScope](https://github.com/Stelnyx/LuxScope),[LuxFaber](https://github.com/Stelnyx/LuxFaber),[SecGate](https://github.com/Stelnyx/SecGate),**ApiGate**)。它读取磁盘上的源代码和 OpenAPI 规范,并生成一份报告:包含每个端点、其声明的认证姿态、代码与规范之间的差异,并根据五个 0-100 分的评分标准进行打分。**100% 静态** — 无 HTTP 请求、无凭证、无运行中的服务器。零网络调用。相同输入 → 字节级一致的输出。
**诚实的定位。** ApiGate 是一款**表面审计器**,而非运行时扫描器,也非 DAST 工具。报告明确指出了静态分析**能够**和**不能**证明什么——这是一个可打印的信任特性,而非脚注。ApiGate 无法验证运行时授权(BOLA / 对象级访问)。它可以证明某个端点声明了守卫。它无法证明该守卫是正确的。参见[此工具无法证明的内容](#what-this-does-not-prove)。
**状态。** 早期版本 (`v0.3.0`)。通过 [npm provenance](https://docs.npmjs.com/generating-provenance-statements) 发布。漏洞请通过 [SECURITY.md](SECURITY.md) 报告。
**准确性契约。** ApiGate 的解析 + 评分管道是确定性的——相同输入在每次运行中生成 JSON 和 HTML 字节级一致的报告。三个测试套件锁定了该契约:
- `test/determinism.mjs` — 跨所有解析器、分类器、差异比较、评分和渲染调用的重新运行,确保 JSON 和 HTML 的字节相等性。
- `test/golden-apigate.mjs` — 手工制作的多框架测试夹具;预期的端点数量、姿态分布、差异桶和总分都在代码中内联,因此任何更改都会在代码审查中显现。
- `test/report-theme-contract.mjs` — 断言 HTML 报告是通过 `@stelnyx/report-theme` 渲染的,而非通过并行的本地渲染器。
## 总分
每次运行都会生成一个 **总分 (0-100)** 和一个二元的通过/失败门控。该分数是五个 0-100 评分标准的算术平均值:
```
Headline: 86 / 100 █████████████████░░░ STRONG rubric v1
Inventory 86 / 100 █████████████████░░░
Auth Coverage 67 / 100 █████████████░░░░░░░
Open Risk 85 / 100 █████████████████░░░
Spec Drift 90 / 100 ██████████████████░░
Determinism 100 / 100 ████████████████████
```
| 评分标准 | 衡量内容 |
|---------------------|--------------------------------------------------------------------------------------------------------|
| **清单解析率** | `100 × 已解析 / 总数`。通过动态前缀挂载的路由会拉低此项——不会被静默丢弃。 |
| **认证覆盖度** | `100 × 已守卫 / (已守卫 + 开放 + 未知)`。未知项计入负面——一个我们无法分类的路由不是确认已守卫的端点。有意公开的端点(登录/注册/刷新/健康检查/...)被排除——它们被声明为设计上公开,不是覆盖度缺口。 |
| **开放端点风险** | 从 100 开始。开放的写方法(POST/PUT/PATCH/DELETE)每个 `-12`;开放的 GET 每个 `-3`。下限为 0。 |
| **规范漂移** | 从 100 开始。影子 `-5`,陈旧 `-5`,认证漂移每项 `-10`。当未找到规范时为 `null`(不计入平均值)。 |
| **确定性** | 在 v0.1 中锁定为 100。字节相等性测试是实际执行它的部分。 |
评分等级:`STRONG ≥ 85`,`GOOD ≥ 70`,`MIXED ≥ 50`,`WEAK < 50`。与 SecGate / LuxFaber / LuxScope 使用相同的等级。
二元门控(在开放写方法时退出码为 1,可配置)独立于分数。`headlineScore` + `rubrics` 被写入 `apigate-report.json`,供 CI 仪表板和趋势跟踪使用。
## 摘要
```
npx @stelnyx/apigate .
```
清点每个 HTTP 端点,分类认证姿态,与任何 OpenAPI 规范进行差异比较,输出 JSON 报告 + 一个自包含的 HTML 报告。干净时退出 `0`,存在开放写端点时退出 `1`(默认策略)。这就是整个产品。
## 当前功能
ApiGate 遍历目录中的源文件并生成:
- **一份标准化的 JSON 报告** — 每个端点、姿态、差异桶、评分标准、总分
- **一份自包含的 HTML 报告** — 通过 `@stelnyx/report-theme` 渲染;在视觉和结构上与 SecGate / LuxScope / LuxFaber 报告完全相同
- **一个退出码** — 存在开放写端点时退出 `1`(可配置);用于阻塞 CI
ApiGate 不运行代码。它不发送 HTTP 请求。它不需要凭证或运行中的服务器。一切都在解析时基于源文件发生。
## 框架支持
| 框架 | 检测方式 |
|------------|--------------------------------------------------------------------------------------------------------------------------|
| **Express** | 对 `.js/.mjs/.cjs` 使用 acorn AST;对 `.ts/.tsx` 使用正则表达式回退。解析同一文件中的 `app.use('/prefix', router)` 挂载。 |
| **Fastify** | acorn AST。处理 `fastify.(...)` 和 `fastify.route({ method, url, preHandler })`。 |
| **NestJS** | 对 `.ts/.js` 进行装饰器提取。将 `@Controller(...)` 与方法装饰器 `@Get / @Post / @Put / @Patch / @Delete / @Options / @Head / @All` 配对。捕获类和方法级别的守卫(`@UseGuards`、`@Auth`、`@Roles`、`@ApiBearerAuth`)。 |
| **OpenAPI** | 解析 `*.yaml`/`*.yml`/`*.json` 文件,要求根对象为 `swagger:` (2.0) 或 `openapi:` (3.x)。遵循操作级别的 `security` 和根级继承。 |
无法静态解析的路由(动态挂载前缀、计算方法名、无法解析的文件)被标记为 `UNRESOLVED`——绝不会猜测。它们计入**清单解析率**评分标准,因此报告会告诉您 ApiGate 能够和不能看到什么。
## 网络访问
ApiGate **零**网络调用。无遥测、无账户、无回拨、无建议数据库、无从 URL 获取规范。报告仅写入本地文件。代码永远不会离开您的机器。
这是无条件的,不是标志。离线 CI 与开发人员笔记本电脑一样有效。
## 此工具无法证明的内容
ApiGate 的诚实之楔。报告在每次运行中都会呈现此部分,绝不会隐藏在开关之后:
1. **静态分析无法验证运行时授权(BOLA / 对象级访问)。** ApiGate 仅检查声明的认证姿态,而非认证中间件本身的正确性。
2. 在端点的中间件链中具有已声明认证标识符的端点被分类为 `GUARDED`——该中间件在运行时仍可能被错误配置、可绕过或不安全。
3. 通过动态字符串挂载的路由(计算前缀、运行时注册、工厂函数)被报告为 `UNRESOLVED` 而非猜测。
4. ApiGate 使用内置的启发式模式列表将常见的公开认证路径(登录 / 注册 / 刷新 / 健康检查 / OAuth 回调)标记为 **有意公开**。该启发式是确定性和可配置的,但两种方式都可能出错——请审查标记的端点,并在您的项目不同意时在 `.apigate.config.json` 中覆盖 `publicAuthPatterns`。
5. ApiGate 零网络调用。它不会将代码、遥测数据或扫描产物发送到任何地方。
如果您需要运行时授权测试(BOLA、IDOR、破损的对象级认证),请使用动态扫描器。ApiGate 是 DAST 工具的补充;它不替代 DAST 工具。
### 启发式姿态:设计上公开
大多数 API 有意公开少量未认证端点——注册、登录、刷新、密码重置、OAuth 回调、健康探测。如果没有帮助,ApiGate 的 `openWriteMethods: true` 默认设置会在首次运行时将这些全部标记为失败。
ApiGate 附带一个确定性的、精确匹配这些模式的列表(见 `lib/heuristics.mjs` → `DEFAULT_PUBLIC_AUTH_PATTERNS`)。被列表匹配的端点:
- **保留在清单中**——它们永远不会被隐藏。
- **保留其声明的姿态**(OPEN / UNKNOWN)——该启发式不会对代码的说法撒谎。
- **被排除在默认的退出-1 门控之外。**
- **被排除在认证覆盖度的分母之外。**
- 在 HTML 报告中被标记为 `PUBLIC`(附加于其姿态)。
覆盖模式列表:
```
{
"publicAuthPatterns": [
{ "method": "POST", "path": "/api/v2/auth/login" },
{ "method": "GET", "path": "/api/v2/auth/google/callback" }
]
}
```
`[]` 会完全禁用该启发式(每个开放端点都计入)。
`failOn.intentionalPublic: true` 保留报告中的启发式,但使这些端点无法通过门控(严格/合规模式)。
## 安装
### 通过 npm(推荐)
```
npm install -g @stelnyx/apigate
```
### 通过 npx 一次性使用
```
npx @stelnyx/apigate .
```
### 从源码安装
```
git clone https://github.com/Stelnyx/ApiGate.git
cd ApiGate
npm install
chmod +x apigate.js
sudo ln -sf "$(pwd)/apigate.js" /usr/local/bin/apigate
```
## 用法
```
# 扫描当前目录
apigate .
# 扫描特定路径
apigate /path/to/project
# 将报告写入自定义目录
apigate /path/to/project --output-dir /tmp/reports
# 去除绝对路径(当 CI=true 时自动开启)
apigate /path/to/project --strip-paths
# 仅 JSON / 仅 HTML
apigate . --format json
apigate . --format html
# 显示解析器警告
apigate . --debug
# PR 感知:此分支是否引入了新的未认证路由?
apigate . --diff main
# 收窄可见端点表格(仅查看——不影响退出代码)
apigate . --filter risk=HIGH,posture=OPEN
# 打印某个端点的证据链(不写入文件,退出代码为 0)
apigate . --explain GET /audit/security-events
# 在 CI 时收紧网关,无需编辑 .apigate.config.json
apigate . --fail-on open-write,unknown,drift,missing-spec,new-open-write
# 适用于 CI 的字节稳定时间戳(符合 SOURCE_DATE_EPOCH 规范)
APIGATE_TIMESTAMP="$(date -u +%Y-%m-%dT%H:%M:%SZ)" apigate .
# 版本 / 帮助
apigate --version
apigate --help
```
**`--fail-on` 标记**(逗号分隔):
| 标记 | 映射到 |
|----------------------|------------------------------------------|
| `open-write` | `failOn.openWriteMethods = true` |
| `open-read` | `failOn.openReadMethods = true` |
| `unknown` | `failOn.unknown = true` |
| `drift` | `failOn.drift = true` |
| `intentional-public` | `failOn.intentionalPublic = true` |
| `new-open-write` | `failOn.newOpenWrite = true`(需要 `--diff`) |
| `missing-spec` | `requireSpec = true` |
未知标记会抛出错误——CI 中的拼写错误永远不会悄悄放松策略。
**`--filter` 语法:**
```
key=value
key=v1|v2 # OR within a key
key1=v1,key2=v2 # AND across keys
```
键:`risk`(HIGH|MED|LOW),`posture`(GUARDED|OPEN|UNKNOWN),`framework`
(express|fastify|nest|openapi),`method`(任何 HTTP 方法),`changed`
(added|removed|changedPosture|changedRisk — 需要 `--diff`)。
**退出码**
| 代码 | 含义 |
|:----:|------------------------------------------------------------------|
| `0` | 通过 — `gate.reasons` 为空 |
| `1` | 失败 — `gate.reasons[]` 列出了触发的确切门控条件 |
| `2` | 无效目标或 CLI 错误 |
JSON 报告中的 `gate.reasons[]` 数组包含锁定的枚举集
(`drift`,`intentional-public`,`missing-spec`,`open-read`,`open-write`,
`unknown-endpoint`),按字典序排序并去重,因此 CI 可以
grep 失败原因而无需解析标准输出。
## 配置
在您的扫描目标目录中创建 `.apigate.config.json`。所有字段都是可选的。
```
{
"frameworks": {
"express": true, "fastify": true, "nest": true, "openapi": true
},
"auth": {
"express": ["requireAuth", "passport.authenticate", "jwt"],
"fastify": ["onRequest", "preHandler", "fastify.authenticate"],
"nest": ["UseGuards", "AuthGuard", "JwtAuthGuard"]
},
"failOn": {
"openWriteMethods": true,
"openReadMethods": false,
"unknown": false,
"drift": false,
"intentionalPublic": false
},
"requireSpec": false,
"strictPublic": false,
"excludePaths": ["node_modules/**", "dist/**", "**/*.test.*"]
}
```
一个带完整注释的示例配置文件位于 [`.apigate.config.example.json`](.apigate.config.example.json) — 将其复制到您的仓库中作为 `.apigate.config.json` 并进行编辑。
### 字段参考
| 字段 | 类型 | 默认值 | 描述 |
|---------------|---------|----------------------------------------|-----------------------------------------------------------------------------|
| `frameworks` | object | 全部为 `true` | 切换单个解析器 |
| `auth` | object | 按框架的默认值 | 当出现在端点的中间件/装饰器链中时,将其分类为 `GUARDED` 的标识符名称 |
| `failOn` | object | `{ openWriteMethods: true, unknown: false, drift: false }` | 退出码策略 |
| `requireSpec` | boolean | `false` | 当未检测到 OpenAPI 2/3 规范时失败 |
| `strictPublic`| boolean | `false` | 除非设置了 `publicAuthPatterns`,否则禁用内置的公开认证模式 |
| `excludePaths`| array | `node_modules/`、`dist/`、测试目录 | 要跳过的文件 glob 模式 |
### 优先级
```
CLI flag > .apigate.config.json > built-in defaults
```
缺少配置:静默,应用默认值。无效的 JSON:记录错误,应用默认值。
### 认证标识符配置
ApiGate 的分类器在端点的中间件/装饰器链中出现已声明的认证标识符之一时报告 `GUARDED`。默认值涵盖了常见的框架习惯用法(`passport.authenticate`、`@UseGuards`、Fastify `preHandler`)。对于项目特定的助手(例如,自定义的 `requireOrg` 中间件),请扩展列表:
```
{ "auth": { "express": ["requireAuth", "requireOrg", "requireBilling"] } }
```
ApiGate **不**检查这些标识符在运行时的作用。它们的已声明存在是信号——这就是静态分析的诚实契约。
## 自食其果
ApiGate 每个版本都会针对四个目标进行扫描。第一个是**确定性测试夹具**(锁定在 100/100——这就是如何证明字节相等性)。其余是真实的公共/生产代码库——它们的数字随着每次扫描而变化,因为代码库在变化。
| 目标 | 框架 | 端点数 | 总分 | 角色 |
|---|---|---:|---:|---|
| [`samples/realworld-express`](samples/realworld-express/)(供应商版本,SHA 固定) | Express | 20 | **100** | 确定性基线——锁定在 100/100,被 `test/determinism.mjs` 用于字节相等性断言。**不是营销展示。** |
| [`samples/immich-nest`](samples/immich-nest/)(克隆版本,SHA 见 SOURCE 文件) | NestJS | 255 | **64** | 真实公共 NestJS 参考——[Immich](https://github.com/immich-app/immich),约 50K★。183 个已守卫 · 35 个开放 · 14 个高风险。 |
| [`samples/ghost-express`](samples/ghost-express/)(克隆版本,SHA 见 SOURCE 文件) | Express | 303 | **66** | 真实公共 Express 参考——[Ghost](https://github.com/TryGhost/Ghost),约 50K★。演示了 `auth.express` 的自定义。 |
| slstudio(私有) | NestJS | 423 | **70** | 私有生产参考。330 个已守卫 · 96 个开放 · 52 个高风险。 |
**数字说明了什么。**
- `nest-realworld` 100/100 并不意味着 ApiGate "通过了 Nest" ——这意味着我们针对该夹具锁定了字节相等性。
- `immich` 64/100 和 `ghost` 66/100 是对真实代码库根据 ApiGate 默认策略 + 轻量级每仓库配置进行的诚实扫描。两者都有真实的 OPEN 发现值得分类;两者也展示了 `parserCapabilities` 中记录的已知解析器限制(全局守卫模式、项目特定的中间件名称)。
- `slstudio` 70/100 内部版本——首次运行时发现了约 39 个假 GUARDED 端点,其唯一的已声明标记是 `@ApiBearerAuth`(Swagger 文档装饰器)。通过 `matchedAuthMarker` 可在 30 秒内完成审查。
**复现公共扫描:**
```
# Immich
git clone --depth 1 https://github.com/immich-app/immich /tmp/immich
APIGATE_TIMESTAMP="2026-05-20T00:00:00.000Z" \
apigate /tmp/immich/server --strip-paths
# Ghost(需要一个小的 auth.express 扩展——参见 samples/ghost-express/SOURCE.md)
git clone --depth 1 https://github.com/TryGhost/Ghost /tmp/ghost
APIGATE_TIMESTAMP="2026-05-20T00:00:00.000Z" \
apigate /tmp/ghost/ghost/core --strip-paths
```
用于更严格的 CI 门控:
```
{
"failOn": { "unknown": true, "intentionalPublic": true, "newOpenWrite": true },
"requireSpec": true,
"strictPublic": true
}
```
`failOn.unknown` 意味着 "无法证明已守卫" 会导致运行失败。`requireSpec` 防止在没有 OpenAPI 文件时得到绿色的漂移分数。`strictPublic` 会禁用内置的公开认证列表,除非您的仓库提供了 `publicAuthPatterns`。`newOpenWrite`(默认在使用 `--diff` 时开启)在 PR 添加未认证的写端点时失败。
## CI / CD
### GitHub Actions — 最小配置
```
- name: Run ApiGate
run: npx @stelnyx/apigate .
# exits 1 on open write endpoints by default — blocks the pipeline
```
### 非阻塞(仅报告)
```
- name: Run ApiGate
run: npx @stelnyx/apigate . || true
- name: Upload report
uses: actions/upload-artifact@v4
with:
name: apigate-report
path: |
apigate-report.json
*.html
```
## 报告输出
每次运行会写入:
- **`apigate-report.json`** — 机器可读,模式见下文
- **`.html`** — 自包含的 HTML 报告(通过 `@stelnyx/report-theme` 渲染)
### JSON 模式
```
{
"version": "0.3.0",
"rubricVersion": "v1",
"riskVersion": "v1",
"timestamp": "ISO 8601",
"target": "/absolute/path or repo basename",
"mode": "static",
"status": "PASS | FAIL",
"gate": {
"status": "PASS | FAIL",
"reasons": ["drift", "intentional-public", "missing-spec", "new-open-write", "open-read", "open-write", "unknown-endpoint"]
},
"headlineScore": 86,
"rubrics": {
"inventoryResolved": 86,
"authCoverage": 67,
"openEndpointRisk": 85,
"specDrift": 90,
"determinism": 100
},
"summary": {
"endpoints": 7, "resolved": 6, "unresolved": 1,
"guarded": 4, "open": 2, "unknown": 1, "intentionalPublic": 0,
"risk": { "HIGH": 1, "MED": 2, "LOW": 4 },
"specEndpoints": 6, "shadow": 1, "stale": 1, "authDrift": 0,
"unknownReasons": { "mount-prefix-not-static": 1 }
},
"endpoints": [
{
"method": "GET | POST | PUT | PATCH | DELETE | OPTIONS | HEAD | ALL",
"path": "/users/:id",
"file": "src/server.js",
"line": 42,
"framework": "express | fastify | nest | openapi",
"resolved": true,
"posture": "GUARDED | OPEN | UNKNOWN",
"intentionalPublic": false,
"authMarkers": ["requireAuth"],
"matchedAuthMarker": "requireAuth",
"risk": "HIGH | MED | LOW",
"riskReason": "open write method",
"unresolvedReason": null
}
],
"drift": {
"shadow": [{ "kind": "shadow", "method": "POST", "path": "/x", "note": "..." }],
"stale": [{ "kind": "stale", "method": "GET", "path": "/y", "note": "..." }],
"authDrift": [{ "kind": "authDriftDeclaredOnly", "method": "PUT", "path": "/z", "note": "..." }]
},
"refDiff": {
"baseRef": "main",
"baseSha": "abc12345...",
"added": [{ "method": "POST", "path": "/admin/purge", "posture": "OPEN", "risk": "HIGH" }],
"removed": [],
"changedPosture": [{ "method": "PUT", "path": "/x", "from": "GUARDED", "to": "OPEN" }],
"changedRisk": [{ "method": "POST", "path": "/y", "from": "MED", "to": "HIGH" }]
},
"frameworksDetected": ["express", "openapi"],
"specsDetected": ["openapi.yaml"],
"parserCapabilities": {
"express": { "sameFileMountPrefix": true, "crossFileMountPrefix": false, "dynamicMountPrefix": "UNRESOLVED" },
"fastify": { "registerPrefixPropagation": false, "routeOptionsParsed": true },
"nest": { "controllerObjectArg": "path field only", "classLevelGuards": true },
"openapi": { "missingSecurity": "UNKNOWN (conservative)", "operationSecurityEmptyArray": "OPEN" }
},
"riskTier": { "version": "v1", "sensitivePathTokens": 9, "buckets": ["HIGH","MED","LOW"], "overrideHook": "config.severityOverrides" },
"filter": "risk=HIGH,posture=OPEN",
"warnings": [],
"limitations": ["..."]
}
```
### 按版本添加的键
| 添加于版本 | 键 | 原因 |
|---|---|---|
| 0.1.2 | `gate.reasons[]` | 触发的门控的枚举锁定列表。CI grep 目标。 |
| 0.1.2 | `endpoints[].matchedAuthMarker` | 触发 GUARDED 分类的首个已声明标识符。 |
| 0.1.2 | `summary.unknownReasons{}` | 按 `unresolvedReason` 的计数。 |
| 0.1.2 | `parserCapabilities{}` | 每个解析器可见内容与未解析内容的冻结矩阵。 |
| 0.2.0 | `refDiff{}` | 与 git ref 的 PR 感知差异。显示 added / removed / changedPosture / changedRisk。 |
| 0.2.0 | `endpoints[].risk` / `riskReason` | 每个端点的 HIGH/MED/LOW 层级。冻结的 v1 阶梯。 |
| 0.2.0 | `summary.risk{}` | HIGH/MED/LOW 计数。 |
| 0.2.0 | `riskTier{}` + `riskVersion` | 风险阶梯的评分标准版本。 |
| 0.2.0 | `filter` | 生效中的过滤器表达式(仅查看)。 |
| 0.3.0 | `parserCapabilities.nest.methodDecoratorsBelowAnchor` | 现为 `true` — 双向装饰器扫描捕获 `@Get`/`@Post` 上方和下方的标记。 |
| 0.3.0 | `parserCapabilities.nest.globalGuardDetection` | 记录为 `NOT DETECTED` — NestJS `APP_GUARD` / `useGlobalGuards` 提供程序对静态分析不可见。使用 `auth.nest` 覆盖或 `severityOverrides`。 |
| 0.3.0 | LIMITATIONS 条目 #7 | 在每份打印报告中披露全局守卫盲点。 |
### 姿态层级
| 姿态 | 含义 |
|-------------|------------------------------------------------------------------------------------------|
| **GUARDED** | 端点的中间件/装饰器链中至少存在一个已声明的认证标识符 |
| **OPEN** | 端点已解析,无认证标识符存在 |
| **UNKNOWN** | 端点本身未解析,或(规范)无安全块存在 |
### `matchedAuthMarker` 实践——可审查性的体现
`matchedAuthMarker`(在 v0.1.2 中添加)是捕获假 GUARDED 而不改变信任模型的杠杆。分类器仍然在端点的装饰器链中出现任何已声明标识符时将其标记为 GUARDED——但报告现在会准确显示是*哪个*标识符触发了匹配,因此不寻常的标识符会凸显出来。
在 v0.1.2 上针对一个拥有 423 个端点的生产 NestJS 应用进行自食其果的实例:
```
matchedAuthMarker distribution (GUARDED endpoints):
313 ApiBearerAuth ← Swagger documentation decorator
12 UseGuards ← actual runtime guard
2 Roles
```
`@ApiBearerAuth()` 是一个 Swagger 文档装饰器,**不是**运行时守卫。327 个 GUARDED 端点中有 313 个匹配了它。其中大多数仍然受到在 `app.module.ts` 中注册的全局 `APP_GUARD` 的保护(对静态分析不可见——见 `parserCapabilities.nest`),但其中 39 个端点在其装饰器链中根本没有其他守卫标识符。如果没有 `matchedAuthMarker`,这些端点在报告中将是静默的。有了它,审查者就有了一条 30 秒的分类路径。
如果您的代码库想要完全消除误报,请从 `.apigate.config.json` 的 `auth.nest` 中移除 `ApiBearerAuth`。ApiGate 的默认值故意是宽松的(遗漏真实守卫的代价大于 `matchedAuthMarker` 可见的假 GUARDED 的代价)。
## 设计一致性
ApiGate 在视觉和结构上与 SecGate、LuxScope 和 LuxFaber 无法区分。HTML 报告通过 `@stelnyx/report-theme@^0.1.0` 渲染——相同的版本、相同的导入、相同的外壳信封,无分叉,无本地重新样式化。参见 [DESIGN_PARITY.md](DESIGN_PARITY.md) 了解契约。
如果缺少的主题组件阻碍了 ApiGate,解决方案是向 `report-theme` 提交上游 PR,而不是本地修补。这就是四件套货架保持一个产品的方式。
## 文档
| 文档 | 内容 |
|--------------------------------------------------------|--------------------------------------------------------------------------------|
| [`CHANGELOG.md`](CHANGELOG.md) | 版本历史 — 每次版本的 Added / Changed / Fixed |
| [`OPEN-CORE.md`](OPEN-CORE.md) | 开源核心边界和付费扩展路线图 |
| [`DESIGN_PARITY.md`](DESIGN_PARITY.md) | 报告主题消费契约 |
| [`SECURITY.md`](SECURITY.md) | 漏洞报告、SLA、协调披露 |
| [`CONTRIBUTING.md`](CONTRIBUTING.md) | 开发设置、分支 + 提交规范、PR 检查表 |
## 贡献
参见 [`CONTRIBUTING.md`](CONTRIBUTING.md)。根据 [`SECURITY.md`](SECURITY.md) 私下报告漏洞——**请勿为安全报告打开公开议题**。
## 许可证
[MIT](LICENSE) — © Stelnyx
标签:AES-256, API安全, API治理, DevSecOps, Express, Fastify, GNU通用公共许可证, JSON输出, MITM代理, NestJS, Node.js, OpenAPI, 上游代理, 云安全监控, 代码规范, 安全扫描, 安全报告, 工具链, 数据可视化, 时序注入, 漏洞评估, 自定义脚本, 表面审计, 认证检查, 静态分析