Authenticate once, use credentials everywhere.
SigCLI opens a real browser for you to log in — any SSO, any site. It captures the session credentials, encrypts them locally, and makes them available to your scripts and AI agents on demand.
12You log in once sig stores credentials Your tools use them (real browser, any SSO) (encrypted, ~/.sig/) (sig request / run / proxy)
No passwords in shell history. No tokens in your repo. No manual copy-paste.
1npm install -g @sigcli/cli
Requires Node 18+. Then run sig init to detect your browser and create the config file.
1sig init
Pass any URL — sig opens a browser, you log in normally, sig captures the session:
1sig login https://jira.example.com
That's it. Check it worked:
1sig status
Now use the credentials:
1sig request https://jira.example.com/rest/api/2/myself
You can also pass credentials directly without opening a browser:sig login <url> --token <pat>
Four ways to use stored credentials, from most secure to least:
Make an authenticated HTTP request. Credentials never leave the process.
123456789101112sig request https://jira.example.com/rest/api/2/myself # POST with body sig request https://jira.example.com/rest/api/2/issue \ --method POST \ --body '{"fields":{"summary":"Bug"}}' \ --header "Content-Type: application/json" # Output formats sig request <url> --format body # response body only sig request <url> --format headers # response headers only sig request <url> --format json # full structured response
Run any command with credentials injected as environment variables. Sensitive values are automatically redacted from output.
12345678# Run a script with credentials sig run jira -- python fetch_issues.py # Multiple providers at once sig run jira slack -- python cross_tool.py # See what env vars are available sig run jira -- env | grep SIG_
Injected variables follow the pattern SIG_<PROVIDER>_COOKIE or SIG_<PROVIDER>_TOKEN.
Start a local proxy that injects credentials into any HTTP request transparently. Apps don't need any changes — just point HTTP_PROXY at it.
12345678sig proxy start # Then any tool works automatically: export HTTP_PROXY=http://127.0.0.1:7891 export HTTPS_PROXY=http://127.0.0.1:7891 curl https://jira.example.com/rest/api/2/myself sig proxy stop
Best for long-running processes, AI agents, and tools that fork many subprocesses.
Print credential headers to stdout. Use sparingly — values are exposed in your shell.
123sig get jira # JSON headers sig get jira --format value # raw cookie string sig get jira --format header # HTTP header format
Which one should I use?sig proxy — AI agents, daemonssig request — one-off API callssig run — wrapping scripts/toolssig get — debugging only
Everything lives in ~/.sig/config.yaml. Running sig login <url> auto-creates provider entries, so most users never edit this file manually.
1234567891011121314151617181920212223242526# ~/.sig/config.yaml version: 2 mode: browser browser: execPath: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome browserDataDir: ~/.sig/browser-data storage: credentialsDir: ~/.sig/credentials providers: jira: domains: - jira.example.com entryUrl: https://jira.example.com/ strategy: browser ttl: 10d extract: - from: cookies as: session match: "*" apply: - in: header name: Cookie value: "${session}"
The easiest way: just sig login <url> — sig auto-creates config. For manual setup, add a provider entry with these fields:
123456789101112131415my-service: domains: [example.com] # which URLs this provider handles entryUrl: https://example.com/ # URL opened for login validateUrl: https://example.com/api/me # optional: protected endpoint to verify credentials strategy: browser # use browser to authenticate loginMode: auto # optional: auto (default) | headless | visible ttl: 12h # how long credentials are valid extract: - from: cookies # what to capture (cookies or localStorage) as: session # name for the captured value match: "*" # which cookies (* = all) apply: - in: header # how to inject into requests name: Cookie value: "${session}" # reference the extracted value
Some apps store tokens in localStorage instead of cookies (Slack, Microsoft Teams). Use from: localStorage with a key pattern and optional jsonPath:
12345678910111213141516171819app-slack: domains: [your-org.enterprise.slack.com] entryUrl: https://app.slack.com/client/YOUR_TEAM_ID strategy: browser extract: - from: cookies as: session match: "*" - from: localStorage as: xoxc-token match: localConfig_v2 jsonPath: teams.YOUR_TEAM_ID.token apply: - in: header name: Cookie value: "${session}" - in: header name: Authorization value: "Bearer ${xoxc-token}"
Public sites set tracking cookies to all visitors. Add validateUrl pointing to a protected endpoint so sig can distinguish auth cookies from anonymous ones:
12345678910111213reddit: domains: [www.reddit.com, reddit.com] entryUrl: https://www.reddit.com/ validateUrl: https://www.reddit.com/prefs/friends strategy: browser extract: - from: cookies as: cookie match: "*" apply: - in: header name: Cookie value: "${cookie}"
sig probes validateUrl with extracted credentials — 2xx means logged in, 401/403 means not. SSO sites don't need this — redirect detection works automatically.
Tip: Use sig login <url> --as my-name to pick a custom provider ID instead of the auto-generated one.
For APIs that use OAuth2 Client Credentials grant — no browser needed. Configure client_id and client_secret once, sig manages token exchange, expiry tracking, and silent refresh automatically.
123456sig login https://api.example.com \ --strategy oauth2 \ --token-url https://auth.example.com/oauth/token \ --client-id my-client \ --client-secret my-secret \ --scope "read write"
Or interactively — just pass --strategy oauth2 and sig prompts for the rest:
12sig login https://api.example.com --strategy oauth2 # Prompts: Token URL, Client ID, Client Secret, Scopes
After setup, all commands work automatically:
123sig get my-provider # Bearer token (auto-refreshes if expired) sig request https://api.example.com/data # Injects Authorization header sig run my-provider -- curl https://api.example.com/data
1234567891011First login: 1. Store client_id + client_secret (encrypted at rest) 2. POST to token endpoint → receive access_token 3. Store access_token with TTL 4. Write provider config to ~/.sig/config.yaml Daily use (sig get / sig request): 1. Check stored access_token 2. If valid → inject Bearer header 3. If expired → silent re-exchange using stored secrets 4. No user interaction needed
After first login, config.yaml stores non-sensitive settings. Secrets live in the encrypted credential store:
1234567891011121314# ~/.sig/config.yaml (non-sensitive) my-api: domains: - api.example.com strategy: oauth2 oauth2: tokenUrl: https://auth.example.com/oauth/token scopes: - read - write apply: - in: header name: Authorization value: Bearer ${access_token}
Client ID and secret are stored only in the encrypted credential store — never in config.yaml.
1234567891011121314# Check status sig status my-provider # Force refresh (re-exchange token) sig login my-provider --force # Update client secret sig login my-provider --client-secret new-secret # Logout (clears token, keeps secrets for next refresh) sig logout my-provider # Remove everything (config + credentials) sig remove my-provider --force
OAuth2 flags:--strategy oauth2 — select strategy--token-url — token endpoint--client-id — client ID--client-secret — client secret--scope — space-separated scopes--network-proxy — proxy for token requests
Log in on your laptop, push credentials to headless servers over SSH.
123456789# On the server — set up without a browser: sig init --remote # On your laptop — add the remote and push: sig remote add prod user@server.example.com sig sync push prod # On the server — use credentials: sig run jira -- python deploy.py
Keep sessions alive automatically. The proxy daemon handles refresh in the background.
12345sig watch add jira # add to auto-refresh list sig proxy start # proxy also runs the refresh loop # Optional: auto-sync to remote after each refresh sig watch add jira --auto-sync prod
Run sig doctor first — it checks your browser, config, and permissions.
1sig doctor
validateUrl to your provider config pointing to a protected endpoint.sig login <url> --mode visible or set loginMode: visible in provider config.ttl or use sig watch add <provider> for auto-refresh.sig proxy trust to add the local CA to your system.sig init --remote + sig sync pull to get credentials from another machine.Add --verbose to any command for detailed error output.
Lightweight read-only SDKs for consuming credentials stored by the CLI. No browser, no config — just read the encrypted credential files and use the values in your code.
12npm install @sigcli/sdk # TypeScript/Node pip install sigcli-sdk # Python
12345678910111213141516171819202122import { SigClient, applyRules } from '@sigcli/sdk' const client = new SigClient() // Get credential (read + decrypt) const cred = await client.getCredential('my-jira') console.log(cred.values) // { cookie: "sid=abc; csrf=xyz" } // Apply template rules to get HTTP headers const { headers } = applyRules(cred.values, [ { in: 'header', name: 'Cookie', value: '${cookie}' } ]) // headers = { Cookie: "sid=abc; csrf=xyz" } // List all stored credentials const providers = await client.listProviders() // Watch for credential changes client.on('change', (providerId, credential) => { console.log(providerId, 'updated:', credential.values) }) client.watch()
123456789101112131415161718192021from sigcli_sdk import SigClient, apply_rules, ApplyRule client = SigClient() # Get credential (read + decrypt) cred = client.get_credential("my-jira") print(cred.values) # {"cookie": "sid=abc; csrf=xyz"} # Apply template rules to get HTTP headers rules = [ApplyRule(in_="header", name="Cookie", value="${cookie}")] result = apply_rules(cred.values, rules) # result.headers == {"Cookie": "sid=abc; csrf=xyz"} # Use with requests import requests response = requests.get("https://jira.example.com/rest/api/2/myself", headers=result.headers) # List all stored credentials for p in client.list_providers(): print(f"{p.providerId} ({p.strategy})")
SDK design:
The SDK reads credential files that the CLI writes to ~/.sig/credentials/. It handles AES-256-GCM decryption transparently. Use applyRules to replicate the CLI's template interpolation (${key} syntax).