# Documentation

## Why self-host?

By default, keychains.dev acts as both the credential manager _and_ the proxy — API calls flow through our servers where credentials are injected. For most users this is fine: credentials are encrypted in transit and never stored.

But if your threat model requires **zero-trust data isolation**, you can deploy a satellite proxy on your own infrastructure. Keychains.dev will only see metadata (which provider, which scopes). The actual tokens, API requests, and responses stay entirely on your servers.

### Without satellite proxy  
Your code → keychains.dev → Target API  
Credentials injected at keychains.dev

### With satellite proxy  
Your code → Your Proxy → Target API  
↑credentials  
keychains.dev  
Credentials resolved by keychains.dev, injected on _your_ servers

## Benefits & trade-offs

### Benefits

- +API request bodies and responses never leave your infrastructure
- +Full control over the proxy code (MIT licensed, ~200 LOC)
- +Comply with data residency requirements
- +Built-in end-to-end verification test before activation

### Trade-offs

- –You manage the deployment (Vercel makes this trivial)
- –Credential resolution adds a round-trip to keychains.dev
- –You're responsible for proxy uptime

## Quickstart

### 1. Deploy the proxy

Clone the open-source proxy and deploy to Vercel:

```terminal
git clone https://github.com/interagentic/keychains.dev_proxy && cd keychains.dev_proxy
npx vercel --prod

Vercel CLI 39.x
Deploying to production...
✓  Ready! Deployed to https://keychains-proxy-abc.vercel.app
```

### 2. Connect to your account

One command to verify and activate your proxy. It runs a full end-to-end test automatically — if the test fails, nothing is saved.

```terminal
npx -y keychains@latest proxy set https://keychains-proxy-abc.vercel.app

Checking proxy server health and version...
  200 keychains-proxy v0.1.0

Running end-to-end proxy test...

1. Initializing test on keychains.dev... OK (test a1b2c3d4...)
  2. Sending proxied request through keychains-proxy-abc.vercel.app... OK
  3. Verifying values on keychains.dev... OK

✓ header_oauth   a1b2c3d4...    ✓ query_oauth    m3n4o5p6...
    ✓ header_apikey  e5f6g7h8...    ✓ query_apikey   q7r8s9t0...
    ✓ header_custom  i9j0k1l2...    ✓ query_custom   u1v2w3x4...
    ✓ body_oauth     y5z6a7b8...    ✓ body_apikey    c9d0e1f2...
    ✓ body_custom    g3h4i5j6...

✓ All 9 test values passed through the proxy correctly.

✓ User account <you@example.com> now uses remote proxy
    https://keychains-proxy-abc.vercel.app for all API calls.
```

### 3. Use as normal

Your existing code works unchanged. All SDKs automatically route through your proxy.

```python
$ import keychains

$ repos = keychains.get("https://api.github.com/user/repos")
$ print(repos.json())
```

## How the end-to-end test works

The test verifies the **complete credential resolution pipeline**, not just HTTP forwarding. Here's what happens:

1.  CLI generates **9 random strings** and stores them on keychains.dev under a test ID
2.  CLI sends a request through your proxy with `{{placeholder}}` templates in headers, query params, and body
3.  Your proxy detects the placeholders and calls `resolve-and-fetch` on keychains.dev
4.  keychains.dev recognizes the test URL, fetches the stored random values, and returns them as “credentials”
5.  Your proxy replaces all `{{...}}` templates with the resolved values and forwards the request
6.  CLI reads the echoed values from keychains.dev and compares — all 9 must match

This exercises the _entire_ pipeline: placeholder extraction, credential resolution API call, placeholder replacement, request forwarding, and response delivery. It lets us verify your proxy is working correctly **before sending any real secrets or confidential data to it**.

## Security model

The satellite proxy is intentionally simple — a thin passthrough. **keychains.dev remains the sole authority** over which credentials are released and for which APIs.

| Proxy controls                     | keychains.dev controls                       |
|------------------------------------|----------------------------------------------|
| Extracting placeholder names         | Resolving domain → provider                  |
| Replacing {{...}} with values       | Inferring OAuth scopes from URL              |
| Forwarding the request              | Validating permission chains                  |
|                                    | Deciding which credentials to return         |
|                                    | Never returning refresh tokens                |

Even if the proxy code is modified, it cannot override provider resolution, inflate scopes, obtain refresh tokens, or request credentials for unrelated providers. The proxy submits only three things: target URL, HTTP method, and placeholder names.

## Managing your proxy

```terminal
# Check current configuration
npx -y keychains@latest proxy get

Proxy URL   https://keychains-proxy-abc.vercel.app
  Status      active

# Re-run the end-to-end test
npx -y keychains@latest proxy test

# Test a different proxy URL without saving
npx -y keychains@latest proxy test https://other-proxy.vercel.app

# Remove satellite proxy
npx -y keychains@latest proxy clear

✓ Satellite proxy removed. Requests go through keychains.dev directly.
```

You can also manage the proxy URL from the dashboard settings page. Machines pick up proxy URL changes automatically on their next authentication.

### Open source

The satellite proxy is ~200 lines of TypeScript under the MIT license. Inspect the code, audit it, or fork it for your needs.

[View on GitHub](https://github.com/interagentic/keychains.dev_proxy)
