Test mode
A test key hits the same endpoint as a live one and reaches only test resources. Test traffic is free.
Every key is minted in an environment, test or live, and the environment is inside the key's hashed material. There is no code path in which a mis-set flag promotes a test key to live.
One endpoint, both environments
The shape the docs lead with is a single deployment that serves both. Declare your resources once, per environment, and the SDK hands each handler the right one for the calling key:
const keyring = new Keyring({
resources: { db: { live: liveDb, test: testDb } },
});
app.get('/v1/orders', (req, res) => req.keyring?.db.orders.findMany());The constructor refuses a resource named after a field of req.keyring, so resources: { env: ... } cannot shadow the one field the whole story reads from.
Code far from the request reads the environment from the ambient scope:
import { currentEnv } from '@keyring/sdk';
async function sendReceipt(order) {
if (currentEnv() === 'test') return;
}currentEnv() is null outside a request. That is deliberately not 'live': a background worker that was never told is the classic place a test receipt gets emailed to a real customer.
A deployment that serves one environment only sets env on the client and refuses the other outright.
Test traffic costs nothing
Billing counts active tenants per month from live requests only. A tenant that only ever sends test traffic is not counted, and the number is defined in one place in the control plane's schema, not recomputed anywhere.
The boundary on the control plane
A krsk_test_ secret key is the credential to give CI and staging. What it can do is a rule about the principal, not about which tables happen to have an environment column, and the control plane's test suite sweeps every registered route against it:
- It cannot name
liveon any request:403 forbidden. - It gets the ordinary
404for a live resource it names by id. - It sees no live row in any listing, including the audit log.
- It is read-only on projects, tenants and the workspace, and the workspace it reads has its billing email withheld.
- It is refused outright on
GET /v1/usage/billing,GET /v1/membersandGET /v1/invites.
A live secret key manages both environments. The asymmetry runs one way only.
Test keys in your usage data
A denied request is logged in the environment of the key that was refused, so "why is my test key rejected?" is answered from the test-mode usage, not lost in the live one.