Skip to main content

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:
  1. Obtains OAuth token (expires in ~1 hour)
  2. Stores refresh token (expires in 7 days)
  3. Creates session file (~/.ccs/cliproxy/sessions.json)
  4. Automatically refreshes tokens 5min before expiry
Result: Once authenticated locally, CI/CD can run for 7 days without re-auth.

Headless Delegation Mode

This mode:
  • Skips interactive prompts - Returns error if auth needed
  • Uses default profile - Or specify with first arg: ccs codex -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
1

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 metadata
  • gemini-{account}.json - OAuth tokens
Session expiry: 7 days from last token refresh.
2

Copy Session Files to CI

Option A: GitHub Actions SecretsBase64-encode session files:
Add to GitHub secrets:
  • Go to repo Settings → Secrets → Actions
  • Create secret CCS_SESSIONS with contents of ccs-sessions.b64
Option B: GitLab CI Variables
Settings → CI/CD → Variables → Add variable:
  • Key: CCS_SESSIONS
  • Type: File
  • Value: (paste base64 content)
Option C: Self-Hosted RunnerCopy directly to runner home:
3

Restore Sessions in CI

GitHub Actions:
GitLab CI:
Docker:
4

Use Headless Mode in Pipeline

GitHub Actions Example:
GitLab CI Example:
5

Handle Session Expiry

Sessions expire after 7 days. Options:Option A: Scheduled Re-AuthenticationCreate GitHub Action that runs weekly:
Option B: Check and Exit Gracefully
Option C: Remote Proxy (Recommended)Use Remote Proxy to centralize auth on server.
6

Configure Environment Variables

Control behavior via env vars:
Security tip: Never log CCS_PROXY_AUTH_TOKEN in CI output.
7

Parse Responses (Advanced)

Headless mode outputs raw AI response. Parse for CI:
Example: Extract action items

Complete CI/CD Examples

GitHub Actions: Automated Documentation

GitLab CI: Code Quality Gate

Jenkins: Nightly Analysis

Environment Variables Reference

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
Solutions:

Token Refresh Failed

Symptom: [X] Network error: UND_ERR_SOCKET Causes:
  • Firewall blocking OAuth endpoints
  • Proxy configuration issues
  • Network timeout
Solutions:

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

Next Steps

Remote Proxy

Centralize auth on server, avoid session expiry issues

Token Management

Deep dive into session persistence and refresh logic