-
Notifications
You must be signed in to change notification settings - Fork 13
Description
Problem
Once a user grants consent to a client, that consent persists indefinitely in the database. There is no mechanism to automatically expire
old consents, which means:
- Users may forget which applications have access to their data
- Compromised or abandoned clients retain access indefinitely
- No opportunity for users to review permissions periodically
Current Behavior
// Consent stored with GrantedAt timestamp but no expiration check
type UserConsent struct {
UserId int64
ClientId int64
Scope string
GrantedAt sql.NullTime
}
Consent is reused indefinitely if all requested scopes were previously granted (handler_consent.go:115-137).
Proposed Solution
- Add ConsentMaxLifetimeInSeconds setting (global and per-client override)
- Modify consent check to compare GrantedAt + MaxLifetime against current time
- When consent expires, user sees consent screen again (not an error)
- Default could be 0 (no expiration) for backwards compatibility
Example implementation
// In consent checking logic
if consent.GrantedAt.Valid {
consentAge := time.Since(consent.GrantedAt.Time)
if settings.ConsentMaxLifetimeInSeconds > 0 &&
consentAge > time.Duration(settings.ConsentMaxLifetimeInSeconds)*time.Second {
// Treat as no consent - show consent screen
}
}