Generating Tokens
Generating Tokens
Learn how to generate access tokens using different OAuth2 flows and configurations.
Quick Reference
| Task | Command |
|---|---|
| Get token with profile | entra-auth-cli get-token -p PROFILE |
| Override scope | entra-auth-cli get-token -p PROFILE --scope "SCOPE" |
| Specify flow | entra-auth-cli get-token -p PROFILE -f FLOW |
| Silent mode | entra-auth-cli get-token -p PROFILE --silent |
| Save to file | entra-auth-cli get-token -p PROFILE -o token.txt |
| Refresh token | entra-auth-cli refresh -p PROFILE |
Basic Token Generation
Using a Profile
entra-auth-cli get-token -p my-profile
Output:
Authenticating with profile 'my-profile'...
✓ Token acquired successfully
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ij...
What happens:
- Profile loaded from
~/.entra-auth-cli/profiles.json - Secrets retrieved from secure storage
- Authentication flow executed
- Access token printed to stdout
Specifying a Flow
Override the default flow:
entra-auth-cli get-token -p my-profile -f ClientCredentials
Available flows:
ClientCredentialsAuthorizationCodeDeviceCodeInteractiveBrowser
Client Credentials Flow
Non-Interactive Service Authentication
entra-auth-cli get-token -p service-principal -f ClientCredentials
Requirements:
- Client secret or certificate configured
- Application permissions granted
- Admin consent completed
Example:
# Service principal for Graph API
entra-auth-cli get-token -p graph-sp -f ClientCredentials
Output:
✓ Token acquired successfully
eyJ0eXAiOiJKV1QiLCJh...
Interactive Browser Flow
User Authentication with Browser
entra-auth-cli get-token -p user-app -f InteractiveBrowser
What happens:
- Browser opens to Entra ID login page
- User enters credentials
- User consents to permissions (if required)
- Browser redirects to localhost with code
- Tool exchanges code for token
Example:
entra-auth-cli get-token -p personal-graph -f InteractiveBrowser
Output:
Opening browser for authentication...
✓ Authentication successful
✓ Token acquired
eyJ0eXAiOiJKV1QiLCJh...
Device Code Flow
Authentication on Limited-Input Devices
entra-auth-cli get-token -p iot-device -f DeviceCode
What happens:
- Tool displays code and URL
- User visits URL on another device
- User enters code
- User authenticates
- Tool polls and receives token
Example:
entra-auth-cli get-token -p headless-server -f DeviceCode
Output:
Device Code Authentication
To sign in, use a web browser to open:
https://microsoft.com/devicelogin
and enter the code: ABCD-1234
Waiting for authentication...
✓ Token acquired successfully
Authorization Code Flow
Web Application Authentication
entra-auth-cli get-token -p webapp -f AuthorizationCode
Requirements:
- Redirect URI configured in app registration
- Delegated permissions
- User credentials
Example:
entra-auth-cli get-token -p web-backend -f AuthorizationCode
Output:
Opening browser for authentication...
Redirect URI: http://localhost:8080
✓ Authorization code received
✓ Token acquired
eyJ0eXAiOiJKV1QiLCJh...
Scope Override
Runtime Scope Specification
Override profile’s default scope:
entra-auth-cli get-token -p myprofile \
--scope "https://graph.microsoft.com/User.Read Mail.Read"
Use cases:
- Different operations need different permissions
- Testing with minimal scopes
- Temporary scope changes
Multiple Scopes
Space-separated:
entra-auth-cli get-token -p myprofile \
--scope "https://graph.microsoft.com/User.Read Mail.Read Calendars.Read"
Comma-separated:
entra-auth-cli get-token -p myprofile \
--scope "https://graph.microsoft.com/User.Read,Mail.Read,Calendars.Read"
.default Scope
Request all configured permissions:
entra-auth-cli get-token -p myprofile \
--scope "https://graph.microsoft.com/.default"
Certificate Authentication
Using Certificates Instead of Secrets
entra-auth-cli get-token -p cert-profile -f ClientCredentials
Profile configuration:
{
"name": "cert-profile",
"clientId": "...",
"tenantId": "...",
"certificatePath": "/path/to/cert.pfx",
"useCertificate": true
}
Certificate password:
- Stored securely in platform-specific storage
- Prompted once during profile creation
- Never stored in plaintext
Advantages
✅ More secure than secrets
✅ Longer validity periods
✅ Better for automation
✅ Certificate rotation support
Output Options
Silent Mode
Suppress all output except the token:
entra-auth-cli get-token -p myprofile --silent
Output:
eyJ0eXAiOiJKV1QiLCJh...
Use in scripts:
TOKEN=$(entra-auth-cli get-token -p myprofile --silent)
curl -H "Authorization: Bearer $TOKEN" https://graph.microsoft.com/v1.0/me
Save to File
entra-auth-cli get-token -p myprofile -o token.txt
Output:
✓ Token saved to token.txt
Use later:
TOKEN=$(cat token.txt)
curl -H "Authorization: Bearer $TOKEN" ...
JSON Output
entra-auth-cli get-token -p myprofile --json
Output:
{
"accessToken": "eyJ0eXAiOiJKV1QiLCJh...",
"expiresOn": "2024-12-01T12:00:00Z",
"tokenType": "Bearer",
"scopes": ["https://graph.microsoft.com/.default"]
}
Token Inspection
Inspect Token Claims
# Generate and inspect in one command
entra-auth-cli get-token -p myprofile --silent | entra-auth-cli inspect
Or separately:
TOKEN=$(entra-auth-cli get-token -p myprofile --silent)
entra-auth-cli inspect -t "$TOKEN"
Output:
{
"aud": "https://graph.microsoft.com",
"iss": "https://sts.windows.net/...",
"iat": 1701432000,
"exp": 1701435600,
"appid": "12345678-1234-1234-1234-123456789abc",
"scp": "User.Read Mail.Read",
"roles": []
}
Learn about token inspection →
Token Refresh
Refreshing Expired Tokens
If you have a refresh token:
entra-auth-cli refresh -p myprofile
Requirements:
- Original token acquired with
offline_accessscope - Refresh token stored in cache
Output:
Refreshing token for profile 'myprofile'...
✓ Token refreshed successfully
eyJ0eXAiOiJKV1QiLCJh...
Note: Client Credentials flow doesn’t support refresh tokens. Just request a new token instead.
Learn about token refreshing →
Common Patterns
Pattern 1: Script Automation
#!/bin/bash
set -e
# Get token
TOKEN=$(entra-auth-cli get-token -p automation --silent)
# Use token
curl -H "Authorization: Bearer $TOKEN" \
https://graph.microsoft.com/v1.0/users \
| jq
Pattern 2: Environment Variable
export ACCESS_TOKEN=$(entra-auth-cli get-token -p myprofile --silent)
# Use in multiple commands
curl -H "Authorization: Bearer $ACCESS_TOKEN" https://api1.example.com
curl -H "Authorization: Bearer $ACCESS_TOKEN" https://api2.example.com
Pattern 3: Token Caching
TOKEN_FILE=~/.cache/entra-auth-cli-token.txt
# Check if token exists and is valid
if [ ! -f "$TOKEN_FILE" ] || ! entra-auth-cli discover -f "$TOKEN_FILE" &>/dev/null; then
entra-auth-cli get-token -p myprofile --silent > "$TOKEN_FILE"
fi
TOKEN=$(cat "$TOKEN_FILE")
Pattern 4: Multi-API Access
# Get tokens for different APIs
TOKEN_GRAPH=$(entra-auth-cli get-token -p graph-profile --silent)
TOKEN_AZURE=$(entra-auth-cli get-token -p azure-profile --silent)
# Use with different APIs
curl -H "Authorization: Bearer $TOKEN_GRAPH" https://graph.microsoft.com/v1.0/me
curl -H "Authorization: Bearer $TOKEN_AZURE" https://management.azure.com/subscriptions
Troubleshooting
“Profile not found”
Cause: Profile name is incorrect
Fix:
# List profiles
entra-auth-cli config list
# Use correct name
entra-auth-cli get-token -p correct-name
“AADSTS70011: Invalid scope”
Cause: Requested scope is not configured in app registration
Fix:
- Go to Azure Portal → App registrations
- Select your app → API permissions
- Add the required permission
- Grant admin consent (if needed)
“AADSTS7000215: Invalid client secret”
Cause: Client secret is expired or incorrect
Fix:
# Rotate secret in Azure Portal
# Update profile
entra-auth-cli config edit -p myprofile
# Select: Client Secret
# Enter: new-secret
“Insufficient privileges”
Cause: Token has scope but lacks underlying permission
Fix:
- Verify API permissions in Azure Portal
- Grant admin consent
- For users: Assign appropriate Azure AD role
“Browser did not respond”
Cause: Browser authentication timed out
Fix:
- Try Device Code flow instead:
entra-auth-cli get-token -p myprofile -f DeviceCode - Check redirect URI configuration
- Ensure localhost port is not blocked
Best Practices
✅ Use Appropriate Flows
- Automation: Client Credentials
- User apps: Interactive Browser
- Headless/SSH: Device Code
- Web apps: Authorization Code
✅ Request Minimal Scopes
# ❌ Over-privileged
--scope "https://graph.microsoft.com/.default"
# ✓ Minimal
--scope "https://graph.microsoft.com/User.Read"
✅ Handle Token Expiration
# Check expiration before use
entra-auth-cli discover -f token.txt
# Refresh if needed
if [ $? -ne 0 ]; then
entra-auth-cli get-token -p myprofile --silent > token.txt
fi
✅ Secure Token Storage
# Set restrictive permissions
TOKEN_FILE=~/.cache/my-token.txt
entra-auth-cli get-token -p myprofile --silent > "$TOKEN_FILE"
chmod 600 "$TOKEN_FILE"
❌ Avoid
- ❌ Hard-coding tokens
- ❌ Committing tokens to git
- ❌ Sharing tokens via email/Slack
- ❌ Using expired tokens
- ❌ Requesting excessive scopes