# SEC-001 canonical-origin verification

Date: 2026-08-02  
Status: `VERIFIED LOCALLY`; proxy and production verification remain.

## Implemented boundary

- Production startup requires a clean HTTPS `App:PublicBaseUrl`; Development/Test defaults to `http://localhost:3000` when absent.
- Password-reset, verification, admin-reset, Gmail/Graph callback, billing and reminder URLs use that immutable origin.
- Production requests accept the canonical Host; `backend`, `localhost`, `127.0.0.1` and `::1` are accepted only for `/health`.
- Session, CSRF and trusted-device cookie security derives from the canonical origin, not request or forwarded headers.
- Deployment preflight requires the canonical HTTPS origin; legacy per-provider callback-origin variables were removed.

## Commands and results

| Command | Result |
|---|---|
| `dotnet build JobTrackerApi/JobTrackerApi.csproj -c Release --no-restore` | Pass; 0 warnings, 0 errors |
| focused `dotnet test` filter for origin/auth/Gmail/Graph/billing/2FA/session tests | Pass; 79/79 |
| `dotnet test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj -c Release --no-restore` | Pass; 474/474 |
| `docker compose config --quiet` with synthetic required values | Pass; only expected unset optional-variable warnings |
| `tr -d '\r' < deploy/deploy.sh \| bash -n` | Pass |
| `git show HEAD:deploy/deploy.sh \| tr -d '\r' \| bash -n` | Pass; confirms direct Git-Bash CRLF failure predates SEC-001 |
| `git diff --check` | Pass; line-ending conversion warnings only |
| trust-boundary `rg` for request Host/scheme, forwarded proto and legacy origin aliases | Pass; only the central production Host decision remains |

## Focused cases

`ExternalOriginTests` covers missing/blank/non-HTTPS production origins; credentials, path, query and fragment rejection; local default; canonical port matching; internal-health restriction; provider-override/host-poisoning resistance; and canonical secure-cookie behavior.

## Limitations and remaining checks

- A hidden local Production-mode process launch was rejected by the command policy before execution. No service or temporary database was created, and no runtime result is claimed.
- Complete reverse-proxy behavior belongs to SEC-002 and remains unverified.
- Reset/verification navigation needs a safe local email sink or mock plus browser runtime; no email was sent.
- Production canonical/hostile Host smoke is required before SEC-001 can be `DONE`.
