ReskSafety · Documentation

ENV Match

Secrets and PII are replaced by stable [[RESK_*]] flags before the payload leaves the firewall, then restored locally in the response — including streamed chunks and tool-call arguments. The provider never receives the original value.

  • Enabled by default
  • Per-request vault
  • Streaming-safe

How it works

user prompt: "mail [email protected], key sk-live-9f2a…"
        │
        ▼  mask (before egress)
provider sees: "mail [[RESK_EMAIL_1]], key [[RESK_SECRET_1]]"
        │
        ▼  model answers, echoing the flags
model output:  "Sent to [[RESK_EMAIL_1]] using [[RESK_SECRET_1]]"
        │
        ▼  restore (local, from the per-request vault)
client sees:   "Sent to [email protected] using sk-live-9f2a…"

Masking happens in the firewall process, after authentication and policy screening, and immediately before the upstream call. Restoration happens on the way back, after the output policy checks. The mapping is held in memory for the duration of one request.

What is masked

KindDetectionFlag
ENVValues of protected environment variables: LLM_BACKEND_API_KEY, ANTHROPIC_API_KEY, PROVIDER_ENCRYPTION_KEY, JWT_SECRET_KEY, CSRF_SECRET, RESKPOINTS_API_KEY, RESEND_API_KEY, DATABASE_URL, plus names in ENV_MATCH_ENV_VARS[[RESK_ENV_1]]
SECRETsk-…, sk-ant-…, GitHub, Slack, Stripe, AWS and Google API keys, JWTs, Bearer … tokens, PEM private keys, api_key=…/password=… assignments[[RESK_SECRET_1]]
SHA32, 40 and 64 character hexadecimal digests (MD5, SHA-1, SHA-256)[[RESK_SHA_1]]
EMAILEmail addresses[[RESK_EMAIL_1]]
PHONEPhone numbers, international or grouped (9–15 digits)[[RESK_PHONE_1]]
CARDPayment card numbers, validated with the Luhn checksum[[RESK_CARD_1]]

Values are de-duplicated inside a request: the same secret referenced three times keeps the same flag. Distinct values get distinct indexes per kind.

Round trip details

Configuration

VariableDefaultEffect
ENV_MATCH_ENABLEDtrueMaster switch
ENV_MATCH_ENV_VALUEStrueMask protected environment values
ENV_MATCH_SECRETStrueMask known secret formats
ENV_MATCH_DIGESTStrueMask MD5/SHA hex digests
ENV_MATCH_PIItrueMask emails, phones, card numbers
ENV_MATCH_MIN_SECRET_LENGTH8Ignore shorter environment values
ENV_MATCH_MAX_MATCHES500Safety cap per request
ENV_MATCH_HINTtrueAdd the system hint about flags
ENV_MATCH_ENV_VARSemptyExtra environment variable names (comma separated)

Turning off a category only disables detection for it; masking stays enabled for the others. Typical reasons to narrow the scope: a tool that legitimately needs to forward a phone number, or prompts that contain digests the model must reason about.

Guarantees

Limits

Try it

curl -s http://localhost:8000/v1/chat/completions \
  -H "Authorization: Bearer $RESK_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4o-mini",
    "messages": [{"role": "user", "content": "Email [email protected] the key sk-abcdefghijklmnop1234567890"}]
  }'

With a debug provider or a request log capture, the upstream body contains [[RESK_EMAIL_1]] and [[RESK_SECRET_1]]; the client receives the original address and key in the answer.

Implementation

The layer lives in backend/src/resk_app/services/env_match_service.py and is wired into both firewall routers (OpenAI and Anthropic, streaming and non-streaming, batch tool calls). Tests cover detection, flag stability, vault isolation, streaming splits, tool-argument restoration and an end-to-end request against a mocked provider: backend/tests/test_env_match.py.