Files
agatha 602648ef56 Feat: Gate API docs endpoints behind API_DOCS_ENABLED env var
When API_DOCS_ENABLED=false, FastAPI registers no routes for /docs,
/redoc, or /openapi.json, returning 404 for all three. Default is true
for backwards compatibility. Invalid values fall back to true (FR-007).

Fix: Remove tests/ and alembic/ from api/.dockerignore so the test
Dockerfile (which uses COPY . .) includes the test suite; Dockerfile.prod
is unaffected as it only copies app/ explicitly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 20:40:48 +00:00

6.2 KiB

Feature Specification: API Documentation Visibility Gate

Feature Branch: 012-api-docs-gate Created: 2026-05-07 Status: Draft Input: User description: "Add an environment variable flag to disable the FastAPI Swagger and ReDoc documentation endpoints (and the raw OpenAPI schema) in production. When disabled, all three endpoints return 404. When enabled (the default), behaviour is unchanged. The flag should be off by default in production and on by default in development."

User Scenarios & Testing (mandatory)

User Story 1 - Documentation Hidden in Production (Priority: P1)

An operator deploys the API to a production environment and wants to ensure that the interactive documentation UI and the raw API schema are not publicly reachable. Setting a configuration flag causes all three documentation endpoints to return "not found", as if they do not exist.

Why this priority: Exposing the full API schema and interactive console to anonymous users in production reveals the attack surface of the application. Hiding it is a low-effort, high-value hardening step.

Independent Test: Start the API with the flag set to disabled. Request each of the three documentation endpoints. All three must return 404.

Acceptance Scenarios:

  1. Given the API is started with documentation disabled, When a client requests the interactive documentation UI, Then the response is 404 Not Found.
  2. Given the API is started with documentation disabled, When a client requests the alternative documentation UI, Then the response is 404 Not Found.
  3. Given the API is started with documentation disabled, When a client requests the raw OpenAPI schema endpoint, Then the response is 404 Not Found.
  4. Given the API is started with documentation disabled, When a client requests any other API endpoint (e.g., the health check), Then the response is unaffected — normal behaviour continues.

User Story 2 - Documentation Available in Development (Priority: P2)

A developer runs the API locally without setting the flag. The documentation endpoints remain fully accessible — no change in behaviour from before this feature.

Why this priority: Developer productivity depends on the interactive docs being available during local development. The default must not break existing workflows.

Independent Test: Start the API without the flag set (or with it explicitly enabled). Request each of the three documentation endpoints. All three must respond successfully with their normal content.

Acceptance Scenarios:

  1. Given the API is started without the flag set, When a client requests any documentation endpoint, Then the response is the same as it was before this feature was introduced.
  2. Given the API is started with the flag explicitly set to enabled, When a client requests any documentation endpoint, Then the response is the same as it was before this feature was introduced.
  3. Given the flag is changed from enabled to disabled (or vice versa), When the API is restarted, Then the new state takes effect immediately with no other changes required.

Edge Cases

  • What happens if the flag is set to an unrecognised value (e.g., a typo)?
  • What happens if the flag is absent entirely — is the default enabled or disabled?
  • Does disabling documentation affect any other behaviour (e.g., internal schema generation used for validation)?
  • If a monitoring tool scrapes the schema endpoint for API drift detection, does disabling break it?

Requirements (mandatory)

Functional Requirements

  • FR-001: The system MUST support a configuration flag that controls whether the API documentation endpoints are reachable.
  • FR-002: When the flag is set to disabled, all three documentation endpoints (interactive UI, alternative UI, and raw schema) MUST return 404 Not Found.
  • FR-003: When the flag is set to enabled, the behaviour of all three documentation endpoints MUST be identical to the behaviour before this feature was introduced.
  • FR-004: The flag MUST default to enabled when not explicitly set (preserving backwards compatibility for existing deployments).
  • FR-005: Disabling documentation MUST NOT affect any other API endpoint, including the health check, authentication, and all resource endpoints.
  • FR-006: The flag MUST be configurable via an environment variable without requiring a code change or rebuild.
  • FR-007: An unrecognised or missing flag value MUST fall back to the enabled default rather than causing a startup failure.
  • FR-008: The existing .env.example file MUST be updated to document the flag and its default value.
  • FR-009: The production environment configuration MUST set the flag to disabled by default.

Success Criteria (mandatory)

Measurable Outcomes

  • SC-001: With the flag disabled, all three documentation endpoints return 404, confirmed by automated test.
  • SC-002: With the flag enabled (or absent), all three documentation endpoints respond successfully, confirmed by automated test.
  • SC-003: All existing tests continue to pass — zero regressions introduced.
  • SC-004: The flag takes effect on restart with no other intervention required.
  • SC-005: The .env.example file documents the flag so any developer setting up the project discovers it without reading source code.

Assumptions

  • There are exactly three documentation-related endpoints to gate: the primary interactive UI, the alternative documentation UI, and the raw OpenAPI schema JSON. No other endpoints are affected.
  • The flag is read once at application startup; a running process does not need to respond to live changes.
  • Internal schema generation (used by the framework for request validation) is not affected by hiding the documentation endpoints — only the public-facing HTTP routes are removed.
  • The production Dockerfile (api/Dockerfile.prod) does not hardcode the flag; it is supplied via the deployment environment (docker-compose, Kubernetes secret, etc.).
  • "Off by default in production" means the recommended value for production is disabled, documented in .env.example and in the production docker-compose or deployment config; it does not mean the application auto-detects its environment.