Keys and Reveal Policy
Tokenizing is safe to allow widely. Revealing is where plaintext leaves NoPII, so it is allowed only to the user a token belongs to, and every attempt is logged.
API keys
Create keys under API Keys in the admin console. The full key is shown once. NoPII stores only a hash of it.
| Kind | Prefix | Where it belongs | Notes |
|---|---|---|---|
| Secret | nsk_live_ | Your servers only | Mints client sessions and reveal grants |
| Publishable | npk_live_ | A web page | Requires a list of allowed origins |
| Device | ndk_ | An enrolled device | Issued by device enrollment |
Scopes
| Scope | Secret | Publishable | Device |
|---|---|---|---|
client_session:create | yes | no | no |
reveal_grant:create | yes | no | no |
tokenize | yes | yes | yes |
detokenize:own | yes | yes | yes |
detokenize:any | opt in | no | no |
proxy:forward | yes | yes | yes |
Privileged scopes requested for a publishable or device key are dropped rather than granted.
Publishable keys and origins
Anyone can read a publishable key out of your page, so its origin list is the only thing stopping someone else from using it. Entries are exact origins, such as https://app.example.com, or subdomain wildcards, such as https://*.example.com, which never match the bare domain.
Native apps send no Origin header, so they cannot use publishable keys. They use client sessions.
Client sessions
A client session is a short-lived token your server mints with its secret key and hands to the browser or app. It lasts 15 minutes by default and an hour at most, and can tokenize and reveal but never mint another session.
curl -X POST https://api.nopii.co/v1/client-sessions \
-H "Authorization: Bearer nsk_live_..." \
-H "Content-Type: application/json" \
-d '{"end_user_id": "user-42", "ttl_seconds": 900}'Always set end_user_id to your own user id. It is what the reveal policy checks. A session bound to one user cannot claim to be another, whatever the request body says.
Reveal policy
When a token is created, NoPII records who created it. A later reveal is allowed only when:
- the caller's end user created the token, or
- the token was created in the session the caller names, and that session does not belong to another end user, or
- the caller presents a reveal grant that covers the token, or
- the caller's key has
detokenize:any.
Each token gets its own answer: revealed, forbidden, purged, or not_found. A partial result is normal. The SDKs leave refused tokens in place, or show a placeholder you choose.
Sessions belong to users
The first end user to tokenize in a session owns it. Session ids travel to your backend and may end up in logs, but another user who learns one still cannot reveal anything with it.
Without end users, the session id is the only scope
conversation-123. Let the SDK generate them, or better, use client sessions bound to your users.If NoPII's shared cache is unavailable, reveals are refused rather than allowed. An outage can cost a user their history view, never another user's data.
Reveal grants
A reveal grant is temporary permission to reveal tokens the caller does not own, for support tools and other cross-user views. Your server creates it with a secret key.
| Field | Meaning |
|---|---|
subject_end_user_id | Covers every token this end user created |
tokens | Covers these specific tokens |
grantee_end_user_id | Who may use it, through their client session. Without it, only your secret key may. |
ttl_seconds | From 60 seconds to a day. 15 minutes by default. |
reason | Recorded with the grant, such as a ticket number |
The caller passes the grant id when revealing. A grant that is expired, revoked, from another tenant, or issued to someone else is refused. See the Node.js SDK for an example.
Reveal log
Every reveal attempt is recorded, one entry per token, refusals included: the outcome, the end user, the key or session, the client IP, and the grant if one was used. Refusals are kept because repeated refusals are how probing shows up.
Review it under Audit Log, on the Reveals tab, filtered by outcome, end user, token, grant, or date. The Reveal Grants tab lists grants and how often each was used.
Tokens-only mode
When your backend forwards tokenized messages to the proxy, send X-NoPII-Mode: tokens-only. The model is told what the tokens mean, and the reply stays tokenized, streamed tool call arguments included, so plaintext never reaches your servers on the way back. Anything the browser missed is still tokenized by the proxy, and stays revealable by the user whose session sent it.
Related
- SDKs: which tier keeps plaintext where
- Client API reference: every endpoint and error
- GDPR compliance: purged tokens can no longer be revealed