You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 9d5acfc
Browse filesBrowse the repository at this point in the historyBrowse files
The refresh flow in UltimateAuth is not a single fixed operation.
9
+
Refresh is how an existing authentication context continues without asking the user to authenticate again. In UltimateAuth, it is not synonymous with issuing a new access token: the operation depends on the active authentication mode and on whether the context is represented by a server-side session, refresh credentials, or both.
10
10
11
-
👉 It is a **mode-dependent continuation strategy**.
11
+
A successful refresh preserves the authenticated identity and its continuity. It does **not** prove the user's credentials again, create a new login, or necessarily extend every lifetime associated with the authentication.
12
12
13
-
## 🧠 What is Refresh?
14
-
In traditional systems:
13
+
## The model: continuity, not a second login
15
14
16
-
- Refresh = get a new access token
15
+
UltimateAuth distinguishes three related operations:
17
16
18
-
In UltimateAuth:
17
+
-**Authentication** establishes a new authenticated context after the required proof is accepted.
18
+
-**Refresh** attempts to continue an already established context, subject to its current validity and security policies.
19
+
-**Reauthentication** establishes trust again when continuation is unavailable or no longer permitted.
19
20
20
-
👉 Refresh continues an existing authentication state
21
+
This distinction matters for both security and client behavior. A refresh request can fail because a session expired, a refresh credential is invalid or consumed, the device context does not match, or the underlying chain is no longer usable. The client should treat an unsuccessful refresh as a need to authenticate again, not as an invitation to retry the same credential indefinitely.
21
22
22
-
> Refresh is not re-authentication
23
-
> → It is session continuation
23
+
## Mode-dependent strategies
24
24
25
-
## 🔀 Two Refresh Strategies
26
-
UltimateAuth supports two fundamentally different refresh behaviors:
25
+
UltimateAuth implements refresh through two building blocks: **session touch** and **refresh-token rotation**. A mode selects how they are combined.
|`PureOpaque`| Session ID | Validate session; touch when policy requires | Continue the existing session; no new access or refresh token |
30
+
|`Hybrid`| Session ID **and** refresh token | Validate and conditionally touch session; rotate refresh token | Continue session and issue replacement tokens |
31
+
|`SemiHybrid`| Session ID **and** refresh token | Validate session; rotate refresh token | Issue replacement tokens without a session touch |
32
+
|`PureJwt`| Refresh token | Validate and rotate refresh token | Issue replacement tokens; no session touch in the flow |
30
33
31
-
- No tokens involved
32
-
- No new session created
33
-
- Existing session is extended
34
+
**Current support status:**`PureOpaque` and `Hybrid` are the supported modes for the initial release. The `SemiHybrid` and `PureJwt` branches are present in the refresh implementation but should not be presented as completed, generally supported configurations in v0.1.0.
34
35
35
-
```
36
-
Session → Validate → Touch → Continue
36
+
The mode is resolved from the effective authentication context on the server. Clients do not select a refresh algorithm independently.
37
+
38
+
## Session touch
39
+
40
+
A session touch is a controlled update to existing server-side authentication state. It does not issue a replacement credential or create a new session.
41
+
42
+
```text
43
+
Session ID
44
+
→ Validate session, chain and device context
45
+
→ Recheck active state and chain/session relationship
46
+
→ Touch if policy requires
47
+
→ Continue with the same session ID
37
48
```
38
49
39
-
👉 This updates activity without changing identity
50
+
In `PureOpaque`, the refresh flow requires a session ID. The session validator checks the session against the current tenant, device context and session options. The touch service then reloads the session and chain from the store and checks that they are still active and consistent, including the chain's active session, tenant, user and chain identifiers.
40
51
41
-
### 🔹 Token Rotation (Stateless / Hybrid)
42
-
Used in:
52
+
Touch behavior is governed by the effective session options:
43
53
44
-
- Hybrid
45
-
- SemiHybrid
46
-
- PureJwt
54
+
-`TouchInterval` avoids writing activity state on every request. If the interval has not elapsed, the operation may succeed as **NoOp**.
55
+
-`TouchMode` is `IfNeeded` by default; `Force` requests a touch even when the normal interval has not elapsed.
56
+
-`SlidingExpiration` allows a touch to extend the session expiration using the configured `Lifetime`.
57
+
- An absolute chain expiration remains an upper bound; sliding expiration cannot extend the session beyond it.
58
+
-`IdleTimeout` participates in chain-state validation. An idle or otherwise inactive chain cannot be revived merely by touching it.
47
59
48
-
- Refresh token is validated
49
-
- Old token is revoked
50
-
- New tokens are issued
60
+
A successful **NoOp** is not a failed refresh: the existing state was valid, but no persistence update was necessary. Likewise, a touch is not an unconditional promise to extend the session's expiry; that depends on policy and the absolute limit.
51
61
62
+
## Refresh-token rotation
63
+
64
+
Rotation replaces a valid refresh credential while preserving its association with the existing authentication context.
65
+
66
+
```text
67
+
Refresh token
68
+
→ Validate token, tenant, device and expected session (if supplied)
69
+
→ Resolve user, session and chain
70
+
→ Prepare replacement refresh/access tokens
71
+
→ Atomically consume old refresh token and store replacement
72
+
→ Return new credentials
52
73
```
53
-
RefreshToken → Validate → Revoke → Issue New Tokens
54
-
```
55
74
56
-
👉 This ensures forward security
75
+
The rotation service first rejects modes or configurations that do not permit refresh-token issuance (`PureOpaque` or `IssueRefresh = false`). It then validates the presented credential and its context. The replacement refresh token and access token are prepared before the existing token is consumed. Persistence uses the refresh-token store's execution boundary and `TryConsumeAsync`, so competing requests cannot both successfully consume the same old token.
76
+
77
+
Rotation preserves the validated user, session and chain association; it is **not** a new authentication or a new session. Claims for the replacement access token are obtained through the configured claims provider.
57
78
58
-
<br>
79
+
### Reuse and concurrent requests
59
80
60
-
## ⚖️ Mode-Based Behavior
61
-
Refresh behavior is determined by the authentication mode:
81
+
A consumed refresh token cannot be used again to obtain another replacement. UltimateAuth distinguishes two situations:
62
82
63
-
| Mode | Behavior |
64
-
|-------------|-----------------------|
65
-
| PureOpaque | Session Touch |
66
-
| Hybrid | Rotation + Touch |
67
-
| SemiHybrid | Rotation |
68
-
| PureJwt | Rotation |
83
+
-**Likely concurrent request:** if a consumed token has a recorded replacement and the second request falls within `RefreshTokenConcurrentRequestWindow`, the second rotation is rejected without treating it as a confirmed replay.
84
+
-**Replay outside that window:** the rotation service revokes the associated refresh-token chain, or tokens associated with the session when a chain identifier is unavailable.
69
85
70
-
👉 UltimateAuth automatically selects the correct strategy.
86
+
This distinction reduces destructive responses to ordinary client-side concurrency while retaining a response to suspicious reuse. The concurrency window is **not** a grace period in which the old token may be exchanged again: the second request still fails.
71
87
72
-
<br>
88
+
The rotation implementation shown here revokes refresh-token state. Do not interpret that as an unconditional guarantee that every related server-side session is also revoked; session invalidation is a separate concern.
73
89
74
-
## 🔄 Step-by-Step Execution
90
+
## How each mode executes
75
91
76
-
### 1️⃣ Input Resolution
77
-
The system resolves:
92
+
### PureOpaque: session continuation
78
93
79
-
- SessionId (if present)
80
-
- RefreshToken (if present)
81
-
- Device context
94
+
`PureOpaque` has no refresh-token rotation step. The endpoint resolves the existing session from the authentication flow context, validates it and performs a conditional touch. It returns `Touched` when state was updated or `NoOp` when the valid session required no update.
82
95
83
-
### 2️⃣ Mode-Based Branching
84
-
The system determines the refresh strategy:
96
+
No access token or refresh token is issued. The existing session ID remains the credential representing the continued context.
85
97
86
-
- Session-based → Touch
87
-
- Token-based → Rotation
88
-
- Hybrid → Both
98
+
### Hybrid: session and token continuity
89
99
90
-
### 3️⃣ Session Validation
91
-
If session is involved:
100
+
`Hybrid` requires **both** a valid session ID and a refresh token. The flow:
92
101
93
-
- Session is validated
94
-
- Device binding is checked
95
-
- Expiration is evaluated
102
+
1. Validates the session and device context.
103
+
2. Performs the session touch operation according to policy.
104
+
3. Validates and rotates the refresh token, requiring it to match the expected session.
105
+
4. Returns the existing session ID together with replacement access and refresh tokens.
96
106
97
-
### 4️⃣ Token Validation (if applicable)
98
-
If refresh token is used:
107
+
The order is important: **session touch happens before token rotation** in the current implementation. These operations are not presented as one cross-store transaction. If rotation subsequently fails, the refresh response fails, although a preceding session touch may already have been persisted. This should not be described as an all-or-nothing operation.
99
108
100
-
- Token is validated
101
-
- Session and chain are verified
102
-
- Device consistency is checked
109
+
### SemiHybrid and PureJwt: implementation branches
103
110
104
-
### 5️⃣ Security Checks
105
-
The system enforces:
111
+
The current service includes branches for two additional modes:
106
112
107
-
- Token reuse detection
108
-
- Session validity
109
-
- Chain integrity
113
+
-`SemiHybrid` requires a session ID and refresh token, validates the session and rotates the token, but does not touch the session.
114
+
-`PureJwt` uses the refresh token for rotation without a session touch step in `RefreshFlowService`.
110
115
111
-
👉 If validation fails → reauthentication required
116
+
These describe the existing code paths, **not a promise of v0.1.0 production support**. Configuration validation and supported-mode documentation remain authoritative for which modes applications can enable.
112
117
113
-
### 6️⃣ Execution
114
-
Depending on the strategy:
118
+
## Request resolution and response delivery
115
119
116
-
#### Session Touch
117
-
- Updates `LastSeenAt`
118
-
- Applies sliding expiration
119
-
- No new tokens issued
120
+
The refresh endpoint uses the server's `AuthFlowContext`. It obtains the session ID from `flow.Session`, the device from `flow.Device`, and the refresh token through `RefreshTokenResolver`.
120
121
121
-
#### Token Rotation
122
-
- Revokes old refresh token
123
-
- Issues new access token
124
-
- Issues new refresh token
122
+
For refresh-token input, the resolver checks:
125
123
126
-
#### Hybrid Mode
127
-
- Validates session
128
-
- Rotates tokens
129
-
- Updates session activity
124
+
1. The explicit `X-Refresh-Token` header, if present.
125
+
2. The configured refresh cookie, when cookie delivery is active.
126
+
3. The configured refresh header, when header delivery is active.
130
127
131
-
### 7️⃣ Response Generation
132
-
The response may include:
128
+
The explicit header takes precedence. Header values may be supplied with a `Bearer ` prefix, which the resolver strips.
133
129
134
-
- SessionId
135
-
- Access token
136
-
- Refresh token
130
+
On success, the endpoint chooses a **primary credential** according to the refresh response policy, rather than automatically writing every credential returned by the flow. The refresh token is written separately when permitted by the response policy and when a replacement exists. Actual cookie/header placement is determined by the effective response configuration and client profile.
137
131
138
-
👉 Output depends on mode and client
132
+
The HTTP endpoint returns **`204 No Content`**on successful refresh and **`401 Unauthorized`** when continuation fails. Clients should obtain credentials from the configured response delivery mechanism rather than expecting a JSON token payload. When `Diagnostics.EnableRefreshDetails` is enabled, the endpoint also writes the refresh outcome through its diagnostic response writer.
139
133
140
-
<br>
134
+
> Response delivery customization is not fully independent in v0.1.0: mode templates and client-profile adaptation constrain the effective behavior. Do not assume every configured credential-delivery override is honored.
141
135
142
-
## 🔐 Security Model
143
-
The refresh flow includes strong protections:
136
+
## Outcomes and client expectations
144
137
145
-
### 🔁 Token Reuse Detection
146
-
If a refresh token is reused:
138
+
| Outcome | Meaning | Client interpretation |
139
+
| --- | --- | --- |
140
+
|`NoOp`| Existing session is valid; no touch was necessary | Continue normally |
141
+
|`Touched`| Existing session activity was updated | Continue normally |
142
+
|`Rotated`| Refresh token was consumed and replacement credentials issued | Replace stored credentials with the new values |
143
+
|`ReauthRequired`| The flow could not safely continue | Stop using the failed refresh credential and require authentication |
147
144
148
-
- Chain may be revoked
149
-
- Session may be revoked
145
+
`RefreshFlowResult` also recognizes `Success` as a successful outcome, although the mode-specific branches described above return `NoOp`, `Touched`, `Rotated` or `ReauthRequired`.
150
146
151
-
👉 This prevents replay attacks
147
+
Clients should serialize refresh attempts where practical. Parallel refresh requests using the same token do not produce multiple valid replacements, even when they fall within the concurrency window.
152
148
153
-
### 🔗 Session Binding
154
-
- Tokens are bound to session
155
-
- Session is bound to device
149
+
## Security boundaries
156
150
157
-
👉 Prevents token misuse across devices
151
+
Refresh continues existing trust only while the relevant state remains valid:
158
152
159
-
### 🧬 Chain Integrity
160
-
- Refresh operates within a chain
161
-
- Cross-device usage is rejected
153
+
-**Session and chain checks:** session-based paths validate active state, tenant, user, chain and session relationships.
154
+
-**Device context:** session and refresh-token validation receive the current device context; mismatches can prevent continuation.
155
+
-**Single-use refresh tokens:** successful rotation consumes the old credential and persists a replacement.
156
+
-**Replay response:** suspicious reuse can revoke refresh-token state associated with the chain or session.
157
+
-**Expiration:** idle, session, chain and refresh-token validity rules can end continuation. Refresh does not bypass those limits.
158
+
-**Issuance policy:**`IssueRefresh = false` prevents rotation before the old token is consumed.
162
159
163
-
<br>
160
+
These controls complement one another. A refresh token should be treated as a sensitive credential, not as a harmless request to generate another access token.
164
161
165
-
## 🧠 Mental Model
166
-
If you remember one thing:
162
+
## Summary
167
163
168
-
👉 Refresh = continuation
169
-
👉 Not new authentication
164
+
The useful distinction is not simply *stateful versus stateless*. It is **what must remain valid for authentication to continue**:
170
165
171
-
## 📌 Key Takeaways
166
+
-`PureOpaque` continues an existing server-side session, with conditional activity updates.
167
+
-`Hybrid` requires both session validity and successful refresh-token rotation.
168
+
- Other rotation branches exist, but are not part of the completed v0.1.0 supported-mode set.
172
169
173
-
- Refresh behavior depends on auth mode
174
-
- Stateful systems use session touch
175
-
- Stateless systems use token rotation
176
-
- Hybrid systems combine both
177
-
- Security is enforced at every step
170
+
Refresh does not authenticate a user again. It extends the usefulness of an already established authentication context only within the boundaries of the selected mode and configured security policies.
0 commit comments