OAUTH 2.0 · LAB
Read, modify and write back a client registration
Read a registration from its configuration endpoint, add a redirect URI with a full-replacement PUT, and see what a partial PUT would do. Today, compare the portal's protection against concurrent edits.
PlannedUses your lab tenant
The lesson
Builds on: Registering a client dynamically.
New to the labs? Start with the lab toolkit and the shared cast and names every lab uses.
Planned. The core of this lab waits on platform features that are not built yet. The planned walkthrough shows exactly how it will run; Do today is a real exercise you can do now.
- G9 Dynamic client registration and registration management
Setup
Keep the shell variables from the dynamic registration labs. Once G9 exists, you need a client registered through the API and its
REGresponse in the same shell.Planned (G9): in OAuth > Registration, turn management through the configuration endpoint On, with registration access token rotation On read and update.
Planned walkthrough
Save the two values the registration response gave you. Read the token without echoing it.
RCU=$(jq -r .registration_client_uri <<<"$REG")
read -rs RAT; export RAT # paste registration_access_token from the response
Why it matters: "The client configuration endpoint". The client uses the address exactly as given and never builds it from the endpoint and client ID itself.
Read the current registration.
CURRENT=$(curl -s "$RCU" -H "Authorization: Bearer $RAT")
jq 'del(.client_secret, .registration_access_token)' <<<"$CURRENT"
If the response carries a new registration_access_token, store it with read -rs RAT and discard the old one before doing anything else.
Why it matters: "Reading the current registration". Current is meant literally: an administrator may have changed the client since it registered.
Modify and write back the whole registration, leaving out the fields the server owns.
jq '.redirect_uris += ["http://127.0.0.1:8765/review-482/alt"] | del(.registration_access_token, .registration_client_uri, .client_id_issued_at, .client_secret_expires_at)' <<<"$CURRENT" \
| curl -s -X PUT "$RCU" -H "Authorization: Bearer $RAT" -H 'Content-Type: application/json' -d @- | jq .redirect_uris
Why it matters: "Replacing the registration". Read, modify, write: the body carries every field as the server last returned it, plus your one change.
Open Audit and OAuth > Clients. The update is recorded with the registration access token as the credential, and the client's existing tokens were revoked because its redirect URIs changed.
Why it matters: a change to where codes may go ends grants made under the old registration.
Do today
Call the configuration endpoint for a client ID.
curl -si "$ISSUER/oauth/register/$CLIENT_ID" | head -1
curl -si -X PATCH "$ISSUER/oauth/register/$CLIENT_ID" | grep -i -E '^HTTP|^allow'
The first answer is 501. The second is 405 with Allow: GET, PUT, DELETE: the endpoint selects the operation by method, exactly as the lesson describes, and PATCH is not one of them. Logs show oauth.registration_configuration rejected not_implemented and method_not_allowed.
Concurrent edits, done the tenant's way. In OAuth > Clients, create
lab-tmp-review-482with the Web application preset and redirect URIhttp://127.0.0.1:8765/review-482/callback. Open it in two browser tabs. In tab A, add the redirect URIhttp://127.0.0.1:8765/review-482/altand save. In tab B, add a different redirect URI and save.Tab B is refused with a message asking you to refresh before editing again. The portal sends the version it read, and the tenant rejects a write based on a stale read. RFC 7592 has no such check, so with the configuration endpoint the last write would silently win.
Audit shows
tenant.oauth.clients.updatesucceeded for tab A, and the refused update for tab B. Refresh tab B to see tab A's change.
Break it
These run once G9 exists.
Send a partial PUT, only
client_idandredirect_uris. The tenant treats every omitted field as a removal and refuses the result as unusable, with400 invalid_client_metadata, rather than leaving a client with no grants.Include a
client_secretyou made up. Expect400 invalid_client_metadata: a client can never choose its own secret.
Check your work
Today, Logs show oauth.registration_configuration rejected not_implemented and method_not_allowed, and Audit shows one successful and one refused tenant.oauth.clients.update for lab-tmp-review-482. Once G9 exists, Audit also shows the configuration endpoint read and update, and the Break it refusals.
Cleanup
Delete
lab-tmp-review-482in OAuth > Clients.Once G9 exists, keep the registered client and
RATfor the next lab.
Missing infrastructure
G9: the client configuration endpoint with GET, PUT and DELETE, registration access tokens with rotation, full-replacement validation that refuses unusable results, and revocation of existing tokens when the redirect URIs change. Once these exist, the Planned walkthrough runs as written.