Skip to content

feat(api): version column + If-Match optimistic locking on mutable entities (T14 part 2) #385

@ericfitz

Description

@ericfitz

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):

  1. Add a version (integer) column to every mutable top-level entity (threat_models, diagrams, projects, teams, assets, threats, documents, surveys).
  2. Migration: auth/migrations/000NN_add_version_column.up.sql defaulting existing rows to 1.
  3. PUT and PATCH handlers require If-Match: <current-version> (or accept version in the body).
  4. UPDATE statement: UPDATE ... WHERE id = ? AND version = ?; affected != 1 → 409 Conflict. Increment version on every successful write.
  5. Wire ETag header (already mentioned in OpenAPI for some endpoints) into the version check.
  6. 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

Metadata

Metadata

Assignees

Labels

Projects

Status

Done

Relationships

None yet

Development

No branches or pull requests

Issue actions