# ContextKey Shield — Independent Security Review Request

Status: internal implementation checklist prepared; independent review not performed; live provider route remains disabled by default.

## Review target

Route: `/api/contextkey/proxy` (Netlify Edge Function, `netlify/edge-functions/contextkey-proxy.js`). It is separate from the existing QI assistant router and requires a dedicated provider key. The feature is fail-closed unless an operator configures the provider/quota secrets, turns on the proxy, and records the independent security and provider-spending-control gates.

The implemented request is text-only, one prompt, at most 4,000 characters and 128 generated tokens. It rejects unsigned/expired QI sessions, non-allowlisted origins, extra request fields, apparent credential/SSN/EIN patterns, and requests beyond atomic Upstash limits of 10/account/day and 40 total/day. It uses a fixed provider hostname, does not expose the key to the browser, does not persist prompts in application code, and sets `store: false`. Provider data policies and Netlify platform logs remain separate shared-responsibility considerations.

## Required independent checks

- Verify QI HMAC verification, expiry bounds, identity mapping, and account/workspace isolation; specifically assess session issuance and the fact that this route quotas by signed `sub`.
- Test exact-origin/CORS behavior, preflight, absent/malformed Origin, content type, methods, oversized bodies, JSON schema, Unicode, secret-pattern bypasses, and output handling.
- Test Upstash REST authentication, Lua atomic counters, UTC day rollover, denied-request counting, outages, replay, and global/account limit behavior under concurrent calls.
- Confirm provider-key separation from QI, open redirect/SSRF impossibility, provider timeouts, provider errors, and response truncation/shape handling.
- Review abuse, prompt injection, data minimization, provider retention, model selection, and logging. The service does not claim model output moderation or safety certification.
- Review billing exposure and establish an actual provider-side spending/budget alert/limit before setting `CONTEXTKEY_PROVIDER_SPENDING_LIMIT_SET=true`; the application quota is a request cap, not a dollar-denominated hard spend cap.
- Review Netlify environment variable scopes and mark every key/token as secret. Use a separate staging provider project/key and quota database first.
- Run signed staging tests and independent penetration/security tests. Record findings, evidence, remediation, reviewer, date, and approval scope.

## External review path (not yet requested or completed)

- CISA's Cyber Hygiene Services describe no-cost vulnerability and web-application scanning for eligible organizations. Ask CISA to confirm eligibility, authorized asset scope, and whether its service includes the depth of application testing needed here: <https://www.cisa.gov/cyber-hygiene-services> and <https://www.cisa.gov/stopransomware/services>. A scan is useful input, not a substitute for an independent source-code/configuration review or a formal penetration test report.
- For a true independent review, engage an application-security assessor with documented web/API penetration-testing experience, written rules of engagement, a staging-only target, and a report covering the checks above. Confirm fees, scope, data handling, and deliverables before sharing credentials or enabling production routes.
- Do not send live provider keys, QI signing secrets, customer data, or encryption keys to a reviewer. Provide a staging environment and short-lived least-privilege test credentials through an agreed secure channel.

## Deployment gates — do not bypass

Required Netlify function/edge environment variables:

- `CONTEXTKEY_OPENAI_API_KEY` — dedicated provider key; secret value.
- `CONTEXTKEY_MODEL` — fixed administrator-selected model; never client-selectable.
- `UPSTASH_REDIS_REST_URL` and `UPSTASH_REDIS_REST_TOKEN` — dedicated rate-limit database; token secret.
- `CONTEXTKEY_SECURITY_REVIEW_APPROVED=true` — only after independent review and remediation.
- `CONTEXTKEY_PROVIDER_SPENDING_LIMIT_SET=true` — only after an actual provider-side spend control is configured and checked.
- `CONTEXTKEY_PROXY_ENABLED=true` — only for the explicitly approved staging/live scope.

Never set approval flags merely to make the test button light up. The status endpoint reports only whether the gates are open; it sends no upstream request. A provider call happens only after a signed-in operator checks the disclosure and selects “Send one bounded test.”

## Review record — intentionally blank

- Independent reviewer / organization: ____________________
- Scope and test environment: ____________________
- Review date and report reference: ____________________
- Findings and severity: ____________________
- Remediation verified: ____________________
- Approved model, limits, and deployment scope: ____________________

Do not fill these fields or open the live route until the work has actually occurred.
