Overview
CCS implements sophisticated token management to provide seamless authentication:
Proactive Refresh - Tokens renewed 5min before expiry (no interruptions)
Session Persistence - Reference counting tracks active sessions
Automatic Recovery - Handles network errors, token expiry gracefully
Multi-Account Support - Separate tokens per account
Token Lifecycle
OAuth Flow (Initial Authentication)
┌─────────┐ ┌─────────┐ ┌──────────┐ ┌─────────┐
│ ccs CLI │────▶│ Browser │────▶│ Provider │────▶│ Consent │
└─────────┘ └─────────┘ │ OAuth │ │ Page │
▲ └──────────┘ └─────────┘
│ │
│ Access Token │
│ + Refresh Token │
└─────────────────────────────────┘
Files Created:
~/.ccs/cliproxy/gemini-{account}.json - Access + refresh tokens
~/.ccs/cliproxy/sessions.json - Session metadata
Proactive Token Refresh
CCS checks token expiry before every request :
Token expires at: 14:00:00
Current time: 13:54:00
Time remaining: 6 minutes
Action: Refresh now (threshold: 5 minutes)
Why 5 minutes?
Accounts for network latency
Prevents mid-request expiry
Ensures smooth user experience
Refresh Process:
Send refresh_token to provider
Receive new access_token (expires in 1 hour)
Receive new refresh_token (expires in 7 days)
Update {provider}-{account}.json
Continue with original request
Session Persistence
Session Files
Location: ~/.ccs/cliproxy/sessions.json
Structure:
{
"gemini" : {
"primary" : {
"email" : "user@gmail.com" ,
"tokenPath" : "~/.ccs/cliproxy/gemini-primary.json" ,
"expiresAt" : "2026-01-12T14:00:00Z" ,
"refreshedAt" : "2026-01-05T13:55:00Z" ,
"referenceCount" : 2 ,
"lastError" : null
}
}
}
Key Fields:
Field Purpose expiresAtAccess token expiry (1 hour from issue) refreshedAtLast refresh timestamp referenceCountNumber of active sessions using this token lastErrorMost recent error (for debugging)
Reference Counting
Purpose: Track multiple active CCS sessions reusing the same CLIProxy proxy/session state
How it works:
# Terminal 1
ccs codex "Task 1" # referenceCount: 1
# Terminal 2 (while Terminal 1 running)
ccs codex "Task 2" # referenceCount: 2
# Terminal 1 completes
# referenceCount: 1
# Terminal 2 completes
# referenceCount: 0
Why it matters:
Prevents premature token cleanup
Supports shared proxy sessions without tearing down token state too early
Tracks active usage
This is not the same thing as full per-session isolation. Multiple sessions
can reuse the same CLIProxy session/proxy state while still sharing provider
runtime state.
Session Cleanup
Automatic cleanup when:
referenceCount reaches 0
Session idle for >7 days
Manual logout via ccs codex --logout
Cleanup process:
Revoke refresh token with provider
Delete token file
Remove from sessions.json
Update accounts.json registry
File Structure
Token Files
Per-account token storage:
~ /.ccs/cliproxy/
├── gemini-primary.json # First account tokens
├── gemini-work.json # Second account tokens
├── codex-default.json # Codex tokens
└── agy-enterprise.json # Antigravity tokens
Token file format:
{
"access_token" : "ya29.a0AfB..." ,
"refresh_token" : "1//0gZ..." ,
"expires_at" : 1704463200000 ,
"token_type" : "Bearer" ,
"scope" : "email profile openid"
}
Account Registry
Location: ~/.ccs/cliproxy/accounts.json
Purpose: Map nicknames to email addresses
{
"gemini" : {
"primary" : {
"email" : "user@gmail.com" ,
"tokenPath" : "~/.ccs/cliproxy/gemini-primary.json" ,
"createdAt" : "2026-01-01T10:00:00Z" ,
"lastUsed" : "2026-01-05T14:30:00Z"
},
"work" : {
"email" : "work@company.com" ,
"tokenPath" : "~/.ccs/cliproxy/gemini-work.json" ,
"createdAt" : "2026-01-03T09:00:00Z" ,
"lastUsed" : "2026-01-05T11:15:00Z"
}
}
}
Config Reference
Location: ~/.ccs/config.yaml
Relevant sections:
cliproxy :
oauth_accounts :
primary : user@gmail.com
work : work@company.com
variants :
gemini :
account : primary # Default account for gemini
Manual Token Operations
View Token Status
Use the tokens command to inspect current state: Output: [i] OAuth Token Status
Gemini:
primary (user@gmail.com)
Status: Valid
Expires: 2026-01-05 15:30:00 (in 25 minutes)
Last Refreshed: 2026-01-05 14:25:00
Active Sessions: 1
work (work@company.com)
Status: Valid
Expires: 2026-01-05 16:00:00 (in 55 minutes)
Last Refreshed: 2026-01-05 14:50:00
Active Sessions: 0
Codex:
default (dev@example.com)
Status: Expired
Expires: 2026-01-05 13:00:00 (1 hour ago)
Last Refreshed: 2026-01-05 12:00:00
Active Sessions: 0
Note: Will auto-refresh on next use
Force Token Refresh
Manually trigger refresh without waiting for threshold: ccs tokens --refresh gemini
Use cases:
Debugging refresh issues
Pre-warming tokens before long task
Recovering from network errors
Clear Expired Tokens
Remove tokens that can’t be refreshed: This removes:
Tokens expired >7 days (refresh token expired)
Tokens with persistent errors
Orphaned session entries
Export Tokens (Advanced)
For migration or backup: ccs tokens --export gemini > gemini-backup.json
Security warning: Exported files contain sensitive tokens. Encrypt before storage:gpg -c gemini-backup.json
rm gemini-backup.json
Import Tokens (Advanced)
Restore from backup or migrate between machines: # Decrypt first
gpg -d gemini-backup.json.gpg > gemini-backup.json
# Import
ccs tokens --import gemini < gemini-backup.json
# Clean up
shred -u gemini-backup.json
Note: Only works for same provider. Cross-provider imports not supported.
Troubleshooting
UND_ERR_SOCKET Error
Full error:
[X] Network error: UND_ERR_SOCKET - The socket connection was aborted
Common causes:
Network interruption during refresh
# Check if provider auth endpoint is reachable
curl -I https://auth.openai.com
# Force new auth flow
ccs codex --auth
Proxy interference
# Bypass proxy for OAuth
unset HTTP_PROXY HTTPS_PROXY
# Re-authenticate
ccs codex --auth
Firewall blocking OAuth endpoints
# Test connectivity
curl -v https://auth.openai.com/authorize
# Whitelist required domains:
# - auth.openai.com
Concurrent refresh attempts
Multiple sessions trying to refresh simultaneously
Session files locked by another process
Solution:
# Wait a few seconds and retry
sleep 5 && ccs codex "Task"
Token Refresh Fails
Symptom: [X] Auth error: Failed to refresh token
Causes:
Refresh token expired (>7 days)
# Check session age
stat ~/.ccs/cliproxy/sessions.json
# Re-authenticate
ccs codex --auth
Provider revoked access
User revoked app permissions
Provider detected suspicious activity
Solution:
# Clear old tokens
ccs codex --logout
# Fresh authentication
ccs codex --auth
Clock skew
# Sync system time
sudo ntpdate pool.ntp.org
# Or manually set timezone
sudo timedatectl set-timezone America/New_York
Session File Corruption
Symptom: [X] Config error: Failed to parse sessions.json
Recovery steps:
# Backup corrupted file
cp ~/.ccs/cliproxy/sessions.json ~/.ccs/cliproxy/sessions.json.backup
# Remove corrupted file
rm ~/.ccs/cliproxy/sessions.json
# Re-authenticate (recreates session file)
ccs codex --auth
Prevention: Enable debug logging to catch issues early:
export CCS_DEBUG = 1
ccs codex "Test"
Multiple Accounts Conflict
Symptom: Wrong account used despite --use flag
Cause: Default account set in config overrides flag
Solution:
# Verify default account
grep -A5 "variants:" ~/.ccs/config.yaml
# Update default permanently
ccs codex --use correct-account
# Or override per-session
ccs codex --use correct-account "Task"
Token Not Found After Re-Auth
Symptom: [X] Profile error: Account 'xyz' not found
Cause: Account registry out of sync with token files
Solution:
# Rebuild account registry
ccs tokens --rebuild
# Or manually verify files
ls -la ~/.ccs/cliproxy/ * .json
cat ~/.ccs/cliproxy/accounts.json
Advanced Patterns
Pre-Warming Tokens
For long-running tasks, refresh tokens before starting:
#!/bin/bash
# Pre-warm all accounts
ccs tokens --refresh gemini
ccs tokens --refresh codex
# Now run long task without interruption
ccs codex "Analyze entire codebase in /project"
Monitoring Token Health
Create a cron job to check token status:
#!/bin/bash
# check-tokens.sh
STATUS = $( ccs tokens --json )
EXPIRED = $( echo " $STATUS " | jq -r '.[] | select(.status == "expired") | .account' )
if [ -n " $EXPIRED " ]; then
echo "⚠️ Expired tokens detected: $EXPIRED "
# Send notification
curl -X POST https://hooks.slack.com/... -d "{ \" text \" : \" CCS tokens expired: $EXPIRED \" }"
fi
# Crontab entry (check daily at 9 AM)
0 9 * * * /path/to/check-tokens.sh
Shared Team Tokens
For teams using Remote Proxy :
On server:
# Authenticate with team account
ccs codex --auth --nickname team-codex
# Verify token valid
ccs tokens --refresh team-codex
Clients automatically inherit server’s tokens - no local auth needed.
Environment Variables
Variable Purpose Example CCS_DEBUGShow token refresh logs export CCS_DEBUG=1CCS_SKIP_PREFLIGHTSkip token validation export CCS_SKIP_PREFLIGHT=1CCS_PROXY_FALLBACK_ENABLEDFallback behavior on token error export CCS_PROXY_FALLBACK_ENABLED=0
Security Best Practices
Protect Token Files
# Set restrictive permissions
chmod 600 ~/.ccs/cliproxy/ * .json
# Prevent accidental commits
echo "*.json" >> ~/.ccs/.gitignore
Rotate Tokens Regularly
# Logout all accounts
ccs codex --logout
ccs qwen --logout
# Re-authenticate with fresh tokens
ccs codex --auth
ccs qwen --auth
Recommended: Rotate every 30 days, or immediately if compromise suspected.
Monitor Token Usage
Enable request logging to track token usage:
# ~/.ccs/config.yaml
cliproxy :
logging :
enabled : true
request_log : true
Logs location: ~/.ccs/logs/cliproxy-requests.log
Next Steps
Multi-Account Setup Configure and switch between multiple accounts
Headless CI/CD Use persistent sessions in automation workflows