Generating Tokens

Learn how to generate access tokens using different OAuth2 flows and configurations.


Quick Reference

TaskCommand
Get token with profileentra-auth-cli get-token -p PROFILE
Override scopeentra-auth-cli get-token -p PROFILE --scope "SCOPE"
Specify flowentra-auth-cli get-token -p PROFILE -f FLOW
Silent modeentra-auth-cli get-token -p PROFILE --silent
Save to fileentra-auth-cli get-token -p PROFILE -o token.txt
Refresh tokenentra-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:

  1. Profile loaded from ~/.entra-auth-cli/profiles.json
  2. Secrets retrieved from secure storage
  3. Authentication flow executed
  4. Access token printed to stdout

Specifying a Flow

Override the default flow:

  entra-auth-cli get-token -p my-profile -f ClientCredentials
  

Available flows:

  • ClientCredentials
  • AuthorizationCode
  • DeviceCode
  • InteractiveBrowser

Learn about flows →


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...
  

Detailed guide →


Interactive Browser Flow

User Authentication with Browser

  entra-auth-cli get-token -p user-app -f InteractiveBrowser
  

What happens:

  1. Browser opens to Entra ID login page
  2. User enters credentials
  3. User consents to permissions (if required)
  4. Browser redirects to localhost with code
  5. 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...
  

Detailed guide →


Device Code Flow

Authentication on Limited-Input Devices

  entra-auth-cli get-token -p iot-device -f DeviceCode
  

What happens:

  1. Tool displays code and URL
  2. User visits URL on another device
  3. User enters code
  4. User authenticates
  5. 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
  

Detailed guide →


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...
  

Detailed guide →


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"
  

Learn about scopes →


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

Detailed certificate guide →


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_access scope
  • 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:

  1. Go to Azure Portal → App registrations
  2. Select your app → API permissions
  3. Add the required permission
  4. 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:

  1. Verify API permissions in Azure Portal
  2. Grant admin consent
  3. 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

Next Steps