Overview
Headless mode enables CCS to run in non-interactive environments:- CI/CD Pipelines - GitHub Actions, GitLab CI, Jenkins
- Automated Scripts - Cron jobs, batch processing
- Server-Side Tasks - Background workers, scheduled analysis
- No Browser Required - 7-day session tokens eliminate OAuth flow
How It Works
Session Persistence
When you authenticate via browser, CCS:- Obtains OAuth token (expires in ~1 hour)
- Stores refresh token (expires in 7 days)
- Creates session file (
~/.ccs/cliproxy/sessions.json) - Automatically refreshes tokens 5min before expiry
Headless Delegation Mode
- Skips interactive prompts - Returns error if auth needed
- Uses default profile - Or specify with first arg:
ccs gemini -p "prompt" - Outputs to stdout - JSON-parsable responses
- Exits with code - 0 = success, non-zero = failure
Prerequisites
- CCS installed on CI runner
- Initial authentication done (see Step 1)
- Session files accessible to CI environment
Authenticate Locally First
You cannot authenticate directly in CI - OAuth requires browser.On your local machine:This creates session files in
~/.ccs/cliproxy/:sessions.json- Session metadatagemini-{account}.json- OAuth tokens
Copy Session Files to CI
Option A: GitHub Actions SecretsBase64-encode session files:Add to GitHub secrets:Settings → CI/CD → Variables → Add variable:
- Go to repo Settings → Secrets → Actions
- Create secret
CCS_SESSIONSwith contents ofccs-sessions.b64
- Key:
CCS_SESSIONS - Type: File
- Value: (paste base64 content)
Handle Session Expiry
Sessions expire after 7 days. Options:Option A: Scheduled Re-AuthenticationCreate GitHub Action that runs weekly:Option B: Check and Exit GracefullyOption C: Remote Proxy (Recommended)Use Remote Proxy to centralize auth on server.
Configure Environment Variables
Control behavior via env vars:Security tip: Never log
CCS_PROXY_AUTH_TOKEN in CI output.Complete CI/CD Examples
GitHub Actions: Automated Documentation
GitLab CI: Code Quality Gate
Jenkins: Nightly Analysis
Environment Variables Reference
| Variable | Default | Purpose |
|---|---|---|
CCS_DEBUG | 0 | Enable verbose logging |
CCS_SKIP_PREFLIGHT | 0 | Skip API key validation |
CCS_WEBSEARCH_SKIP | 0 | Disable WebSearch hook |
CCS_PROXY_FALLBACK_ENABLED | 1 | Fallback to local proxy |
CCS_UNIFIED_CONFIG | 1 | Use unified config mode |
CCS_MIGRATE | 0 | Trigger auto-migration |
DISABLE_TELEMETRY | unset | Disable Claude telemetry |
DISABLE_ERROR_REPORTING | unset | Disable error reporting |
DISABLE_BUG_COMMAND | unset | Disable bug reporting |
Troubleshooting
Authentication Required
Symptom:[X] Auth error: No valid session found
Causes:
- Sessions not restored correctly
- Session files expired (>7 days)
- Wrong provider in headless command
Token Refresh Failed
Symptom:[X] Network error: UND_ERR_SOCKET
Causes:
- Firewall blocking OAuth endpoints
- Proxy configuration issues
- Network timeout
Session File Permissions
Symptom:[X] Config error: EACCES
Cause: Session files not readable by CI user
Solution:
Prompt Too Long
Symptom: Command line argument limit exceeded Solution: Use file redirection:Security Best Practices
Protect Session Files
- Encrypt in transit: Use secrets/variables, not environment variables
- Rotate regularly: Re-authenticate every 7 days maximum
- Scope access: Limit CI job permissions to necessary secrets
- Audit logs: Monitor secret access in GitHub/GitLab audit logs
Minimize Token Exposure
Use Self-Hosted Runners
For sensitive repos, use self-hosted runners:- Sessions stay on your infrastructure
- No need to upload to GitHub secrets
- Easier re-authentication workflow
