Skip to content
Back to skills

899 Refresh Token E8379576

ASecurity

OAuth 2.0 Refresh Token Grant for obtaining new access tokens without user interaction.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
securitypythongobashapisecurity

Works with

  • cli
  • api

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 899-refresh-token_e8379576 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 899 Refresh Token E8379576?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 899 Refresh Token E8379576
[![Security: A โ€” Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-899-refresh-token-e8379576/badge)](https://www.skillsdirectory.com/skills/tools-only-899-refresh-token-e8379576)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# Refresh Token Flow Template

OAuth 2.0 Refresh Token Grant for obtaining new access tokens without user interaction.

## When to Use
- Access token has expired
- Extending session without re-authentication
- Background token renewal
- Any scenario requiring long-lived access

## Mermaid Template

```mermaid
%%{init: {'theme': 'base', 'themeVariables': {
  'actorBkg': '#ddd6fe',
  'actorTextColor': '#1f2937',
  'actorBorder': '#6d28d9',
  'signalColor': '#334155',
  'signalTextColor': '#1f2937',
  'noteBkgColor': '#f8fafc',
  'noteTextColor': '#1f2937',
  'noteBorderColor': '#334155'
}}}%%
sequenceDiagram
    autonumber

    box rgba(221,214,254,0.3) CLIENT APPLICATION
        participant A as ๐Ÿ–ฅ๏ธ Application
    end

    box rgba(167,243,208,0.3) SALESFORCE
        participant SF as โ˜๏ธ Salesforce<br/>Authorization Server
        participant API as ๐Ÿ“Š Salesforce<br/>REST API
    end

    Note over A,API: Refresh Token Flow (RFC 6749 Section 6)

    A->>API: 1. API Request with Access Token
    Note over A,API: Authorization: Bearer ACCESS_TOKEN

    API->>A: 2. 401 Unauthorized
    Note over API,A: {<br/>  "errorCode": "INVALID_SESSION_ID",<br/>  "message": "Session expired"<br/>}

    A->>A: 3. Detect Token Expiration

    A->>SF: 4. POST /services/oauth2/token
    Note over A,SF: grant_type=refresh_token<br/>client_id=CONSUMER_KEY<br/>client_secret=CONSUMER_SECRET<br/>refresh_token=REFRESH_TOKEN

    SF->>SF: 5. Validate Refresh Token
    Note over SF: โ€ข Token not revoked<br/>โ€ข Client matches original<br/>โ€ข Scopes still valid

    SF->>SF: 6. Generate New Access Token
    Note over SF: May also rotate<br/>refresh token

    SF->>A: 7. Return New Tokens
    Note over SF,A: {<br/>  "access_token": "NEW_TOKEN...",<br/>  "refresh_token": "ROTATED...",<br/>  "instance_url": "https://...",<br/>  "token_type": "Bearer",<br/>  "issued_at": "..."<br/>}

    A->>A: 8. Update Stored Tokens
    Note over A: Replace old tokens<br/>with new ones

    A->>API: 9. Retry API Request
    Note over A,API: Authorization: Bearer NEW_ACCESS_TOKEN

    API->>A: 10. โœ… Successful Response
```

## ASCII Fallback Template

```
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚     Application       โ”‚     โ”‚     Salesforce     โ”‚
โ”‚   (stored tokens)     โ”‚     โ”‚   (Auth Server)    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
            โ”‚                           โ”‚
            โ”‚  1. API Request           โ”‚
            โ”‚     (old access_token)    โ”‚
            โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€>โ”‚
            โ”‚                           โ”‚
            โ”‚  2. 401 Unauthorized      โ”‚
            โ”‚     (session expired)     โ”‚
            โ”‚<โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚
            โ”‚                           โ”‚
            โ”‚  3. POST /token           โ”‚
            โ”‚     grant_type=           โ”‚
            โ”‚       refresh_token       โ”‚
            โ”‚     refresh_token=XXX     โ”‚
            โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€>โ”‚
            โ”‚                           โ”‚
            โ”‚           4. Validate     โ”‚
            โ”‚              refresh tokenโ”‚
            โ”‚                           โ”‚
            โ”‚           5. Generate new โ”‚
            โ”‚              access token โ”‚
            โ”‚                           โ”‚
            โ”‚  6. New Tokens            โ”‚
            โ”‚     - access_token (new)  โ”‚
            โ”‚     - refresh_token       โ”‚
            โ”‚       (possibly rotated)  โ”‚
            โ”‚<โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚
            โ”‚                           โ”‚
            โ”‚  7. Retry API Request     โ”‚
            โ”‚     (new access_token)    โ”‚
            โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€>โ”‚
            โ”‚                           โ”‚
            โ”‚  8. Success โœ…            โ”‚
            โ”‚<โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚
```

## Token Request

```bash
curl -X POST https://login.salesforce.com/services/oauth2/token \
  -d "grant_type=refresh_token" \
  -d "client_id=YOUR_CONSUMER_KEY" \
  -d "client_secret=YOUR_CONSUMER_SECRET" \
  -d "refresh_token=YOUR_REFRESH_TOKEN"
```

## Response Example

```json
{
  "access_token": "00D5g000001ABC...!ARcAQNlBrLGj...",
  "refresh_token": "5Aep8617...",
  "instance_url": "https://mycompany.my.salesforce.com",
  "token_type": "Bearer",
  "issued_at": "1702123456789",
  "signature": "..."
}
```

## Code Example with Auto-Refresh

```python
import requests
from functools import wraps

class SalesforceClient:
    def __init__(self, client_id, client_secret, tokens):
        self.client_id = client_id
        self.client_secret = client_secret
        self.access_token = tokens['access_token']
        self.refresh_token = tokens['refresh_token']
        self.instance_url = tokens['instance_url']

    def refresh_access_token(self):
        """Refresh the access token using the refresh token."""
        response = requests.post(
            'https://login.salesforce.com/services/oauth2/token',
            data={
                'grant_type': 'refresh_token',
                'client_id': self.client_id,
                'client_secret': self.client_secret,
                'refresh_token': self.refresh_token
            }
        )

        if response.status_code == 200:
            tokens = response.json()
            self.access_token = tokens['access_token']
            # Handle potential refresh token rotation
            if 'refresh_token' in tokens:
                self.refresh_token = tokens['refresh_token']
            return True
        return False

    def api_request(self, endpoint, method='GET', **kwargs):
        """Make an API request with automatic token refresh."""
        url = f"{self.instance_url}/services/data/v59.0/{endpoint}"
        headers = {
            'Authorization': f'Bearer {self.access_token}',
            'Content-Type': 'application/json'
        }

        response = requests.request(method, url, headers=headers, **kwargs)

        # If token expired, refresh and retry
        if response.status_code == 401:
            if self.refresh_access_token():
                headers['Authorization'] = f'Bearer {self.access_token}'
                response = requests.request(method, url, headers=headers, **kwargs)

        return response

# Usage
client = SalesforceClient(
    client_id='YOUR_CONSUMER_KEY',
    client_secret='YOUR_CONSUMER_SECRET',
    tokens={
        'access_token': 'initial_access_token',
        'refresh_token': 'initial_refresh_token',
        'instance_url': 'https://mycompany.my.salesforce.com'
    }
)

# Automatic refresh on 401
response = client.api_request('sobjects/Account')
```

## Refresh Token Policies

### Connected App Settings

| Policy | Description |
|--------|-------------|
| `Refresh token is valid until revoked` | Never expires (default) |
| `Immediately expire refresh token` | Single use |
| `Expire refresh token if not used for N` | Idle timeout |
| `Expire refresh token after N` | Absolute timeout |

### Token Rotation

When configured, Salesforce may return a **new refresh token** with each refresh. Always check for and store the new refresh token:

```python
if 'refresh_token' in response:
    # New refresh token issued - old one is now invalid!
    stored_refresh_token = response['refresh_token']
```

## Error Responses

| Error | Cause | Solution |
|-------|-------|----------|
| `invalid_grant` | Refresh token revoked or expired | Re-authenticate user |
| `invalid_client` | Client credentials invalid | Check client_id/secret |
| `invalid_request` | Missing required parameter | Check request format |

## Key Characteristics

| Aspect | Value |
|--------|-------|
| User Interaction | None required |
| Token Rotation | May occur (check response) |
| Best Practice | Refresh proactively before expiration |
| Storage | Securely store refresh token |

## Proactive Refresh Strategy

```python
import time
import jwt

def should_refresh_token(access_token, buffer_seconds=300):
    """Check if token should be refreshed (5 min buffer)."""
    try:
        # Decode without verification to read exp claim
        decoded = jwt.decode(access_token, options={"verify_signature": False})
        exp_time = decoded.get('exp', 0)
        return time.time() > (exp_time - buffer_seconds)
    except:
        return True  # Refresh if we can't decode

# Proactive refresh before API call
if should_refresh_token(access_token):
    refresh_access_token()
```

## Security Considerations

1. **Store refresh tokens securely** - Encrypted storage, secure keychain
2. **Handle rotation** - Always update stored refresh token
3. **Implement revocation** - Revoke tokens on logout
4. **Monitor for abuse** - Track refresh token usage patterns
5. **Use HTTPS only** - Never send tokens over HTTP

## Revoking Tokens

When user logs out, revoke the refresh token:

```bash
curl -X POST https://login.salesforce.com/services/oauth2/revoke \
  -d "token=YOUR_REFRESH_TOKEN"
```

## Customization Points

Replace these placeholders:
- `CONSUMER_KEY` โ†’ Your Connected App's Consumer Key
- `CONSUMER_SECRET` โ†’ Your Connected App's Consumer Secret
- `REFRESH_TOKEN` โ†’ The refresh token from initial authorization

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading commentsโ€ฆ

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.