Documentation/Building Your App/Field Encryption
Field Encryption
How to encrypt sensitive field values yourself before they reach Supero, what Supero seals on your behalf and under what condition, and what to expect when you query encrypted data.
Overview
Supero does not have a schema flag that transparently encrypts a field for you — there is no
"encrypted": true property you can add to a schema field. If you need a value protected beyond Supero's normal transport and access controls, you encrypt it yourself on the client before it is ever sent, using a key you generate and hold.
There are two distinct encryption mechanisms in Supero, and they cover different things:- •Client-side field encryption — you enable it on your own API client and hold the key. You choose what to encrypt by choosing what values you pass through an encryption-enabled client. This section covers that mechanism.
- •Sealing of managed-integration credentials — when you configure a service from the managed services catalog (for example, an API secret key for a payment or messaging provider), the credential fields you enter are sealed at rest, provided the deployment key store is enabled. See the caveat below before you rely on it.
⚠️ Not a substitute for a compliance program
This page describes a data-protection mechanism, not a certification. Treat it as one control among several (access policy, RBAC, transport security, audit logging) rather than a checkbox for a specific regulatory standard.
Client-Side Field Encryption
Your generated Python SDK ships with a low-level API client (the
ApiLib class) alongside the high-level supero package. ApiLib accepts an enable_encryption flag and an encryption_key — a 32-byte AES-256 key that you generate and store yourself, for example in your own secrets manager. Supero never sees the key and cannot decrypt the data without it.python
from py_api_lib import ApiLib
# You generate and hold this key yourself (32 bytes, AES-256).
# Supero never sees it and cannot decrypt without it.
encryption_key = my_secrets_manager.get("patient-records-key")
client = ApiLib(
api_key="ak_live_...",
enable_encryption=True,
encryption_key=encryption_key,
)Once encryption is enabled on a client, every create, read, and update you make through that client encrypts field values before they leave your process and decrypts them again when you read them back. Encryption is applied to field values only — field names stay in plaintext so Supero can still validate that required fields are present and enforce your schema's shape.
A fixed set of fields is always kept in plaintext, regardless of the encryption setting, because Supero needs them to route, link, and display the record:
| Field | Why it stays plaintext |
|---|---|
| uuid | Primary identifier — used for every lookup |
| fq_name | Fully-qualified name — used for routing and hierarchy resolution |
| parent_type / parent_uuid | Used to resolve the record's place in the hierarchy |
| obj_type | Used to route the record to the correct schema |
| name | Kept searchable — avoid putting sensitive data directly in name |
| topic | Used for event routing |
On the wire and at rest, an encrypted value is a versioned ciphertext string in the form
ENC:v1:<base64>, and the record carries an _encrypted boolean. For example, a client with encryption enabled that creates a record ends up storing something like this:json
{
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"fq_name": ["healthcare-app", "patients", "john-doe"],
"obj_type": "patient",
"name": "John Doe",
"ssn": "ENC:v1:xK9mR3pL2nQ8rT5sB7uV4wX6yZ0aA1b...",
"diagnosis": "ENC:v1:pL2nQ8rT5sB7uV4wX6yZ0aA1bC3dE9f...",
"_encrypted": true,
"created_at": "2026-01-15T10:30:00Z",
"updated_at": "2026-01-15T10:30:00Z"
}Reading Encrypted Data
A client that reads a record marked
_encrypted but does not itself have encryption enabled (with the matching key) does not get back ciphertext disguised as a value — the read fails outright with an encryption error, naming the fields it could not decrypt. This is deliberate: it stops ciphertext from silently ending up in a UI, a log line, or a report as if it were the real value.🚨 There is no key recovery
Supero does not hold a copy of your encryption key and cannot decrypt your data if you lose it. There is no support-assisted recovery path. Treat the key with the same care as a production database credential.
⚠️ Encrypted values are not queryable
Because Supero only ever sees ciphertext, encrypted fields cannot be filtered, sorted, or matched in list or query calls — including exact-value matches. Each encryption uses a fresh random nonce, so encrypting the same plaintext twice produces two different ciphertexts, and Supero's schema validation checks that an encrypted field is present but skips validating its underlying type or pattern. Keep any field you need to filter, sort, or search on — status, category, dates, totals — outside the encrypted set.
Managed Integration Credentials
Separately from the client-side mechanism above, Supero seals the credential fields you provide when you configure a managed integration from the services catalog — for example, an API secret key for a payment or messaging provider.
It applies to that fixed set of integration-credential fields only. It is not a general-purpose mechanism you can point at your own schema fields — for that, use client-side encryption as described above.
🚨 Sealing is conditional, not automatic
This is the caveat to check before you put a real vendor credential anywhere. At-rest sealing requires the deployment key store to be enabled. It is not on by default, and when it is off, sealing is a pass-through: the value is stored in plaintext, with no error, no warning, and a record that looks identical through the API. On Supero Cloud the key store is managed for you. On a self-hosted or on-premise deployment, confirm it is enabled first — see Security and On-Premise Deployment.
Limits and Best Practices
- •Encryption is a client setting, not a schema property — there is no per-field "encrypted" flag in a schema definition.
- •Enabling encryption on a client is effectively all-or-nothing for the values that client writes; it isn't scoped per field in the schema. Choose what you send through an encryption-enabled client versus a plain one.
- •There is no built-in key-rotation workflow. To rotate a key, read your data with the old key and rewrite it with a new one.
- •You are responsible for generating, storing, and backing up the encryption key. Store it in a secrets manager, not in source code or a committed environment file.
- •Keep fields you need to filter, sort, or search on outside the encrypted set — see Reading Encrypted Data above.
- •Avoid putting sensitive data in a record's name field — it is always stored in plaintext.
Next Steps
- •Authentication — how to issue and scope the API keys your encryption-enabled client authenticates with
- •Schema Reference — the schema fields, types, and system fields referenced in the plaintext-field table above
- •Roles & Permissions Reference — who can read and configure records in your domain
- •Managed Integrations & Provider Catalog — how managed integration credentials get configured and sealed
On this page