✨ feat(auth): JWT TTL hot-reload + fix hardcoded 24h bug (ADR-0023 Phase 2) #44
Reference in New Issue
Block a user
Delete Branch "feat/adr-0023-phase2-jwt-ttl-hot-reload"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Two fixes in one diff
Both touch the same surface (
JWTConfigplumbing), so kept together.1. Bug fix (pre-existing)
pkg/server/server.gowas hardcodingExpirationTime: time.Hour * 24when buildingJWTConfig, completely ignoringauth.jwt.ttlfrom config (default 1h). Production has been signing tokens with 24h TTL regardless of config since the field was added.2. Hot-reload (ADR-0023 Phase 2)
Extends
JWTConfigwithGetTTL func() time.Durationcallback. NeweffectiveTTL()helper prefersGetTTL()when set, falls back toExpirationTimeotherwise (test-friendly).server.gowiresGetTTL: cfg.GetJWTTTL— a method value capturing*Config. WhenWatchAndApplyre-unmarshals into the same Config on file change, the next token generation reads the new TTL. Tokens already issued keep their original expiry — only newly-generated tokens are affected.WatchAndApplynow also logs the newjwt_ttlon every reload.Tests
TestWatchAndApply_JWTTTLinpkg/config/config_hot_reload_test.go: rewrites the config file and assertsc.GetJWTTTL()flips within 2s. Polling (no fixed sleep), race-clean.pkg/usertests (incl. JWT manager + cleanup loop from PR #41) all pass with-race.ADR-0023 status
Was:
Phase 1 Implemented (logging.level).Now:
Phase 1+2 Implemented (logging.level + auth.jwt.ttl).Remaining:
api.v2_enabled— needs router refactor (always-register + middleware gate); deferredVerifier verdict (skill-driven)
APPROVE
effectiveTTL()is 6 lines, defensive on nil + non-positive TTL; method value capturescfgcleanly without globals.Test plan
go test -race ./pkg/config/...passesgo test -race ./pkg/user/...passesgo vet ./...cleanjwt_ttl=1h0m0s(default) instead of the previous-but-unused 24h