# Security & Technical Debt Items identified during code review that should be addressed before production. ## High Priority ### Token refresh logic in SvelteKit (`apps/dashboard/src/auth.ts`) The JWT callback stores `expiresAt` and `refreshToken` but never checks expiry or initiates a refresh. Auth.js does not auto-refresh tokens. Without this, users get silently logged out when their access token expires (typically 5-15 minutes for Zitadel). **Fix:** Add expiry check in the `jwt` callback and use `refreshToken` to obtain a new access token when expired. ### JWKS cache thundering herd (`crates/pvm-auth/src/jwks.rs`) When the cache expires, every concurrent request sees stale cache and calls `refresh()` simultaneously. The `RwLock` serializes writes but each request still makes an HTTP call before acquiring the lock. **Fix:** Add a "refresh-in-progress" flag or use double-checked locking so only one request triggers the refresh while others wait. ## Medium Priority ### `trustHost: true` in auth.ts Disables CSRF origin check in Auth.js. Required for local dev behind localhost, but must be removed or made conditional for production. ### `devMode: true` in OIDC app config (`docker/setup-zitadel.sh`) Disables redirect URI validation in Zitadel. The setup script is dev-only, but if a similar script is used for production, this must be `false`. ### Custom login UI Replace the default Zitadel login v1 UI with a fully custom login/signup flow built into the SvelteKit dashboard using Zitadel's Session API. Includes: login, signup, password reset, 2FA flows. Must match PVM visual design. ## Low Priority ### Shell script JSON parsing (`docker/setup-zitadel.sh`) Uses `grep -o` and `cut` to extract JSON fields. Fragile if JSON format changes. Consider using `jq` with a fallback. ### PAT expiration Machine user PAT expires 2030-01-01. Fine for dev, but production should use shorter-lived credentials. ### Running Zitadel as root (`docker-compose.dev.yml`) `user: "0"` is required for `start-from-init` to write the PAT file. Dev-only concern — production deployment should use proper volume permissions.