OIDC Scopes — Controlling Access to User Claims in OpenID Connect
In this tutorial, you will learn about OIDC Scopes. We cover key concepts, practical examples, and best practices to help you master this topic.
OIDC scopes are space-separated identifiers in the authentication request that determine which claims about the user are returned in the ID token and UserInfo response, with the openid scope being mandatory.
What You'll Learn
- The five standard OIDC scopes and the claims they return
- How scopes interact with the UserInfo endpoint
- Custom scopes for provider-specific claims
Why It Matters
Requesting unnecessary scopes makes the consent screen overwhelming and may reduce conversion rates. Requesting too few scopes means missing data requiring additional API calls. Understanding scopes helps you request exactly what you need.
Real-World Use
Doda Browser requests only openid profile email during sign-up. This returns name, avatar, and email — enough to create a profile. It does not request phone or address unless the user explicitly needs those features.
flowchart LR
AuthReq["Authorization Request\nscope=openid profile email"] --> Provider["OIDC Provider"]
Provider --> IDToken["ID Token\nsub, name, email, picture"]
Provider --> UserInfo["UserInfo\nname, email, picture, locale"]
style AuthReq fill:#dbeafe,stroke:#2563eb
Standard OIDC Scopes
scope_claims = {
"openid": ["sub"], # REQUIRED - no other claims without this scope
"profile": [
"name", "family_name", "given_name", "middle_name",
"nickname", "preferred_username", "profile", "picture",
"website", "gender", "birthdate", "zoneinfo", "locale",
"updated_at"
],
"email": ["email", "email_verified"],
"address": ["address"],
"phone": ["phone_number", "phone_number_verified"],
}
Building the Scope Parameter
import urllib.parse
def build_auth_url(client_id, redirect_uri, scope, provider_auth_endpoint):
params = {
"client_id": client_id,
"response_type": "code",
"scope": scope,
"redirect_uri": redirect_uri,
"state": "random-state-value",
"nonce": "random-nonce-value",
}
return f"{provider_auth_endpoint}?{urllib.parse.urlencode(params)}"
# Examples
minimal_url = build_auth_url(
client_id="my-app",
redirect_uri="https://app.com/callback",
scope="openid",
provider_auth_endpoint="https://provider.com/auth"
)
print(f"Minimal: {minimal_url}")
profile_url = build_auth_url(
client_id="my-app",
redirect_uri="https://app.com/callback",
scope="openid profile email",
provider_auth_endpoint="https://provider.com/auth"
)
print(f"Profile: {profile_url}")
Expected output:
Minimal: https://provider.com/auth?client_id=my-app&response_type=code&scope=openid&...
Profile: https://provider.com/auth?client_id=my-app&response_type=code&scope=openid+profile+email&...
Checking Available Claims After Authentication
def check_available_claims(id_token_claims, userinfo, requested_scopes):
available = {}
if "profile" in requested_scopes:
available["name"] = id_token_claims.get("name") or userinfo.get("name")
available["picture"] = id_token_claims.get("picture") or userinfo.get("picture")
if "email" in requested_scopes:
available["email"] = id_token_claims.get("email") or userinfo.get("email")
available["email_verified"] = id_token_claims.get("email_verified") or userinfo.get("email_verified")
if "address" in requested_scopes:
available["address"] = userinfo.get("address")
if "phone" in requested_scopes:
available["phone"] = userinfo.get("phone_number")
return available
Custom Scopes
Providers can define custom scopes:
# Google custom scopes
google_scopes = [
"https://www.googleapis.com/auth/drive.readonly", # Google Drive
"https://www.googleapis.com/auth/calendar", # Google Calendar
]
# Auth0 custom scopes
auth0_scopes = [
"read:users",
"write:users",
"admin",
]
# Combining OIDC and custom scopes
combined_scope = "openid profile email https://www.googleapis.com/auth/drive.readonly"
Common Mistakes
1. Forgetting the openid Scope
Without openid, the provider treats the request as plain OAuth2. No ID token is returned, and you cannot authenticate the user.
2. Requesting Too Many Scopes
Each scope adds claims to the ID token or UserInfo response. Excessive scopes slow down the token exchange and overwhelm the user's consent screen.
3. Assuming All Providers Support All Scopes
The address and phone scopes are optional. Check scopes_supported in the discovery document before requesting them.
4. Missing Scope for UserInfo Claims
If you request openid without profile, the UserInfo endpoint returns only the sub claim. Request the scopes that cover the claims you need.
5. Not Handling Missing Claims Gracefully
Even with the correct scope, some claims may be missing if the user did not provide that data. Always handle missing claims.
Practice Questions
- Why is the
openidscope mandatory for OIDC? - What claims does the
profilescope provide access to? - How do you request both identity and API access scopes?
- Why might a UserInfo response be missing claims even with the correct scope?
- How can you check which scopes a provider supports?
Answers:
- The
openidscope signals to the provider that this is an OIDC request and an ID token should be returned. profileincludes name, given_name, family_name, picture, birthdate, gender, zoneinfo, locale, and other basic profile data.- Combine OIDC scopes (
openid profile email) with API scopes (drive.file) in a single space-separated scope parameter. - The user may not have provided the data, or the provider may not support all claims within that scope.
- Check
scopes_supportedin the provider's discovery document at/.well-known/openid-configuration.
Challenge: Design a scope Strategy for a healthcare app that needs: user identity (name, email), medical records access, and calendar scheduling. Minimize the consent screen while meeting all requirements.
FAQ
Mini Project
Build a Python function that accepts a list of desired claims and returns the minimal set of OIDC scopes needed. For example, ["name", "email"] should return "openid profile email". Include validation against a provider's scopes_supported.
What's Next
Continue with Authentication Request to build complete OIDC authorization URLs, or explore OIDC Response Types for different token delivery methods.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro