feat(jwt,core): stateful access tokens + user-deletion fan-out#13
Merged
Conversation
Introduces two related primitives for 1.1.0: 1. AccessTokenStore SPI in pk-auth-jwt. PkAuthJwtIssuer.issue() always calls store.record(jti, ...) before returning; PkAuthJwtValidator calls store.exists(jti) after signature/audience checks. The default AccessTokenStore.noop() preserves stateless JWT behaviour; hosts wire JdbiAccessTokenStore or DynamoDbAccessTokenStore (both shipped) to make logout / admin-revoke take effect before exp. RevocationCheck stays as the deny-list escape hatch. ADR 0015. 2. UserDeletionService + UserDeletionListener SPI in pk-auth-core. One call (deleteUser) fans out to every registered listener; failures are logged and counted, the service returns a UserDeletionResult. Listeners shipped for credentials, backup codes, OTPs, and access tokens; adapters auto-register them (Spring @bean collection, Dagger @IntoSet, Micronaut Collection<T> injection). Sequential + best-effort rather than motif's single-transaction model because pk-auth's persistence SPIs span JDBI / DynamoDB / in-memory. ADR 0016. Breaking SPI additions: CredentialRepository.deleteByUserHandle and OtpRepository.deleteByUserHandle. All three persistence variants updated. Flyway V8 ships the new access_tokens table. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two related primitives for the 1.1.0 train.
Feature 3 —
AccessTokenStoreSPI inpk-auth-jwt.PkAuthJwtIssuer.issue()always callsstore.record(jti, …)before returning;PkAuthJwtValidator.validate()callsstore.exists(jti)alongsideRevocationCheck. The defaultAccessTokenStore.noop()preserves stateless JWT behaviour — hosts wireJdbiAccessTokenStoreorDynamoDbAccessTokenStore(both shipped) to make logout / admin-revoke take effect beforeexp. NoTokenModeenum: presence of a real bean is the signal. ADR 0015.Cross-cutting —
UserDeletionServiceinpk-auth-core. Single fan-out point that runs every registeredUserDeletionListenerand returns a typedUserDeletionResult. Listeners shipped for credentials, backup codes, OTPs, and access tokens. Each adapter wires them through its native DI mechanism (Spring auto-collection, Dagger@IntoSet, MicronautCollection<T>). Sequential + best-effort rather than motif's single-shared-transaction model because pk-auth's persistence SPIs span JDBI / DynamoDB / in-memory with no shared substrate. ADR 0016.Breaking SPI additions
CredentialRepository.deleteByUserHandle(UserHandle) -> intOtpRepository.deleteByUserHandle(UserHandle) -> intAll shipped implementations (in-memory, JDBI, DynamoDB) are updated. Documented in CHANGELOG.md.
Schema
access_tokens (jti, user_handle, audience, device_id, issued_at, expires_at). PkAuthJdbiSchema.CURRENT_SCHEMA_VERSION bumped to 8.PkAuthCore(primary jti-keyed + user-indexed pointer) with nativettlfor async expiry.Test plan
🤖 Generated with Claude Code