Option 1 — Store the whole profile
UserCreate encrypts the entire profile as one record and returns a UUID token.
email, phone, login, custom:
UserCreateBulk to load many profiles in one call — see Migrating a SQL users table.
What you get
- Indexed lookup by
email,phone,loginandcustom, using secure hashed indexes. - App data for fields that do not belong in the profile.
AppdataCreateattaches a named JSON record to the user —"appname": "billing","appname": "preferences"— kept separate from the profile and readable on its own withAppdataGet. A user can have as many as you need. - Group membership.
GroupAddUserputs the user in a group, so you can organise users and scope access-control policies to a group rather than to individuals. - One licensed record per user, however many fields it holds. App data, consents, sessions and the full version history are all included in that one record, and a card stored inside the profile is not metered separately.
- Erasure in one call.
UserDeletewipes the profile; the token remains as an empty shell, lookups by email stop resolving, and anything derived from the profile stops returning data.UserDeleteBulkdoes the same for many users at once. - Everything else keyed to a user token: shared records, record versioning, consent agreements, data-subject requests, and a per-user audit trail.
What it costs you
- The four indexed fields must be unique.
email,phone,loginandcustomare what makes lookup possible, and no two users can share a value in any of them — a secondUserCreatewith an email already in use fails withDuplicate index: email. Two family members sharing one phone number cannot both carry it inphone; keep the shared value in an ordinary field, which has no such constraint. - The record is all or nothing. Anyone who can call
UserGetsees every field, unless you restrict them with an access-control policy.
Option 2 — Tokenize individual fields
TokenCreate tokenizes a single value. It has no connection to any user record. What comes back depends on the tokentype:
- A string — user name
- A credit card
string. It is stored under the canonical type name text, which TokenGet reports back and which you may also send instead.There is no tokenbase: a string has no format to preserve, so you get a UUID and nothing else. Store the tokenuuid in place of the name and detokenize it with TokenGet.unique: true deduplicates: the same input returns the same token instead of minting a new one. Use TokenCreateBulk for batches, and BulkListUnlock plus BulkListTokens to detokenize many at once.
Use
creditcard and string — between them they cover every field. Only creditcard returns a format-preserving tokenbase; string returns a UUID, so do not expect a look-alike value for a name or an address.The other types (unixtimestamp, uint32, uint64, email, ssn, uuid) are not recommended — they do not scale. See format-preserving tokenization.What you get
- Value-level granularity. A card number can live in a PCI-scoped system while the rest of the profile does not.
- Deduplication across the whole vault with
unique. - Format preservation for
creditcard, so legacy schemas and card validators keep working.
What it costs you
- Each token is a licensed record. Ten fields tokenized individually is ten records, where the same ten fields inside a profile is one. See what counts as a record.
- Erasure is yours to manage. The
tokenstable is not keyed by user token, soUserDeletedoes not touch these tokens and a data-subject erasure request will not reach them. Nothing links a token back to the user’s profile, and there is no index to search, so you must record the mapping yourself and delete withTokenDeleteorBulkDeleteTokens— or give each token an expiry, as below. Lose the mapping and only an expiry will ever remove the value. uniquemakes equal values linkable. The same input always yields the same token, so anyone holding two records can tell they carry the same value without detokenizing either. Leaveuniqueoff where that inference matters — see why shared records, not long-lived tokens.- Groups do not apply. Every group endpoint identifies its member by
modeandidentity— a user. A standalone token cannot be put in a group, so you cannot organise or query tokenized values that way. - No indexed lookup, no app data, no versioning, no agreements, no per-user audit trail — those all hang off a user record.
Share a single field, without a credential
If the goal is to let an outside party read one field of a profile, do not tokenize that field separately — create a shared record scoped to it.recorduuid to the consumer. Retrieving it needs no X-Bunker-Token — that is the point, the partner never receives a vault credential:
fields comes back. After finaltime the UUID stops resolving on its own, with no cleanup call. partner tags every retrieval in the audit trail. Repeat the call once per field to hand different fields to different consumers, each with its own expiry.
Add appname to share fields from one of the user’s app data records instead of the profile.
Expire data automatically
Neither option obliges you to delete anything by hand. BothUserCreate and
TokenCreate — and their bulk forms — accept an expiry at creation, after which the
record is gone without a call from you.
Two parameters, usable together:
The user record has expired and an expired
token reports Token not found. Indexed lookups stop resolving as well.
The same two parameters apply to FileCreate, SessionUpsert and the XTokenCreate
calls; SharedRecordCreate and AgreementAccept take finaltime only.
Expiry is the practical answer to the tracking problem in option 2. A standalone token is invisible to
UserDelete, but a token created with finaltime removes itself, so a retention limit does not depend on your bookkeeping being right. Give every per-field token an expiry unless you have a reason not to.Choosing
Store the whole profile for anything that is a user — it is the cheaper, more capable default, and it is what the PII vault is for.
Tokenize a field on its own when the value has to leave the user record: a card number crossing into a PCI-scoped system, or a value that must keep its original format for a legacy schema.
Mix them for the common case. Keep the profile in the vault, and tokenize only the one high-risk field separately, storing its
tokenuuid inside the profile:
UserDelete — delete it explicitly when erasing the user.
Related
- PII vault — how whole-profile tokenization works
- Format-preserving tokenization — token types, expiration, bulk operations
- Shared records — sharing a scoped, expiring view of a record
- Licensing and limits — what counts as a record