chore: root commit of OWSAP security testing/tightening
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
# Post-Deployment Verification Checklist
|
||||
|
||||
Use this after every deploy (staging and production).
|
||||
|
||||
## Preconditions
|
||||
|
||||
1. Deployment completed successfully.
|
||||
2. Migrations completed successfully.
|
||||
3. Correct environment flags:
|
||||
- `AUTH_DISABLED=false`
|
||||
- `ALLOW_INSECURE_AUTH_FOR_DEV=false`
|
||||
4. Test DB preflight (for DB-backed suites):
|
||||
- `TEST_DATABASE_URL` points to a reachable PostgreSQL instance.
|
||||
- Example quick check:
|
||||
```bash
|
||||
echo "$TEST_DATABASE_URL"
|
||||
```
|
||||
Expected:
|
||||
- single valid URL value
|
||||
- host/port match the intended test database (for local runs usually `127.0.0.1:5432`)
|
||||
|
||||
## A01 smoke checks
|
||||
|
||||
Replace `${API_BASE}` with your deployed API base URL.
|
||||
|
||||
### 1) Protected route requires auth
|
||||
|
||||
```bash
|
||||
curl -i "${API_BASE}/dashboard"
|
||||
```
|
||||
|
||||
Expected:
|
||||
- HTTP `401`
|
||||
- response body includes `UNAUTHENTICATED`
|
||||
|
||||
### 2) Spoofed identity header is ignored
|
||||
|
||||
```bash
|
||||
curl -i -H "x-user-id: spoofed-user-id" "${API_BASE}/dashboard"
|
||||
```
|
||||
|
||||
Expected:
|
||||
- HTTP `401`
|
||||
|
||||
### 3) Admin rollover is not publicly callable
|
||||
|
||||
```bash
|
||||
curl -i -X POST "${API_BASE}/admin/rollover" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"dryRun":true}'
|
||||
```
|
||||
|
||||
Expected:
|
||||
- HTTP `403`
|
||||
|
||||
## A09 smoke checks
|
||||
|
||||
### 4) Security events are emitted for failed auth attempts
|
||||
|
||||
Trigger a failed login attempt:
|
||||
|
||||
```bash
|
||||
curl -i -X POST "${API_BASE}/auth/login" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"email":"nonexistent@example.com","password":"WrongPass123!"}'
|
||||
```
|
||||
|
||||
Expected:
|
||||
- HTTP `401`
|
||||
- API logs include a structured `securityEvent` for `auth.login` with `outcome=failure`
|
||||
- log entry includes `requestId`
|
||||
|
||||
## A10 smoke checks
|
||||
|
||||
### 5) Production origin configuration is public and non-local
|
||||
|
||||
Verify production env/config:
|
||||
|
||||
- `APP_ORIGIN` uses public HTTPS host (not localhost/private IP ranges)
|
||||
|
||||
Expected:
|
||||
- API boots successfully with production env validation.
|
||||
|
||||
## Automated regression checks
|
||||
|
||||
Run in CI against a prod-like environment:
|
||||
|
||||
```bash
|
||||
cd api
|
||||
npm test -- tests/auth.routes.test.ts tests/access-control.account-delete.test.ts tests/access-control.admin-rollover.test.ts
|
||||
SECURITY_DB_TESTS=0 npx vitest run -c vitest.security.config.ts
|
||||
SECURITY_DB_TESTS=1 npx vitest run -c vitest.security.config.ts
|
||||
```
|
||||
|
||||
Expected:
|
||||
- all tests pass
|
||||
|
||||
Note:
|
||||
- A06/A07 runtime suites require PostgreSQL availability.
|
||||
- `SECURITY_DB_TESTS=0` runs non-DB security controls only.
|
||||
- `SECURITY_DB_TESTS=1` includes DB-backed A06/A07 suites.
|
||||
|
||||
## Sign-off
|
||||
|
||||
1. Record outputs in `evidence-log-template.md`.
|
||||
2. Review open residual risks in `residual-risk-backlog.md`.
|
||||
3. Mark release security check as pass/fail.
|
||||
Reference in New Issue
Block a user