refresh

Refresh expired or expiring access tokens using refresh tokens.

Synopsis

  entra-auth-cli refresh [flags]
  

Description

The refresh command obtains a new access token using a previously acquired refresh token. This is useful when you have a long-running process that needs to maintain valid tokens without user interaction.

Refresh tokens are only available when using delegated permissions (user authentication flows like interactive or device code).

Flags

Core Options

--profile, -p

Profile name to refresh tokens for.

  entra-auth-cli refresh --profile production
entra-auth-cli refresh -p dev
  

Default: default

--output, -o

Output format for the new token.

  entra-auth-cli refresh --output json
entra-auth-cli refresh -o yaml
  

Options:

  • token - Just the access token (default)
  • json - Full token response as JSON
  • yaml - Full token response as YAML

--silent, -q

Suppress all output except the token.

  TOKEN=$(entra-auth-cli refresh --silent)
  

Examples

Basic Usage

  # Refresh default profile
entra-auth-cli refresh

# Refresh specific profile
entra-auth-cli refresh --profile production
  

Output Formats

  # Token only
entra-auth-cli refresh

# Full JSON response
entra-auth-cli refresh --output json

# Get new access token in variable
TOKEN=$(entra-auth-cli refresh --silent)
  

Script Usage

  #!/bin/bash

# Check if token needs refresh
if ! entra-auth-cli inspect --profile myapp 2>/dev/null; then
    echo "Token expired, refreshing..."
    entra-auth-cli refresh --profile myapp
fi

# Use refreshed token
TOKEN=$(entra-auth-cli get-token --profile myapp --silent)
  

Requirements

Refresh Token Availability

Refresh tokens are only available with:

  • Interactive Browser Flow
  • Device Code Flow
  • Authorization Code Flow (web apps)

Refresh tokens are NOT available with:

  • Client Credentials Flow (service-to-service)

Offline Access Scope

For refresh tokens to work, the offline_access scope must be included:

  # When creating profile
entra-auth-cli config create --scope "User.Read offline_access"

# When getting initial token
entra-auth-cli get-token --scope "User.Read offline_access"
  

How It Works

  1. CLI retrieves stored refresh token for profile
  2. Sends refresh token to Microsoft Entra ID
  3. Receives new access token (and possibly new refresh token)
  4. Updates cached tokens
  5. Returns new access token

Output

Same formats as get-token:

Default (Token Only)

  eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1yNS1BVW...
  

JSON Format

  {
  "token_type": "Bearer",
  "scope": "User.Read Mail.Read",
  "expires_in": 3599,
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
  "refresh_token": "0.ARoAv4j5cvGGr...",
  "expires_at": "2025-12-28T16:30:00Z"
}
  

Exit Codes

CodeDescription
0Success
1General error
2Profile not found
3No refresh token available
4Refresh token expired/invalid
5Network error

Common Use Cases

Long-Running Process

  #!/bin/bash
set -euo pipefail

# Initial authentication
entra-auth-cli get-token --profile daemon --flow interactive

# Main loop
while true; do
    # Get token (uses cache if valid)
    TOKEN=$(entra-auth-cli get-token --profile daemon --silent)
    
    # Do work with token
    curl -H "Authorization: Bearer $TOKEN" \
      https://graph.microsoft.com/v1.0/me
    
    # Check if token expires soon
    EXPIRES=$(entra-auth-cli inspect --profile daemon --output json | jq -r .exp)
    NOW=$(date +%s)
    
    # Refresh if expiring within 5 minutes
    if [ $((EXPIRES - NOW)) -lt 300 ]; then
        echo "Token expiring soon, refreshing..."
        entra-auth-cli refresh --profile daemon
    fi
    
    sleep 60
done
  

Proactive Refresh

  #!/bin/bash

# Refresh before token expires
refresh_if_needed() {
    local profile="${1:-default}"
    
    if entra-auth-cli inspect --profile "$profile" &>/dev/null; then
        local expires=$(entra-auth-cli inspect --profile "$profile" --output json | jq -r .exp)
        local now=$(date +%s)
        local remaining=$((expires - now))
        
        # Refresh if less than 10 minutes remaining
        if [ $remaining -lt 600 ]; then
            echo "Refreshing token (expires in ${remaining}s)..."
            entra-auth-cli refresh --profile "$profile"
        fi
    else
        echo "Token invalid or expired, refreshing..."
        entra-auth-cli refresh --profile "$profile"
    fi
}

# Usage
refresh_if_needed production
TOKEN=$(entra-auth-cli get-token --profile production --silent)
  

Scheduled Refresh

  # Cron job to refresh tokens periodically
# Add to crontab: crontab -e

# Refresh every 30 minutes
*/30 * * * * /usr/local/bin/entra-auth-cli refresh --profile background-job

# Refresh at specific times
0 8,12,17 * * * /usr/local/bin/entra-auth-cli refresh --profile work-hours
  

Troubleshooting

No Refresh Token Available

Problem:

  $ entra-auth-cli refresh --profile myapp
Error: no refresh token available for profile 'myapp'
  

Cause: Profile uses client credentials flow (no refresh tokens)

Solution:

  # Client credentials profiles don't need refresh
# Just get a new token instead
entra-auth-cli get-token --profile myapp
  

Refresh Token Expired

Problem:

  $ entra-auth-cli refresh --profile user-app
Error: refresh token expired or invalid
  

Solutions:

  # 1. Re-authenticate with user flow
entra-auth-cli get-token --profile user-app --flow interactive --force

# 2. Or recreate profile
entra-auth-cli config delete --name user-app
entra-auth-cli config create --name user-app
entra-auth-cli get-token --profile user-app --flow interactive
  

Missing offline_access Scope

Problem: Refresh token not provided by Entra ID

Solution:

  # Include offline_access scope
entra-auth-cli get-token --profile myapp \
  --scope "User.Read offline_access" \
  --flow interactive

# Or update profile default scopes
entra-auth-cli config edit --name myapp
# Add "offline_access" to scopes
  

Automatic Refresh

The CLI automatically refreshes tokens when calling get-token if:

  1. Access token is expired or expiring soon
  2. Refresh token is available
  3. Profile was authenticated with user flow
  # First call - token expired, automatically refreshes
entra-auth-cli get-token --profile myapp

# You usually don't need to call refresh manually
# The get-token command handles it automatically
  

When to Use refresh Explicitly

Explicit refresh is useful when:

  1. Proactive refresh before expiration

      # Refresh before starting long operation
    entra-auth-cli refresh --profile myapp
    ./long-running-task.sh
      
  2. Testing refresh token validity

      if entra-auth-cli refresh --profile myapp; then
        echo "Refresh token is valid"
    else
        echo "Need to re-authenticate"
    fi
      
  3. Background refresh jobs

      # Keep tokens fresh in background
    while true; do
        entra-auth-cli refresh --profile daemon
        sleep 1800  # Every 30 minutes
    done
      

Refresh Token Lifetime

Refresh token lifetimes vary based on configuration:

TypeTypical Lifetime
Public Client90 days inactive / 24 hours active
Web App90 days inactive / Until revoked
Conditional AccessMay require re-auth periodically

Note: Refresh tokens can be revoked by:

  • User password change
  • Admin action
  • Security policies
  • Conditional Access policies

Security Considerations

Refresh Token Security

  # Refresh tokens are sensitive credentials
# - Never log or expose them
# - Store securely (CLI handles this)
# - Don't share across systems

# ✅ Good - CLI manages storage
entra-auth-cli refresh --profile myapp

# ❌ Bad - exposing refresh token
export REFRESH_TOKEN=$(...)  # Don't do this
  

Token Rotation

  # Some configurations rotate refresh tokens
# Old refresh token becomes invalid after use
# CLI handles this automatically

entra-auth-cli refresh --profile myapp
# CLI stores new refresh token automatically
  

See Also