On this pageLeast privilege, made practical
The quickest way to let an agent pay for something is to hand it the company card number or the production API key. It works on the first day. On the day the prompt is injected or the logs are leaked, it is the whole account.
Least privilege, made practical#
Least privilege is an old idea. What makes it hard for agents is volume: a platform might run thousands of them, each needing slightly different permissions, and nobody will hand-write thousands of policies.
So we make the scope part of creating the credential. Every agent credential is minted from a policy template with three required fields: what it can spend on, how much, and until when.
The shape of a scoped credential#
- Merchant allowlist — the domains or merchant IDs the credential can pay. Anything else is declined at the network.
- Ceiling — a per-transaction and per-period limit, enforced before authorisation.
- Expiry — a hard end date. Credentials for one-off tasks can live for minutes.
- Environment — staging credentials cannot touch production balances, by construction.
Rotation without downtime#
Short-lived credentials only work if replacing them is boring. Each credential can have a successor issued before it expires; both are valid during a short overlap window, and the old one is revoked automatically when the new one is first used.
const next = await nebula.credentials.rotate('cred_7Hn2…', {
overlap: '10m',
})
// Hand `next.secret` to the agent; the old credential
// is revoked the first time `next` authorises.When one leaks anyway#
Assume it will. A leaked scoped credential can spend, at most, the remaining ceiling at the merchants on its allowlist until it expires — and every attempt outside that scope is logged with the merchant that tried. That is an incident you can size in a minute, rather than one you discover on the statement.
Never log credential secrets, even in debug output. Nebula secrets are prefixed nbsk_ so secret scanners can catch them in commits and logs.