Beta

Create a tenant

A new tenant starts with its own users, OAuth settings, audit history and logs. You are its first Tenant Admin.

BTL Admin

OPENID CONNECT · LAB

Sign out of one app and watch the tenant sign you back in

Reproduce the library computer problem with two clients in one tenant, see that local logout leaves the provider session running, then end the provider session yourself and see what survives.

ReadyUses your lab tenant

The lesson

Builds on: Offline access and refresh behavior.

New to the labs? Start with the lab toolkit and the shared cast and names every lab uses.

Partly ready. Most of this lab runs today. Steps that wait on platform features are marked, and Missing infrastructure says what they need.

Your progress

Press Start before you begin. Only events your tenant records after that count, in the order below. Checking reads your tenant's Audit, so you need Audit read access in it.

  1. Create the second app

    Recorded as tenant.oauth.clients.create succeeded.

  2. Sign in to the second app with no password

    Recorded as oauth.authorize succeeded (code_issued) for lab-tmp-slideshow about [email protected].

  3. Get signed back in to lab-collage after local logout

    Recorded as oauth.authorize succeeded (code_issued) for lab-collage about [email protected].

  4. Sign out at the tenant itself

    Recorded as account.sign_out succeeded (signed_out) about [email protected].

  5. See prompt=none fail once the provider session ended

    Recorded as oauth.authorize rejected (login_required) for lab-collage.

  6. Refresh the calendar connection after sign-out

    Recorded as oauth.token succeeded for lab-collage.

Setup

Single sign-on across two of your clients, local logout and the tenant's own sign-out are all real. ID tokens carry no sid and the tenant has no logout protocol yet (G17), which this lab shows rather than hides.

  1. Press Start. In Lab Photos, open OAuth > Clients and create lab-tmp-slideshow, a photo slideshow app: public, PKCE required, grant authorization_code, scopes openid profile, consent mode Remember, redirect URI http://127.0.0.1:8765/callback. Store its client ID:

source ~/btl-oidc.sh
SLIDES_ID="<lab-tmp-slideshow client ID>"
COLLAGE_ID=$CLIENT_ID COLLAGE_SECRET=$CLIENT_SECRET
  1. Run btl-lab callback before each request.

Walkthrough

  1. The connection that should outlive any sign-out. In a private window, sign in to lab-collage as Ava with offline access and keep its refresh token:

SCOPE="openid photos.read offline_access"
signin prompt=consent
redeem '<code>'
REFRESH_COLLAGE=$REFRESH; COLLAGE_ID_TOKEN=$ID_TOKEN

Why it matters: this is the yearly calendar connection, an authorization Ava granted, not a sign-in.

  1. Sign in to the second app in the same window.

CLIENT_ID=$SLIDES_ID CLIENT_SECRET="" SCOPE="openid profile"
signin
redeem '<code>'

No password page: a consent page the first time, then a code. The public client redeems with its client ID only.

Why it matters: one tenant session signs the browser in to every client of that tenant.

  1. Local logout of the collage app. Delete your local session record and the tokens the session held, then start a new collage sign-in:

unset COLLAGE_ID_TOKEN TOKEN ID_TOKEN
CLIENT_ID=$COLLAGE_ID CLIENT_SECRET=$COLLAGE_SECRET SCOPE="openid profile email"
signin

It completes with no password.

Why it matters: ending the session you control leaves the provider's session running, so the next person at this browser becomes Ava. Nothing was forged.

  1. Look for a way to name the provider's session.

part "$ID_TOKEN" | jq '{sid}'
curl -s "$ISSUER/.well-known/openid-configuration" | jq '{end_session_endpoint, frontchannel_logout_supported, backchannel_logout_supported, logout: .btl_endpoint_status["/oidc/logout"]}'

sid is null, there is no end_session_endpoint, and the logout endpoint's status is not_implemented.

Why it matters: without a provider session identifier there is nothing to name in a logout message.

  1. End the provider session yourself. Open $ISSUER/account in the private window and choose Sign out. Now signin prompt=none returns error=login_required for lab-collage, and the same for lab-tmp-slideshow.

Why it matters: only the provider can end the provider's session.

  1. See what survived. Refresh the calendar connection:

curl -s -u "$COLLAGE_ID:$COLLAGE_SECRET" "$ISSUER/oauth/token" -d grant_type=refresh_token --data-urlencode "refresh_token=$REFRESH_COLLAGE" | jq '{scope, refresh_token: (.refresh_token != null)}'

It succeeds. Keep the new refresh token in REFRESH_COLLAGE. The slideshow's local session would also still be inside its own deadlines, because nothing told it.

Why it matters: a sign-out should not cancel December's calendar, and other apps keep their sessions until their own timeouts or a logout message.

  1. Decide what Sign out means in your app and write it down: Sign out ends the local session only, and Sign out here and at Lab Photos ends the local session, then sends the browser to $ISSUER/account where the person can sign out themselves, until RP-initiated logout exists.

Why it matters: what logout means is a product choice, made openly, not a side effect.

Break it

  1. Treat sign-out as revocation. Write the calendar job so that it stops when the person signs out of the tenant. Step 6 shows the assumption is wrong: the tenant does not revoke the grant at sign-out. Disconnecting the calendar is a separate action, which your app offers on its own:

curl -s -u "$COLLAGE_ID:$COLLAGE_SECRET" "$ISSUER/oauth/revoke" --data-urlencode "token=$REFRESH_COLLAGE" -o /dev/null -w '%{http_code}\n'

Check your work

Press Check my progress. The checks look for the second client, a code for it with no new sign-in, a code for lab-collage after its local logout, Ava's sign-out at the tenant, a login_required answer afterward, and a successful refresh after the sign-out.

In Audit, the two codes after the first sign-in have no user_signed_in before them. That is single sign-on, seen from the provider.

Cleanup

  1. Revoke REFRESH_COLLAGE if Break it did not.

  2. Delete lab-tmp-slideshow.

  3. Set SCOPE="openid profile email".

Back to all labs

We value your privacy

We use cookies and similar technologies to enhance your browsing experience, and analytics to understand our traffic. By clicking "Allow All", you consent to optional analytics. Cookie Policy

The Lab