16-2: Roll out locking for token rotation
Status: 2026-03-18
Contents key
This page
Related pages
Public steps
- 16-1: Locking für Rate-Limit und CAPTCHA ausrollen
- 16-3: Add race-adjacent tests
- 16-4: Update operational note
Step-specific public work record for 16-2 under J01-16.
Goal
Roll out the runtime frame from 16-1 to TokenService.rotate().
Only the write path is affected; read operations remain unchanged.
Target areas and lock granularity
| Area | Target operation | Lock scope | Write behaviour |
|---|---|---|---|
| Token | rotate(profile, tokens) |
per profile |
token file overwritten atomically under lock |
| Token | verify(profile, token) |
no lock | read only |
| Token | findProfileForToken(token) |
no lock | read only |
rotate() is a pure write (no read-modify-write sequence).
The lock protects against two concurrent rotations of the same profile.
RuntimeAtomicWriter protects against torn reads by parallel verify() calls.
Review plan
| Check | Expected | Evidence / location | Status |
|---|---|---|---|
rotate() runs under lock |
Lock key token_{profile} per profile; concurrent rotation of the same profile is serialised |
TokenService::rotateLocked() |
Done |
| File written atomically | RuntimeAtomicWriter via temp+rename; readers never see a partially written token file |
TokenService::rotateLocked() |
Done |
| Read operations unchanged | verify(), findProfileForToken(), readHashes() without lock, no regression risk |
TokenService.php |
Done |
| Tests green | 26/26 PHPUnit tests after change | php vendor/bin/phpunit |
Done |
Delta 2026-03-20
The previously still open app-side remainder for 16-2 is now explicitly
closed in the source repo:
- Commit
8ab08e4movesTokenServiceplus the finalAppContextwiring onto the state described on this page. php bin/cli config lint devis green.TokenServiceTestand the relatedConcurrencyTestcases are green withTMPDIRset.