Threat reference
T14 (Data corruption / authorization-state inconsistency via race conditions) — see docs/THREAT_MODEL.md §4.
Context
This is the remaining half of #354 (closed). Part 1 — serializing ACL writes via row-level SELECT ... FOR UPDATE on the parent threat model and parent survey response — landed via updateAuthorizationTx and UpdateAuthorization, oracle-db-admin APPROVED.
What's still missing
The broader optimistic-locking work (§8 mitigation #14 part 1 of #354):
- Add a
version (integer) column to every mutable top-level entity (threat_models, diagrams, projects, teams, assets, threats, documents, surveys).
- Migration:
auth/migrations/000NN_add_version_column.up.sql defaulting existing rows to 1.
PUT and PATCH handlers require If-Match: <current-version> (or accept version in the body).
- UPDATE statement:
UPDATE ... WHERE id = ? AND version = ?; affected != 1 → 409 Conflict. Increment version on every successful write.
- Wire ETag header (already mentioned in OpenAPI for some endpoints) into the version check.
- Existing clients without
If-Match get a deprecation warning header for one release, then a hard 428 (Precondition Required).
Acceptance criteria
- A test concurrently PUTs the same threat model from two goroutines with the same
If-Match; one succeeds (200), the other gets 409.
- oracle-db-admin subagent APPROVED for the migration (this issue is DB-touching).
- All sub-resource handlers (assets / threats / documents / etc) honor the same If-Match contract.
Effort
M (1-2 days; one migration + handler refactor across ~20 endpoints).
Related
Threat reference
T14 (Data corruption / authorization-state inconsistency via race conditions) — see docs/THREAT_MODEL.md §4.
Context
This is the remaining half of #354 (closed). Part 1 — serializing ACL writes via row-level
SELECT ... FOR UPDATEon the parent threat model and parent survey response — landed viaupdateAuthorizationTxandUpdateAuthorization, oracle-db-admin APPROVED.What's still missing
The broader optimistic-locking work (§8 mitigation #14 part 1 of #354):
version(integer) column to every mutable top-level entity (threat_models,diagrams,projects,teams,assets,threats,documents,surveys).auth/migrations/000NN_add_version_column.up.sqldefaulting existing rows to1.PUTandPATCHhandlers requireIf-Match: <current-version>(or acceptversionin the body).UPDATE ... WHERE id = ? AND version = ?; affected != 1 → 409 Conflict. Increment version on every successful write.If-Matchget a deprecation warning header for one release, then a hard 428 (Precondition Required).Acceptance criteria
If-Match; one succeeds (200), the other gets 409.Effort
M (1-2 days; one migration + handler refactor across ~20 endpoints).
Related