Files

3.6 KiB

Contract: Proxy HTTP Responses

Feature: 001-oidc-proxy-script
File: src/proxyScripts/proxy.js
Endpoint: Any path handled by the adapter (all requests delegated to proxy.js by server.js)
Date: 2025-07-17


Overview

proxy.js responds to every inbound HTTP request with exactly one of two outcomes: a success response (authentication succeeded) or an error response (authentication failed for any reason). The contract defines the exact shape of both outcomes.


Success Response

Trigger: OIDC token successfully obtained (fresh fetch or valid cached token).

HTTP/1.1 200 OK
Content-Type: text/plain

Authorized
Property Value
Status code 200
Status text OK
Content-Type header text/plain
Body Literal string Authorized (no trailing newline)

Acceptance test (FR-007, SC-001, SC-002):

assert.strictEqual(res.statusCode, 200);
assert.strictEqual(res.body, 'Authorized');

Error Response

Trigger: Any of the following (FR-008, SC-004):

  • Token service returns HTTP 4xx or 5xx
  • Token service is unreachable (network error)
  • Token request times out after 5 seconds (FR-014)
  • Token service response is missing id_token or expires_in
  • adapter_settings is missing a required field
HTTP/1.1 401 Unauthorized
Content-Type: text/plain

Unauthorized: <descriptive message>
Property Value
Status code 401
Status text Unauthorized
Content-Type header text/plain
Body prefix Unauthorized: (literal, followed by the error message)
Body Never empty; always includes a human-readable description

Example bodies by error cause:

Cause Example body
Invalid credentials (401 from token service) Unauthorized: HTTP 401
Token service unavailable Unauthorized: connect ECONNREFUSED 127.0.0.1:443
5-second timeout Unauthorized: token service timeout
Response missing id_token Unauthorized: id_token missing from response
Response missing expires_in Unauthorized: expires_in missing from response
Missing tokenUrl in settings Unauthorized: missing required field: tokenUrl

Acceptance test (FR-008):

assert.strictEqual(res.statusCode, 401);
assert.match(res.body, /^Unauthorized: .+/);

Invariants

These MUST hold for every request, regardless of outcome:

  1. One response per request: res.writeHead() MUST be called exactly once; res.end() MUST be called exactly once.
  2. Never 500: proxy.js MUST NOT emit a 500 or leave the connection open. All errors, including unexpected runtime errors, MUST result in a 401 (not a crash or hang).
  3. No imports/exports (FR-009): The script MUST contain zero import or export statements — verified by static analysis.
  4. No forbidden globals (FR-010): No config, global.config, or process.env references — verified by static analysis.
  5. Response within 5 seconds (SC-001, FR-014): The HTTP timeout on the token POST is 5 000 ms. Combined with synchronous error handling, every request resolves within 5 seconds under normal network conditions.

Out of Scope

  • The proxy script does NOT validate the inbound request (method, path, headers, body). Its sole responsibility is OIDC authentication.
  • The response does NOT include the OIDC token in the body. The 200 OK / Authorized body is sufficient to confirm authentication succeeded (spec assumption, line 106).
  • No Authorization response header is set. The adapter's caller does not require it.