From 269289a859197d8d96563cbb80a110cbadac7d24 Mon Sep 17 00:00:00 2001 From: sunlei Date: Sat, 13 Jun 2026 18:52:19 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=8A=A0=E5=9B=BA=E8=BF=90=E8=A1=8C?= =?UTF-8?q?=E6=97=B6=E8=AF=81=E6=8D=AE=E5=87=AD=E6=8D=AE=E8=84=B1=E6=95=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2026-06-13-api-runtime-foundation.md | 5 ++- .../evidence/runtime-evidence.service.ts | 19 +++++++++-- test/runtime/runtime-evidence.service.spec.ts | 32 +++++++++++++++++++ 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/docs/superpowers/plans/2026-06-13-api-runtime-foundation.md b/docs/superpowers/plans/2026-06-13-api-runtime-foundation.md index 8d5745f..fb11313 100644 --- a/docs/superpowers/plans/2026-06-13-api-runtime-foundation.md +++ b/docs/superpowers/plans/2026-06-13-api-runtime-foundation.md @@ -4,6 +4,8 @@ **Goal:** Implement Phase 1 of the approved API runtime foundation: typed runtime config, classified runtime errors, structured runtime evidence, and a lightweight `GET /health/runtime` endpoint that can be used by Jenkins/K8s/ktWorkflow in the next plan. +**Post-review amendment:** The final public `GET /health/runtime` contract intentionally returns only `service`, `checkedAt`, `status`, and `checks`. Earlier code snippets in this plan that included `config` or described the endpoint as a safe config view were superseded during code review to avoid exposing runtime topology on an unauthenticated health endpoint. The internal `RuntimeConfigService` still owns the safe snapshot used to derive checks. + **Architecture:** Add a focused `src/runtime` Nest module. It depends on `ConfigModule` and `CommonModule`, exports typed runtime primitives, and keeps business modules unchanged during this phase. The endpoint returns plain machine-readable JSON, not a Vben response wrapper, so deployment tooling can consume it directly. **Tech Stack:** NestJS 11, TypeScript 5.9, Jest 29 with `ts-jest`, existing `@nestjs/config`, existing `ToolsService`, existing Swagger/Knife4j setup. @@ -1245,11 +1247,12 @@ git commit -m "feat: 添加API运行时健康检查" ### Runtime health The API exposes `GET /health/runtime` for deployment and local smoke checks. + +Post-review note: the public response no longer returns `config`; it exposes status and config check results only. It returns plain JSON with: - `status`: `live`, `ready`, `degraded`, or `blocked`. - `checks`: process and runtime config checks. -- `config`: a safe runtime config snapshot with secrets masked. The endpoint is machine-readable and intentionally does not use the Vben response wrapper. diff --git a/src/runtime/evidence/runtime-evidence.service.ts b/src/runtime/evidence/runtime-evidence.service.ts index 4df7093..746a32c 100644 --- a/src/runtime/evidence/runtime-evidence.service.ts +++ b/src/runtime/evidence/runtime-evidence.service.ts @@ -7,9 +7,9 @@ import { const REDACTED_VALUE = ''; const REDACTED_BASE64_VALUE = ''; const SENSITIVE_KEY_PATTERN = - /password|secret|token|authorization|cookie|privatekey|sshkey|ticket|randstr|replytext|base64/i; + /password|secret|token|authorization|cookie|privatekey|sshkey|accesskey|apikey|ticket|randstr|replytext|base64/i; const SENSITIVE_TEXT_KEY_PATTERN = - '(?:[A-Za-z0-9_-]*(?:password|secret|token|authorization|cookie|private[_-]?key|ssh[_-]?key|ticket|randstr|replyText|base64)[A-Za-z0-9_-]*|sid)'; + '(?:[A-Za-z0-9_-]*(?:password|secret|token|authorization|cookie|private[_-]?key|ssh[_-]?key|access[_-]?key|api[_-]?key|ticket|randstr|replyText|base64)[A-Za-z0-9_-]*|sid)'; const SENSITIVE_TEXT_REPLACEMENTS: Array<[RegExp, string]> = [ [ /data:[a-z0-9.+-]+\/[a-z0-9.+-]+;base64,[a-z0-9+/=\r\n]+/gi, @@ -18,6 +18,21 @@ const SENSITIVE_TEXT_REPLACEMENTS: Array<[RegExp, string]> = [ [/\b[A-Za-z0-9+/]{120,}={0,2}\b/g, REDACTED_BASE64_VALUE], [/\b(Authorization)\s*[:=]\s*[^\r\n]+/gi, '$1='], [/\b(Cookie)\s*[:=]\s*[^\r\n]+/gi, '$1='], + [ + /\b((?:private|ssh)[_-]?key)(\s*[:=]\s*)-----BEGIN[\s\S]*?-----END [^-]+-----/gi, + '$1$2', + ], + [ + /\b((?:private|ssh)[_-]?key)(\s*[:=]\s*)-----BEGIN[\s\S]*?(?=\s+[A-Za-z0-9_-]+\s*[:=]|\s*$)/gi, + '$1$2', + ], + [ + new RegExp( + `\\b(${SENSITIVE_TEXT_KEY_PATTERN})(\\s*[:=]\\s*)Bearer\\s+[^\\s,;&]+`, + 'gi', + ), + '$1$2', + ], [ new RegExp( `(["'])(${SENSITIVE_TEXT_KEY_PATTERN})\\1\\s*:\\s*(?:(["'])[^"']*\\3|[-+]?\\d+(?:\\.\\d+)?|true|false|null)`, diff --git a/test/runtime/runtime-evidence.service.spec.ts b/test/runtime/runtime-evidence.service.spec.ts index 371e2b0..41bb5a5 100644 --- a/test/runtime/runtime-evidence.service.spec.ts +++ b/test/runtime/runtime-evidence.service.spec.ts @@ -279,4 +279,36 @@ describe('RuntimeEvidenceService', () => { expect(serialized).not.toContain('67890'); expect(serialized).toContain('KT_SCAN_SAFE'); }); + + it('redacts access key and api key text plus unquoted multi-word secret values', () => { + const service = new RuntimeEvidenceService(); + + const record = service.createRecord({ + title: 'access key evidence', + taskType: 'backend', + project: 'kt-template-online-api', + environment: 'local', + operation: 'runtime-evidence', + status: 'failed', + details: { + text: + 'accessKey=raw-access-key access_key=raw-snake-access-key apiKey=raw-api-key api_key=raw-snake-api-key private_key=-----BEGIN PRIVATE KEY----- raw unquoted pem token=Bearer raw-bearer-token safe=value', + jsonText: + '{"accessKey":"raw-json-access-key","api_key":"raw-json-api-key","safe":"kept"}', + }, + }); + + const serialized = JSON.stringify(record); + + expect(serialized).not.toContain('raw-access-key'); + expect(serialized).not.toContain('raw-snake-access-key'); + expect(serialized).not.toContain('raw-api-key'); + expect(serialized).not.toContain('raw-snake-api-key'); + expect(serialized).not.toContain('raw unquoted pem'); + expect(serialized).not.toContain('raw-bearer-token'); + expect(serialized).not.toContain('raw-json-access-key'); + expect(serialized).not.toContain('raw-json-api-key'); + expect(serialized).toContain('safe=value'); + expect(serialized).toContain('kept'); + }); });