feat(guardion): Guardion middleware + replace x-portkey-* with x-guardion-* headers#1
feat(guardion): Guardion middleware + replace x-portkey-* with x-guardion-* headers#1rafaelsandroni wants to merge 1 commit into2.0.0from
Conversation
…an up portkey references - edgeHeaderTranslator: remove bidirectional x-portkey ↔ x-guardion sync; x-guardion-policy now maps to x-guardion-config directly - mapper.ts: rename mapGuardConfigToPortkey → mapGuardConfig, internal variable portkeyConfig → guardionConfig, update stale comments - guardion/index.ts: update import and variable names to match renamed mapper export - sessionCache.ts: remove reference to "Portkey's native cache handlers" in comment Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
| logger.info({ | ||
| message: `fetchOrganisationIdFromAPIKey options: ${JSON.stringify(albusFetchOptions)}`, | ||
| }); |
Check failure
Code scanning / CodeQL
Clear-text logging of sensitive information High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 7 days ago
In general, to fix clear-text logging of sensitive information, ensure that values like API keys, passwords, tokens, and authorization headers are never written to logs. Either: (1) remove such logs entirely, (2) log only non-sensitive metadata (e.g., URL, method, status code), or (3) explicitly redact or mask sensitive fields before logging.
Here, the problematic log is:
logger.info({
message: `fetchOrganisationIdFromAPIKey options: ${JSON.stringify(albusFetchOptions)}`,
});albusFetchOptions includes headers containing the apiKey, so we should avoid logging this whole object. The least intrusive change that preserves functionality is to log only non-sensitive parts of the request, such as the HTTP method and URL, and perhaps the list of header keys without their values. Since we must not change behavior outside logging, we will keep albusFetchOptions as-is for the fetch call and only modify the log. A simple, safe fix is to remove the detailed options logging or replace it with a redacted version that omits header values.
Concretely in src/services/albus/index.ts:
- Leave
albusFetchOptionsunchanged so the request behavior is identical. - Replace the
logger.infoat lines 122–124 with a version that logs a safe summary, e.g., method and URL, and optionally that headers are present but not their values. - No new imports or helper methods are required; we can construct a minimal, non-sensitive object inline.
| @@ -120,7 +120,11 @@ | ||
| }); | ||
|
|
||
| logger.info({ | ||
| message: `fetchOrganisationIdFromAPIKey options: ${JSON.stringify(albusFetchOptions)}`, | ||
| message: `fetchOrganisationIdFromAPIKey options: ${JSON.stringify({ | ||
| method: albusFetchOptions.method, | ||
| url: albusFetchUrl, | ||
| headers: Object.keys(albusFetchOptions.headers), | ||
| })}`, | ||
| }); | ||
|
|
||
| try { |
Summary
This PR introduces the full Guardion integration layer on top of the Portkey AI Gateway fork and removes all
x-portkey-*header references from Guardion-owned code, replacing them withx-guardion-*throughout.What's included
New Guardion middleware (
src/middlewares/guardion/)index.ts—guardionAuthmiddleware: extractsx-guardion-api-key/Authorizationheader, fetchesGET /v1/configfrom the Guard API, caches the result (60s soft TTL, 24h hard TTL), injects the mapped config asx-guardion-config, and spoofs anOrganisationDetailscontext so the downstream auth middleware passes cleanlymapper.ts—mapGuardConfig(): translates Guard API config JSON (routing, features, guardrails) into the gateway's internal config formattelemetry.ts— buffered async telemetry flush: batches up to 50 logs and flushes every 5s toPOST /v1/telemetry/logson the Guard API, fire-and-forgetNew Guardion plugin (
src/plugins/guardion/)guardrails.ts—handler: callsPOST /v1/evalon the Guard API, resolvesmonitor→flag,intercept + correction→redact,intercept→block; fails open on Guard API downtimesessionCache.ts— per-(apiKey, applicationId)rolling flag/block counters with configurable lock thresholds and durationstoolPolicy.ts— allowlist/denylist enforcement ontools[]declarations (beforeRequestHook) andtool_calls[]in responses (afterRequestHook)guardrails.test.ts— 9 unit tests covering all resolution pathsHeader refactor (this changeset)
edgeHeaderTranslator.ts— removed the bidirectionalx-portkey-↔x-guardion-sync loop;x-guardion-policynow maps directly tox-guardion-config(no morex-portkey-configwrites)mapper.ts— renamedmapGuardConfigToPortkey→mapGuardConfig,portkeyConfig→guardionConfig; updated commentsguardion/index.ts— updated import to use renamedmapGuardConfigsessionCache.ts— updated comment removing "Portkey's native cache handlers" wordingIntegration test
tests/integration/src/middlewares/edgeHeaderTranslator/edgeHeaderTranslator.test.tsRequest flow
Remaining open issues (not in this PR)
GET /v1/configin Guard APIPOST /v1/telemetry/logsin Guard APImanifest.json+ registerguardioninconf.jsonpolicyfield toEvaluationRequestschemaPolicyRequestschema:detector→detectors(array)Breakdown.resulttypeTest plan
GUARD_API_URL=http://localhost:8000x-guardion-api-key: <key>— verify Guard API/v1/configis called and config is injectedx-guardion-policy: my-policy— verify it is normalized tox-guardion-config: pc-my-policyx-portkey-*headers are no longer set or read by Guardion middlewareblock/redact/flagresponses are correctjest src/plugins/guardion/jest tests/integration/src/middlewares/edgeHeaderTranslator/🤖 Generated with Claude Code