OAUTH 2.0 · LAB
Delete a client and test which of its tokens stop working
Plan deletion through the configuration endpoint, then delete a client in the portal today and check its refresh token, introspection, UserInfo and a local JWT validation one by one.
PlannedUses your lab tenant
The lesson
Builds on: Registration access tokens.
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
- G40 Grant and consent inventory: list and revoke a user's app grants ("connected applications"), app approval policy, tenant-wide app block
Setup
Keep the shell variables from the earlier labs, and make sure
lab-photo-apiexists forbtl-lab introspect. Startbtl-lab callbackbefore the sign-in step.Planned (G9): the registered client from the previous lab allows the refresh grant (change the registration defaults for this lab), and you hold an access token and a refresh token for it, plus its
RCUandRAT.
Planned walkthrough
Delete the registration through its configuration endpoint.
curl -si -X DELETE "$RCU" -H "Authorization: Bearer $RAT" | grep -i -E '^HTTP|cache-control'
Expect 204 No Content with Cache-Control: no-store. Then delete your own copies: unset RAT REG.
Why it matters: "Deleting a registration". The client ID, its secret and its registration access token end together.
Send the same DELETE again. Expect
401. A cleanup job treats this as "already gone" and logs it.
Why it matters: a cleanup job must be safe to run twice.
Test each token as in Do today steps 4 to 7 below. The results are the same as for a client deleted in the portal.
Why it matters: "What happens to issued tokens". Deletion reaches everything the tenant checks, and nothing a resource validates on its own.
Do today
In OAuth > Clients, create
lab-tmp-review-482with the Web application preset: redirect URIhttp://127.0.0.1:8765/callback, grantsauthorization_codeandrefresh_token, scopesopenid offline_access photos.read. Store its credentials:export REVIEW_ID=<client_id>; read -rs REVIEW_SECRET; export REVIEW_SECRET.Run a code flow for it with
scope=openid offline_access photos.read, approve as Ava, and redeem the code.
RESP=$(curl -s -u "$REVIEW_ID:$REVIEW_SECRET" "$ISSUER/oauth/token" -d grant_type=authorization_code \
-d code=<code> --data-urlencode redirect_uri=$REDIRECT -d code_verifier=$VERIFIER)
TOKEN=$(jq -r .access_token <<<"$RESP"); REFRESH=$(jq -r .refresh_token <<<"$RESP"); unset RESP
btl-lab decode "$TOKEN" # note aud and exp
Delete
lab-tmp-review-482in OAuth > Clients. Audit showstenant.oauth.clients.delete.Try the refresh token.
curl -s -u "$REVIEW_ID:$REVIEW_SECRET" "$ISSUER/oauth/token" -d grant_type=refresh_token -d refresh_token=$REFRESH | jq .
The answer is 401 invalid_client: the client no longer exists.
Ask the tenant about the access token:
btl-lab introspect "$TOKEN"returns{"active": false}.Call UserInfo with it.
curl -s -o /dev/null -w '%{http_code}\n' "$ISSUER/oidc/userinfo" -H "Authorization: Bearer $TOKEN"
The answer is 401. Both checks reach the tenant, which knows the client is gone.
Now validate the token the way a resource that never calls the tenant would, using the
audyou noted in step 2.
btl-lab verify "$TOKEN" --issuer "$ISSUER" --audience <aud> --type at+jwt
The signature, issuer, audience and expiry all still check out. A self-contained token stays usable wherever it is validated locally until exp, which is why short access token lifetimes matter.
Fill in the lesson's "Three ways access ends" table from what you observed here and in earlier revocation labs. For the middle row, a person disconnecting the client, note that the tenant does not yet offer users a list of connected applications.
Break it
Once G9 exists, turn off deletion through the configuration endpoint in OAuth > Registration and send a DELETE for another registered client. Expect 405: the pipeline must remove the client another way, such as an administrator in the portal.
Restore: turn deletion through the configuration endpoint back on.
Check your work
Today, Audit shows tenant.oauth.clients.create and tenant.oauth.clients.delete for lab-tmp-review-482, oauth.token succeeded before the deletion, and the introspection by lab-photo-api. The refused refresh named a client that no longer exists, so it appears only in Logs. Once G9 exists, Audit also shows the configuration endpoint delete and the refused second DELETE.
Cleanup
Run
unset TOKEN REFRESH REVIEW_SECRET. The client is already deleted.Once G9 exists, remove any remaining registered lab clients and set the registration mode back to Off.
Missing infrastructure
G9: deletion through the configuration endpoint, with registration access tokens invalidated at the same moment, a tenant setting to allow or refuse it, and a stale-registration cleanup policy (expire registrations unused for a chosen number of days) for installations that never delete themselves.
G40: a list of connected applications where a person can disconnect a client, the middle row of the lesson's table.
Once these exist, the Planned walkthrough runs as written.