Implement shared authentication leases
This commit is contained in:
47
docs/authentication-leases.md
Normal file
47
docs/authentication-leases.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# Authentication leases
|
||||
|
||||
`crates/storage` owns the authentication and inactivity policy shared by every
|
||||
interactive frontend. `AuthenticationSession` owns an uncached `SecretStore`,
|
||||
and `authenticate` accepts only non-secret `KeyInfo`. A frontend therefore
|
||||
never receives or retains a GPG passphrase itself.
|
||||
|
||||
An authenticated session returns an `AuthenticationHandle`. Every clone is
|
||||
bound to the same generation. Manual lock, cancellation, or expiry revokes the
|
||||
generation, clears its cached unlock material, locks the backing secret store,
|
||||
and makes all old handles reject later secret access. A new authentication
|
||||
creates a distinct generation, so an old editor or view cannot become valid
|
||||
again accidentally.
|
||||
|
||||
The lease caches only a zeroizing `SecretBytes` passphrase for each protected
|
||||
key actually requested during the active generation. The underlying
|
||||
`SecretStore` cache is disabled for the session, avoiding duplicate cache
|
||||
lifetimes. Relock drops this map before returning. Git credentials remain in
|
||||
the OS-backed store and are retrieved only through a currently valid handle.
|
||||
|
||||
## Activity and expiry
|
||||
|
||||
The shared TOML setting is:
|
||||
|
||||
```toml
|
||||
[security]
|
||||
inactivity_timeout_seconds = 120
|
||||
```
|
||||
|
||||
The default is 120 seconds; valid values range from 1 second through 24 hours.
|
||||
Frontends call `touch_user_activity` only for real keyboard, pointer, touch, or
|
||||
other intentional user input. Reading a secret, polling `remaining_time` or
|
||||
`expire`, refreshing repository state, performing Git work, and repainting do
|
||||
not move the deadline. This keeps presentation adapters from inventing their
|
||||
own activity heuristics or timeout arithmetic.
|
||||
|
||||
All access checks and relock transitions share one operation lock. At the exact
|
||||
deadline, either an operation finishes before relock or expiry wins and the
|
||||
operation observes a revoked handle; there is no check-then-use window into the
|
||||
secret store. Frontend timers may call `expire` to eagerly clean up at the
|
||||
deadline, while every handle operation also checks expiry before accessing a
|
||||
secret. The monotonic clock boundary is injectable so these cases remain fully
|
||||
deterministic in tests.
|
||||
|
||||
OS authentication cancellation is reported distinctly. Explicit `cancel`
|
||||
also revokes an active generation, which lets an abandoned authentication UI
|
||||
clean up through the same storage-owned path as manual lock.
|
||||
Reference in New Issue
Block a user