Authentication
How Unscrambled handles OAuth flows, API keys, and credential security
Authentication
Unscrambled supports two types of authentication: OAuth flows for services that use them, and API key storage for services that issue static keys. In both cases, credentials are encrypted and stored in Unscrambled's vault — they never exist in plaintext on your machine.
OAuth services
For OAuth-based services, Unscrambled manages the full flow: authorization URL, PKCE challenge, callback server, token exchange, and token refresh.
When you run this command:
- Unscrambled starts a temporary local callback server
- Your browser opens to the service's authorization page
- You approve the requested permissions
- The authorization code is exchanged for access and refresh tokens
- Tokens are encrypted and stored in the Unscrambled vault
- The local callback server shuts down
Token refresh happens automatically. When a token expires, Unscrambled uses the stored refresh token to obtain a new access token before your API call is made. You never see an auth error.
Supported OAuth services
| Service | Scopes requested |
|---|---|
| GitHub | repo, read:user, read:org |
| Slack | channels:read, chat:write, users:read |
| HubSpot | crm.objects.contacts.read, crm.objects.deals.read |
| Notion | Full access to workspace pages and databases |
| Salesforce | api, refresh_token |
| Figma | file_read |
| Linear | read, write |
| Jira | read:jira-work, write:jira-work |
| Varies by product (Drive, Sheets, Calendar, etc.) |
Custom OAuth scopes
You can request specific scopes when adding a service:
API key services
For services that use static API keys, Unscrambled prompts you once, encrypts the key, and stores it. The key is never written to disk on your machine.
Supported API key services
| Service | Key format | Where to generate |
|---|---|---|
| OpenAI | sk-proj-... | platform.openai.com/api-keys |
| Anthropic | sk-ant-... | console.anthropic.com/settings/keys |
| Stripe | sk_live_... / sk_test_... | dashboard.stripe.com/apikeys |
| Resend | re_... | resend.com/api-keys |
| Sendgrid | SG. | app.sendgrid.com/settings/api_keys |
| Cloudflare | API token | dash.cloudflare.com/profile/api-tokens |
Custom services
You can add any REST API by providing the auth configuration manually:
For custom OAuth services:
Managing credentials
List connected services
Remove a service
This revokes the token (where the service supports it) and deletes the encrypted credential from the vault.
Re-authenticate
If an OAuth token can't be refreshed (e.g., the refresh token was revoked), re-run the auth command:
It will replace the existing credential.
How credentials are secured
Unscrambled uses three-tier envelope encryption:
- Master key — Managed by AWS KMS, never leaves the HSM
- Account encryption key — Unique to your account, wrapped by the master key
- Data encryption key — Unique per credential, wrapped by your account key
The actual credential (OAuth token or API key) is encrypted with AES-256-GCM using the data encryption key. Decryption only happens in memory on the server, for the duration of an API call. Credentials are never logged, cached to disk, or included in error responses.
What is not stored on your machine
- OAuth access tokens
- OAuth refresh tokens
- API keys
- Client secrets
What is stored on your machine
- Your Unscrambled session token (in
~/.unscrambled/session.json) - A list of connected services (names only, no credentials)