# Credentials: sandbox and production, safely

> Key types and scopes, where to keep them, least privilege, rotation, and what never to do.

## Keys

| Prefix | Environment |
|---|---|
| `tph_test_` | Talo sandbox: test money |
| `tph_live_` | Talo production: real money |

Each key also has a **scope**:

| Scope | Can | Use it for |
|---|---|---|
| `read` | read payments, payment links, events, the account and its settings, balance and movements (when Talo allows them), keys and webhook URLs, readiness | dashboards, support agents, reports |
| `charge` | read + create payments + create and disable payment links + sandbox transfers + webhook pings | a checkout server, an agent that charges |
| `full` | everything, including refunds, price changes, keys and webhooks | the account owner, admin tasks |

Only a `full` key (or the dashboard) can create keys, of any scope; new keys default to `charge`. Requests outside the scope fail with `403 insufficient_scope`. The key `npx talo-hub login` stores is `full` (it's the person's own); registering webhooks and creating keys need `full`.

`TALO_HUB_API_KEY` is both the name your server reads and the CLI's override: if you export a project's `charge` key in your shell, the CLI uses it instead of your login, and commands that need `full` fail. Keep project keys in the project's env file only.

## Getting keys without exposing them

- **MCP with OAuth (best for agents):** add `https://talopartnerhub.vercel.app/api/mcp` with no header. The client runs OAuth in the browser; the person picks sandbox or production and the scope; the key goes straight to the client and never appears in the conversation.
- **CLI:** `npx talo-hub login` stores a personal key in the user's config (mode 600). `npx talo-hub keys create --name <project> --scope charge` creates a project key; add `--dotenv .env.local` to write it into that file, or `--vercel production|preview[:<branch>]` to store it as a Vercel Secret, so it never appears on screen. `webhooks add` takes the same flags for `TALO_HUB_WEBHOOK_SECRET`. Without them the value is printed once.
- **Dashboard:** API keys → Create.

## Rules

1. Keep keys in server-side environment variables or a secret manager (`TALO_HUB_API_KEY`), never in client code, the repo, logs, issues or chat messages. Add `.env*` to .gitignore. A payment's `checkout_token` (`ct_…`) is not a key: it only reads that payment's public view, so it may go to the browser for the widget.
2. One key per project and environment, named after it, so it can be revoked alone.
3. Use `charge` for checkout servers and agents; keep `full` for people.
4. Sandbox and production keys go in different environments of the deployment (for example Vercel Preview vs Production), never mixed.
5. Rotate: create the new key, deploy it, then `npx talo-hub keys revoke <old id>` (or DELETE /api/v1/api-keys/{id}). Revoke at once if a key leaks.
6. Webhook secrets (`whsec_…`) are shown once: store them like keys (`TALO_HUB_WEBHOOK_SECRET`).
7. Before any production refund, price change or new production key, confirm with the person: say the payment, the amount and what will happen.

## In CI

`TALO_HUB_API_KEY=tph_test_… npx talo-hub … --json`, with the key as a CI secret. Use sandbox keys in CI; production only in the deploy that serves real buyers.

---
Human page: https://talopartnerhub.vercel.app/docs/credentials · All pages: https://talopartnerhub.vercel.app/docs/index.md
