Files
carmanagement/docs/design/SECURITY_DESIGN_UPDATES.md
T
root 8fc88ffc14
Build & Push / Pipeline Tests (push) Failing after 59s
Build & Push / Build & Push Docker Image (push) Has been skipped
Test / Type Check (all packages) (push) Failing after 51s
Test / API Unit Tests (push) Has been skipped
Test / Homepage Unit Tests (push) Has been skipped
Test / Carplace Unit Tests (push) Has been skipped
Test / Admin Unit Tests (push) Has been skipped
Test / Dashboard Unit Tests (push) Has been skipped
Test / API Integration Tests (push) Has been skipped
fix production issues
2026-08-12 16:48:41 -04:00

55 lines
2.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Security design updates (Phases 0 & 3)
Summary of application-security design changes from the production-readiness program. Full finding table lives in `docs/ops/RentalDriveGo_Production_Readiness_Plan.md` §3.
## Closed in code (S1S15)
| ID | Design rule now enforced |
|----|---------------------------|
| S1 | Team list/invite responses use safe presenters — never return password hashes or raw reset tokens |
| S2 | Per-tenant Docker/Compose orchestration is **out of production scope** (fail-closed + ADR-001) |
| S3 | Invite tokens hashed at rest (SHA-256) |
| S4 | Employee email unique per company; login fails closed on ambiguity |
| S5 | Post-login redirects limited to safe relative paths |
| S6 | Authenticated payment/subscription return URLs allowlisted |
| S7 | Admin company slugs validated / slugified |
| S8 | Admin presenters strip reset/verification secrets |
| S9 | Forwarded headers scrubbed by default; `TRUSTED_FORWARD_HEADERS=true` only behind a scrubbing edge (`docs/ops/proxy-trust.md`) |
| S10 | Password reset token lookup is hash-only |
| S11 | `reviewToken` is never returned in reservation/review API JSON (still used server-side for email links) |
| S12 | Public booking access: **read** does not burn the token; **payment init** atomically consumes an unused token |
| S13 | Admin money / privileged mutations require 2FA proof newer than `ADMIN_FRESH_2FA_MAX_AGE_MS` |
| S14 | `.gitignore` present for secrets/build artifacts |
| S15 | `npm run security:static` in CI |
## Public booking token (S12) flow
```
createBooking → mint publicAccessToken (hash stored)
├─ GET booking?token=… → validate (used or unused OK until expiry) — do not consume
└─ initPayment(token) → require usedAt IS NULL → updateMany set usedAt → proceed
(second payment attempt with same token → 404)
```
## Fresh admin 2FA (S13)
`requireFreshAdmin2FA` rejects when:
- TOTP not enrolled, or
- JWT lacks `last2faAt`, or
- `now - last2faAt > ADMIN_FRESH_2FA_MAX_AGE_MS` (default 30 minutes)
Wired on finance/support money and high-privilege admin mutations.
## Tenant isolation design
- App-level: every company resource query includes `companyId` from the authenticated session
- Regression suite: `apps/api/src/tests/integration/cross-tenant-isolation.test.ts`
- Postgres RLS: **deferred** (ADR-002) until the app-level suite and worker/migration roles are ready
## Pen-test
Scope pack: `docs/security/pen-test-scope.md`. Reports belong under `security-reports/` (evidence, not design).