Bring your own keys
Use your provider agreements through the gateway and keep routing and evidence, priced by each BYOK endpoint's own published price.
How BYOK works
Store a provider secret once with POST /api/v1/credentials (credential:write — owner and security_admin; developers hold credential:read). It is encrypted at rest, decrypted just-in-time at dispatch, and never returned by any endpoint, audit row, event or log line. Every response carries only the summary: a fingerprint — the first 16 hex characters of sha256(secret), so you can check which key is stored — the last4 characters, the state, timestamps and the last provider error. A credential applies to every endpoint of that provider for the organization; there are no per-endpoint bindings.
# POST /api/v1/credentials (credential:write)
{ "provider": "anthropic", "name": "prod", "secret": "sk-ant-api03-…" }
# 201 CredentialOut — no field can hold the secret
{ "id": "cred_01J…", "provider": "anthropic", "name": "prod",
"provider_display_name": "Anthropic",
"fingerprint": "8f4e2a1b9c0d7e6f", "last4": "Q7xg", "state": "active",
"last_used_at": null, "last_error": null, "rotated_from_id": null, … }Routing follows the policy: allow_byok admits your credentials, and a request may narrow itself to them with yelno.credential_sources. A BYOK endpoint is eligible only while the organization holds an active credential for its provider — otherwise it is eliminated as byok_credential_missing (or credential_source_ineligible when BYOK is switched off). Every attempt in yelno.attempts names the credential_source it used, platform or byok.
// organization policy — PUT /api/v1/organizations/{id}/policy
{ "allow_byok": true }
// per request, optional — only your own credentials for this call
"yelno": { "credential_sources": ["byok"] }
// response: the credential source each attempt used
"attempts": [{ "sequence": 1, "provider": "openai", "region": "eu-west",
"credential_source": "byok", "state": "provider_completed" }]Rotation, testing and states
POST /api/v1/credentials/{id}/rotate with the new secret inserts a new active row (rotated_from_id = the old id) and revokes the old one in the same transaction — there is no overlap window; the next catalog snapshot binds the new credential. POST /api/v1/credentials/{id}/test is a write-only liveness probe: it never returns the secret, records last_used_at on success or last_error on failure, and never changes the state (method: "provider_probe" makes one authenticated model-list call against a fixed provider host; "format" checks the key shape in mock deployments). PATCH renames, disables, re-enables or marks a credential compromised; DELETE revokes it.
What you pay
BYOK requests are billed by the provider on your own account. Yelno rates them against the BYOK endpoint's own published customer price book — the price of routing, metering and evidence for that endpoint, shown on every request and invoice — with nothing added on top of the provider's own bill. Shared-pool requests are rated against the shared endpoint's published price book, which is the whole price.
Quota and health
Providers whose resale rights are byok_only are reachable only through your credentials; those with shared_capacity can also serve from the shared pool, and the source is labelled on each attempt; excluded providers cannot hold a credential at all. A provider 401 or 403 at dispatch disables the credential: the row moves from active to disabled, last_error records the provider's message (scrubbed of anything key-shaped), the audit row is credential.auth_failed and the credential.auth_failed event is emitted. Endpoint health and the circuit are untouched — the endpoint was not at fault. Re-enable the credential once the key is fixed, or rotate it.