Skip to content

Commit 813fa56

Browse files
committed
UPDATE public OIDC protocol documentation with OP request-handling behaviour
Signed-off-by: ParleSec <mason@masonparle.com>
1 parent f6f4b26 commit 813fa56

1 file changed

Lines changed: 68 additions & 2 deletions

File tree

  • docs/starlight/src/content/docs/protocols

docs/starlight/src/content/docs/protocols/oidc.mdx

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ description: "Identity layer on OAuth 2.0 with ID tokens, discovery, and UserInf
3131

3232
| Path | Methods | Purpose |
3333
|------|---------|---------|
34-
| `/oidc/.well-known/openid-configuration` | GET | Discovery document |
34+
| `/.well-known/openid-configuration` | GET | Discovery document at the issuer root (canonical path a Relying Party derives from the issuer, OIDC Discovery 1.0 Section 4) |
35+
| `/oidc/.well-known/openid-configuration` | GET | Discovery document (prefixed alias, same content) |
3536
| `/oidc/.well-known/jwks.json` | GET | JSON Web Key Set |
3637
| `/oidc/jwks` | GET | JWKS alias |
3738
| `/oidc/authorize` | GET, POST | Authorization endpoint |
@@ -40,8 +41,73 @@ description: "Identity layer on OAuth 2.0 with ID tokens, discovery, and UserInf
4041

4142
## What To Validate
4243

43-
- ID token claims: `iss`, `sub`, `aud`, `exp`, `iat`, `nonce`, `at_hash`
44+
- ID token claims: `iss`, `sub`, `aud`, `exp`, `iat`, `auth_time`, `nonce`, `at_hash`, `c_hash`, `acr`, `amr`
4445
- Discovery fields: `issuer`, `authorization_endpoint`, `token_endpoint`, `jwks_uri`
4546
- JWKS: key type, algorithm, key ID alignment with token header
4647
- UserInfo: scope-dependent claims, subject consistency with ID token
4748
- Hybrid: multiple response types in a single authorization request
49+
50+
## Request Handling Notes
51+
52+
- Authorization errors after `client_id` and `redirect_uri` are validated are
53+
returned to the client by redirect (query for the code flow, fragment for
54+
implicit and hybrid), echoing `state` (RFC 6749 Section 4.1.2.1). Invalid
55+
`client_id` or `redirect_uri` is shown to the user agent and never redirected.
56+
- `prompt=none` returns `login_required` when no end-user session is present;
57+
`prompt=login` and an exceeded `max_age` force re-authentication and set
58+
`auth_time`.
59+
- Public clients must use PKCE: an authorization code request without a
60+
`code_challenge` is rejected (RFC 7636 Section 4.4.1).
61+
- Authorization codes are bound to the client they were issued to; a different
62+
client redeeming a code is rejected with `invalid_grant`.
63+
- Authorization codes are single-use. Replaying a code is rejected with
64+
`invalid_grant` and additionally revokes the access (and refresh) tokens that
65+
code already issued; the revoked access token is then rejected at UserInfo with
66+
`401 invalid_token` (RFC 6749 Section 4.1.2, RFC 6750 Section 3.1).
67+
- A token-endpoint client-authentication failure made over HTTP Basic returns
68+
`401` with a `WWW-Authenticate: Basic` challenge, and token-endpoint errors do
69+
not carry a Bearer challenge (RFC 6749 Section 5.2).
70+
- The authorization endpoint accepts requests by both `GET` and `POST`
71+
(OIDC Core 1.0 Section 3.1.2.1). A `POST` carrying authorization parameters is
72+
handled identically to `GET`; the interactive login form posts to the same
73+
path and is distinguished internally.
74+
- When the flow issues an access token (the code flow always does, as do the
75+
`id_token token` and hybrid flows), the scope-requested claims (`profile`,
76+
`email`, ...) are served from the UserInfo endpoint and are not duplicated in
77+
the ID token. They appear in the ID token only for the `response_type=id_token`
78+
case, where no access token is issued (OIDC Core 1.0 Section 5.4).
79+
- The UserInfo endpoint accepts the access token in the `Authorization: Bearer`
80+
header or, for a form-encoded `POST`, in an `access_token` body parameter
81+
(RFC 6750 Section 2). Presenting both in one request is an `invalid_request`.
82+
- The `request` and `request_uri` parameters are not supported. A request
83+
carrying `request` is rejected with `request_not_supported` and one carrying
84+
`request_uri` with `request_uri_not_supported` rather than being ignored
85+
(OIDC Core 1.0 Section 6.2.1, 6.3.1). Discovery advertises
86+
`request_parameter_supported` and `request_uri_parameter_supported` as `false`.
87+
- The `claims` request parameter is supported (OIDC Core 1.0 Section 5.5), and
88+
discovery advertises `claims_parameter_supported` as `true`. Claims requested
89+
under the `userinfo` member are returned from the UserInfo endpoint; claims
90+
requested under the `id_token` member are returned in the ID token. Every
91+
returned value is real data from the user record, and a value the user does
92+
not have is omitted rather than erroring (Section 5.5.1). A `claims` value that
93+
is not a valid JSON object is rejected with `invalid_request`.
94+
- The `profile` scope returns the full profile standard-claim set from UserInfo
95+
(`name`, `given_name`, `family_name`, `middle_name`, `nickname`,
96+
`preferred_username`, `profile`, `picture`, `website`, `gender`, `birthdate`,
97+
`zoneinfo`, `locale`, `updated_at`). Every value is real data held on the demo
98+
user record, not synthesised per request (OIDC Core 1.0 Section 5.4).
99+
- The `address` and `phone` scopes are also supported and advertised in
100+
`scopes_supported`. The `address` scope returns the structured `address` claim
101+
(OIDC Core 1.0 Section 5.1.1) as a JSON object with the populated members
102+
(`formatted`, `street_address`, `locality`, `region`, `postal_code`,
103+
`country`); blank members are omitted. The `phone` scope returns `phone_number`
104+
and `phone_number_verified` (Section 5.1). All values are real data held on the
105+
demo user record.
106+
- ID tokens carry `acr` and `amr` describing the authentication that actually
107+
happened: single-factor password, reported as `acr` `urn:protocolsoup:ac:password`
108+
and `amr` `["pwd"]` (OIDC Core 1.0 Section 2, RFC 8176). That value is advertised
109+
in `acr_values_supported`. The OP reports the context it genuinely performed and
110+
never echoes a higher assurance level (`1`, `2`, ...) requested via `acr_values`
111+
that it did not satisfy.
112+
- ID tokens are signed with RS256 only; the discovery metadata advertises only
113+
what the OP delivers.

0 commit comments

Comments
 (0)