Identity and Keys
Every run is for somebody. A loop’s identity scheme decides how a user proves who they are, its delivery decides where they can reach it from, and an API key lets your own server start and read runs. Your users never have a plutonium.io account.
The public id
A loop gets its public id (pl_…) the first time you publish it, and keeps it for every
later version. On Loops, a loop’s Keys tab shows it. The public id names the loop to the world: the
embed, the SDK and the run API all use it. It is not a secret and not a credential. A run
started with it always runs the version that is published at that moment.
Identity schemes
A loop’s record declares one scheme in identity.kind.
| Scheme | Who the user is | What your side does |
|---|---|---|
anonymous | A visitor. Each browser gets its own identity, and nobody signs in. | Nothing. |
signed_assertion | A user your system has signed in. The id you give becomes the run’s subject. | Your server signs a JWT with the loop’s secret for each sign-in. |
oidc | A user your own OpenID issuer has signed in. | Your page passes on the id token your issuer gave the user. |
The user’s identity is the run’s subject. Per-user budgets and limits count against it, and Runs shows it for every run.
Limits on who may start runs
Each scheme carries limits in identity.limits:
per_ip— how many runs, sign-ins and searches one network address may make in a window, for example10/1m. They share one count, so a new visitor’s first conversation spends two.per_subject_runs— how many runs one user may start in a window, for example5/1d.
A user over a limit is refused with a sentence that says, in words, when to try again: “You can
try again in about 4 hours.” The Retry-After header carries the exact seconds.
A signed assertion
Your server signs a compact HS256 JWT with the loop’s secret. Its sub is your user’s id.
It is exchanged once at POST /api/loops/{publicId}/identities for a user token: an
assertion can be used only once, so mint a new one for each exchange.
An owner finds the secret on the loop’s Keys tab, under Signing secret, once the loop is published. Show the secret and Copy the secret read it; reading it again gives the same value.
To replace it, press Rotate…, then Rotate it. The old secret stops working at once: every assertion signed with it is refused from that moment, so put the new secret in your backend first. Rotating publishes a new version of the loop.
Your own OpenID issuer
With oidc, the record names your issuer and your client id. The id token must be signed
RS256 or ES256 with a key your issuer publishes, its iss must be the issuer, and its aud
must name the client id. Its sub becomes the run’s subject.
Identity in the API reference lists the routes and their answers.
Where users reach the loop
delivery in the record names how users reach the loop and from which sites:
delivery:
kinds: [embed] # embed, sdk, api
origins: [https://www.example.com]
api_key_scopes: []
originsare the sites the embed and the SDK may load on, each starting withhttps://. A frame on any other site is refused before a run starts. Publish refuses an origin that is plutonium.io’s own address rather than a site of yours.- A loop with no
kindshas no way in from outside your account. You can still try it from Chat.
Checking a user’s email
A loop can ask the user to prove an email address before it acts for them. Declare it in the
record’s checks as {kind: user_verification, method: email}. The run waits, the
user receives a code by email and types it into the chat, and the run goes on. The run checks the
address before the first step that writes or sends anything, and before its outputs leave. If
your identity scheme already gives an address, the code goes there.
The address and the code never reach a model. A tool can receive the checked address as an argument, without the model ever reading it.
API keys
An API key (rk_…) lets your server start and read runs of one loop. Only an owner of the
account can mint, see or revoke keys.
- Declare
apiin the loop’sdelivery.kinds, and list inapi_key_scopeswhat a key may do. - Publish the version.
- On Loops, open the loop and its Keys tab, tick the scopes, and press Mint a key.
- Copy the key, then press I have copied it. This is the only time it is shown. If it is lost, revoke it and mint another.
The scopes Keys offers are the ones the loop’s delivery allows:
| Scope | What a key with it may do |
|---|---|
create_runs | Start runs in this loop. |
read_runs | Read this loop’s runs and what they produced. |
read_collections | Read the collections this loop writes. |
To revoke a key, press Revoke… beside it on the loop’s Keys tab, then Revoke it. Anything that uses it stops working at once, and this cannot be undone.
Never put a key in a web page. Anyone who opens the page can read it, and it spends your account’s money. The embed and the SDK never need one.