Install
openclaw skills install secure-api-callsClawHub Security found sensitive or high-impact capabilities. Review the scan results before using.
Call any API without leaking credentials. Keychains proxies requests and injects real tokens server-side — your agent never sees them.
openclaw skills install secure-api-callskeychains.dev is a credential proxy for AI agents. Instead of real API keys and OAuth tokens, you use placeholders like {{OAUTH2_ACCESS_TOKEN}}. Keychains injects the real credentials server-side — your agent never sees them.
npm install -g keychains@0.0.13
keychains curl https://api.github.com/user/repos \
-H "Authorization: Bearer {{OAUTH2_ACCESS_TOKEN}}"
keychains curl https://api.github.com/user/repos -H 'Authorization: Bearer {{OAUTH2_ACCESS_TOKEN}}'"keychains curl https://slack.com/api/chat.postMessage -X POST -H 'Authorization: Bearer {{OAUTH2_ACCESS_TOKEN}}' -H 'Content-Type: application/json' -d '{\"channel\":\"#general\",\"text\":\"Hello!\"}'"keychains curl https://api.stripe.com/v1/customers?limit=5 -H 'Authorization: Bearer {{STRIPE_SECRET_KEY}}'"keychains curl 'https://gmail.googleapis.com/gmail/v1/users/me/messages?maxResults=10' -H 'Authorization: Bearer {{OAUTH2_ACCESS_TOKEN}}'"keychains curl instead of curl. Put {{PLACEHOLDER}} where the credential goes.No credentials ever pass through the agent. The user controls everything from keychains.dev/dashboard.
npm install -g keychains@0.0.13~/.keychains/ with an Ed25519 SSH keypair)Put {{VARIABLE_NAME}} where you'd normally put the real credential — in headers, body, or query params.
| Prefix | Type | Examples |
|---|---|---|
OAUTH2_ | OAuth 2.0 | {{OAUTH2_ACCESS_TOKEN}}, {{OAUTH2_REFRESH_TOKEN}} |
OAUTH1_ | OAuth 1.0 | {{OAUTH1_ACCESS_TOKEN}}, {{OAUTH1_REFRESH_TOKEN}} |
| Anything else | API key | {{STRIPE_SECRET_KEY}}, {{OPENAI_API_KEY}} |
Keychains auto-detects the provider from the URL.
When keychains returns an approval link, show it to the user and poll:
keychains curl https://api.github.com/user/repos \
-H "Authorization: Bearer {{OAUTH2_ACCESS_TOKEN}}"
# → "Authorize at: https://keychains.dev/approve/abc123xyz"
keychains wait https://keychains.dev/approve/abc123xyz --timeout 800
keychains curl https://api.github.com/user/repos \
-H "Authorization: Bearer {{OAUTH2_ACCESS_TOKEN}}"
# → works now
For TypeScript/Node.js agents, @keychains/machine-sdk provides keychainsFetch() — a drop-in fetch() replacement with the same automatic registration and credential handling as the CLI.
npm install @keychains/machine-sdk
import { keychainsFetch, KeychainsError } from '@keychains/machine-sdk';
try {
const res = await keychainsFetch('https://api.github.com/user/repos', {
headers: { Authorization: 'Bearer {{OAUTH2_ACCESS_TOKEN}}' },
});
console.log(await res.json());
} catch (err) {
if (err instanceof KeychainsError && err.approvalUrl) {
console.log('Please approve:', err.approvalUrl);
}
}
| SDK | Install | Description |
|---|---|---|
| Python SDK | pip install keychains | Drop-in requests replacement. keychains.get(), keychains.post(), keychains.Session(). |
| Client SDK | npm install @keychains/client-sdk | TypeScript SDK for delegated environments (VMs, cloud functions). |
Full details: security whitepaper · privacy policy · terms of service
How proxying works: Your request (URL, headers, body) is routed through keychains.dev. The proxy replaces {{PLACEHOLDER}} variables with real credentials from the user's vault, forwards to the upstream API, and returns the response as-is. The proxy does not store or modify the response body.
Credential encryption: AES-256-GCM at rest. Only decrypted in memory at proxy time. Auto-deleted 90 days after last use. Never sold or shared.
Audit log: Every proxied request is logged (URL, method, provider, timestamp, status code). Archived to AWS S3 with Object Lock — immutable, tamper-proof. Configurable retention (30 days–3 years). Request/response bodies and credential values are never logged.
Local keys: On first run, an Ed25519 SSH keypair is generated in ~/.keychains/ (private key: 0600 permissions, never leaves the machine). Used for machine auth via SSH challenge-response. Rotate anytime with keychains machine rotate-keys.
Credential isolation: Real credentials live only in the user's vault on keychains.dev. Never sent to the agent. Bound to their provider (a GitHub token can only go to github.com).
Infrastructure: Vercel (app), Upstash Redis (ephemeral state), MongoDB Atlas (persistent, encrypted), AWS S3 (audit archival). All under data processing agreements.
User control: Biometric approval required for every credential use. Instant revocation per machine, provider, or agent. Full data export (JSON), account deletion, GDPR/CCPA compliant. No tracking, no ads, no data sales.
Got an approval link? Normal. Show it to the user, wait for approval, retry.
Template variable not replaced? You're using regular curl/fetch instead of keychains curl / keychainsFetch().
Tested with the following providers so far: