Skip to content

Commit 9364261

Browse files
committed
Merge branch 'main' into feat/anonymous-sessions
# Conflicts: # README.md # src/auth0_server_python/auth_server/__init__.py # src/auth0_server_python/auth_server/server_client.py # src/auth0_server_python/auth_types/__init__.py
2 parents 090b798 + 75920ab commit 9364261

15 files changed

Lines changed: 3388 additions & 81 deletions

File tree

README.md

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,35 @@ The `AUTH0_SECRET` is the key used to encrypt the session and transaction cookie
5555
openssl rand -hex 64
5656
```
5757

58+
#### Authenticating with Private Key JWT
59+
60+
The SDK authenticates to Auth0 with either a client secret or a Private Key JWT (`private_key_jwt`). To use Private Key JWT, pass your private signing key as `client_assertion_signing_key` instead of `client_secret`:
61+
62+
```python
63+
from auth0_server_python.auth_server.server_client import ServerClient
64+
65+
with open('private_key.pem') as f:
66+
private_key = f.read()
67+
68+
auth0 = ServerClient(
69+
domain='<AUTH0_DOMAIN>',
70+
client_id='<AUTH0_CLIENT_ID>',
71+
client_assertion_signing_key=private_key,
72+
secret='<AUTH0_SECRET>',
73+
authorization_params={
74+
'redirect_uri': '<AUTH0_REDIRECT_URI>',
75+
}
76+
)
77+
```
78+
79+
The key must be a PKCS8 PEM private key. Register its public key on your Auth0 application under **Settings → Credentials**, and set the application's authentication method to Private Key JWT. The signing algorithm defaults to `RS256` and can be overridden with `client_assertion_signing_alg`. Auth0 accepts `RS256`, `RS384`, and `PS256`, all of which use an RSA key. The algorithm must match the key type and the algorithm chosen when the public key credential was created.
80+
81+
> [!NOTE]
82+
> The passkey challenge endpoints (`register` and `challenge`) accept only a client secret, so a client configured with just a signing key cannot use them.
83+
84+
> [!IMPORTANT]
85+
> Private keys must not be committed to source control. Load them from a secure secret store or an environment-provided file.
86+
5887
### 3. Add login to your Application (interactive)
5988

6089
Before using redirect-based login, ensure the `redirect_uri` is configured when initializing the SDK:
@@ -200,7 +229,11 @@ Let a logged-in user manage their own enrolled authentication methods — enroll
200229

201230
Bind tokens to a key your server holds ([RFC 9449](https://www.rfc-editor.org/rfc/rfc9449)) so a stolen token alone cannot be replayed. DPoP is supported for Passkey sign-in (`signin_with_passkey`) and the authentication-methods/factors methods on `MyAccountClient`. For key generation and usage, see [examples/Passkeys.md](examples/Passkeys.md#3-dpop-bound-passkey-tokens-optional) and [examples/MyAccountAuthenticationMethods.md](examples/MyAccountAuthenticationMethods.md#dpop).
202231

203-
### 10. Anonymous Sessions
232+
### 10. Passwordless Authentication
233+
234+
Sign users in with a one-time code sent by email or SMS, or with a magic link sent by email, via [Auth0 embedded passwordless login](https://auth0.com/docs/authenticate/passwordless/implement-login/embedded-login/relevant-api-endpoints). OTP verification and the magic-link callback each establish a server-side session like every other login path. For prerequisites, both flows, custom scopes/audiences, step-up MFA, and error handling, see [examples/Passwordless.md](examples/Passwordless.md).
235+
236+
### 11. Anonymous Sessions
204237

205238
Give a visitor an Auth0 `anon@<uuid>` identity before they log in, so cart/preference metadata attached pre-login is available to Post-Login Actions once they do. Requires a separate `anonymous_store` instance — never the same instance as `state_store` — and a tenant-level paid add-on flag. For setup, the token renewal ladder, login injection, and the store-isolation requirement, see [examples/AnonymousSessions.md](examples/AnonymousSessions.md).
206239

examples/MFA.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -545,15 +545,16 @@ The SDK does not store your private key, so you must re-supply it on the `verify
545545

546546
By default, `verify()` returns tokens without persisting them to the session store. However, you can automatically persist tokens by setting `persist=True`.
547547

548-
> [!WARNING]
549-
> `persist=True` **updates an existing session** — it does not create one. On a passkey-first login (`signin_with_passkey``MfaRequiredError`) no session exists yet, so `persist=True` raises `MfaVerifyError("No existing session found to update with MFA tokens")` and discards the tokens `verify()` just obtained. On that path, use `persist=False` (the default) and store the returned tokens yourself — see [Passkeys.md → Completing MFA on a passkey login](Passkeys.md#completing-mfa-on-a-passkey-login-and-where-the-session-comes-from).
548+
> [!NOTE]
549+
> `persist=True` updates an existing session when one is present. For first login MFA flows where the SDK has not created a session yet, `ServerClient.mfa` can create the initial session from the final MFA token response when that response includes an ID token.
550550
551551
### Automatic Session Update
552552

553553
When you set `persist=True`, the SDK will:
554-
1. Update the session's `access_token` for the specified audience
555-
2. Update the session's `id_token` if present
556-
3. Add the token to the `token_sets` array with expiration information
554+
1. Update an existing session, or create the initial session when the MFA flow completed a first login
555+
2. Persist the `access_token` for the specified audience
556+
3. Persist the `id_token` if present
557+
4. Add the token to the `token_sets` array with expiration information
557558

558559
```python
559560
verify_response = await server_client.mfa.verify(

examples/Passkeys.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ server_client = ServerClient(
4141

4242
The **Passkey** grant (`urn:okta:params:oauth:grant-type:webauthn`) must be enabled for your application under **Applications → Your App → Grant Types**.
4343

44+
> [!NOTE]
45+
> The passkey challenge endpoints accept a client secret only, not a client assertion. A client configured with just a `client_assertion_signing_key` (Private Key JWT) cannot use the passkey flows, so configure a `client_secret` to use them.
46+
4447
## 1. Passkey Signup
4548

4649
### Step 1 — Request a signup challenge

0 commit comments

Comments
 (0)