Skip to main content

Design application cryptography

Select a standard construction and define keys, nonces, context, record format, failure behavior, tests, and migration before coding.

Learning outcomes

  • Derive the cryptographic requirement from a precise threat and data boundary.
  • Select a maintained protocol or high-level construction instead of composing primitives.
  • Define key, nonce, associated-data, serialization, error, and version behavior.
  • Verify implementation, deployment, recovery, and migration with known and negative tests.

Protection need

Start with the data, actor, boundary, and adverse condition. Do not start with an algorithm name.

Example: a multi-tenant service stores API credentials that workers must use. A database reader and backup operator must not learn the credential. A worker for one tenant must not decrypt another tenant's credential. Unauthorized modification must be detected before use. The service must rotate root keys, restore backups, and investigate key use.

State what cryptography cannot protect. A compromised authorized worker can use the credential. A user with permission to reveal it can copy it. The application must still authorize tenant, object, action, and purpose. Availability depends on the key service and recovery process.

Inventory plaintext locations and transformations:

  • Browser, API, and transport endpoints.
  • Application memory and logs.
  • Queue messages and worker memory.
  • Database, replicas, indexes, snapshots, and backups.
  • Key service requests and caches.
  • Export, support, recovery, and migration tools.

Choose the layer that separates the data from the expected attacker. Disk encryption protects lost media and does not protect against a database query through the running service. Application encryption can separate storage from plaintext and gives the application and key service decryption authority.

Security objectives and requirements

Write the required properties:

  • Confidentiality of the credential outside an authorized worker operation.
  • Integrity and authenticity of the ciphertext and its tenant, object, purpose, and format.
  • Independent data keys or another scope that limits one compromise.
  • Explicit authorization for unwrap or decrypt by workload, tenant, object class, and environment.
  • No plaintext credential in logs, URLs, metrics, traces, errors, or general backups.
  • Defined availability, backup, rotation, compromise, and recovery behavior.
  • Versioned data that can migrate algorithms and keys.

Select a high-level construction from a maintained library or key service. For stored data, use authenticated encryption and envelope encryption when the key model needs it. For a transport, use a current authenticated protocol such as TLS instead of an application-designed encrypted channel. For a signature, use a standard signed format and trusted key selection.

Define the complete record:

  1. Format version.
  2. Construction or suite identifier under server policy.
  3. Key identifier and key scope.
  4. Nonce or IV with its required generation rule.
  5. Associated data and exact serialization.
  6. Ciphertext and authentication tag.
  7. Creation and migration metadata that is safe to expose.

Do not let the record select an arbitrary algorithm or remote verification key. The reader maps a supported version to one fixed implementation and rejects unknown or retired formats according to migration policy.

Security invariants and evidence

Important invariants:

  • No two encryption operations reuse a nonce where the selected construction forbids it under one key.
  • The tenant, object, purpose, and format used for authorization are authenticated with the ciphertext.
  • Plaintext is released only after authentication succeeds.
  • A worker can invoke only the key and operation required for its tenant and purpose.
  • Root key material never enters ordinary application source, configuration, logs, or memory when the key service can perform the operation.
  • A restored system cannot repeat nonce state or silently write an old format.
  • Every encrypted record has a readable version until migration and retention allow retirement.

Evidence combines library and standard documentation, test vectors, code review, configuration review, key-policy tests, deployed identity tests, backup restore, rotation, and old-format rejection. Verify the exact built dependency versions and key-service policies.

Use negative tests for modified ciphertext, tag, associated data, tenant, object, version, key identifier, nonce length, truncation, duplication, and unknown fields. Assert no plaintext or side effect occurs after failure.

Failure cases

Exercise operational and adversarial failures:

  • Secure-random failure or nonce reuse after replica start, retry, clone, or restore.
  • Key-service timeout, quota, region loss, disabled key, and policy drift.
  • A worker identity requesting another tenant's wrapped data key.
  • Ciphertext copied to another object or environment.
  • An attacker-selected old algorithm, key identifier, or malformed record.
  • Partial key rotation where some writers or readers use the wrong version.
  • Backup restore without the required old key or with an old active writer.
  • Logging or tracing middleware that captures plaintext or cryptographic request data.
  • Compromise of an application process with permission to invoke decrypt.

For each, define deny, retry, degraded operation, recovery, and evidence. Do not retry an operation in a way that repeats a nonce or duplicates a side effect.

Design tradeoffs and residual risk

Application encryption reduces storage exposure and adds key-service availability, latency, cost, record-version, backup, and recovery complexity. Per-object keys limit blast radius and increase operation and metadata volume. Caching unwrapped keys improves availability and increases plaintext-key lifetime. Non-exportable root keys improve custody and can make disaster recovery harder.

Record the threat boundary each layer covers. If the application runtime and key service authorize broad decryption, the design does not protect against runtime compromise. Reduce runtime authority, separate tenant and purpose, and monitor unusual use.

Pomerium boundary

Pomerium provides current authenticated transport on configured downstream and upstream connections and uses cryptography for its sessions and identity assertions. Application data encryption is separate. The application owns record format, data classification, keys, nonces, associated data, key-service identity, authorization, backup, recovery, and migration.

Pomerium can protect human access to key administration and can help restrict application routes. It does not authorize a workload's cryptographic operation or keep an upstream process from logging plaintext.

Exercise

Design encryption for one sensitive application field. Produce:

  1. Threat boundary and plaintext-location inventory.
  2. Required confidentiality, integrity, authenticity, availability, and migration properties.
  3. Standard construction and maintained implementation.
  4. Key hierarchy, identities, operations, and policies.
  5. Record format with version, nonce, associated data, ciphertext, and tag.
  6. Nonce strategy across replicas, retries, and restore.
  7. Negative test matrix.
  8. Rotation, compromise, backup, restore, and retirement plan.

Implement a test fixture with known vectors. Modify every record field and prove the reader rejects it without plaintext or side effects. Restore a backup into an isolated environment and prove it can read old data but writes only the current format.

Evaluation checklist

  • Does the requirement name the data, threat, boundary, endpoint, and residual plaintext locations?
  • Is the design a standard protocol or high-level construction rather than custom primitive composition?
  • Are key purpose, scope, custody, operation policy, nonce rule, associated data, and record version explicit?
  • Does authentication complete before plaintext or any side effect is released?
  • Do tests cover tampering, substitution, replay, restore, mixed versions, key failure, and migration?
  • Can a compromised authorized runtime still decrypt broad data, and is that residual risk bounded?
  • Can the team recover data and retire old cryptography without hidden keys or consumers?

Next learning unit

Sources and further reading

Keep learning

Cryptography and Data Protection

Envelope Encryption

Encrypt data with a data-encryption key and protect that key under a separately stored key-encryption key or key service.

Learn this term
Cryptography and Data Protection

Cryptographic Agility

Inventory and replace algorithms, parameters, protocols, keys, libraries, certificates, and stored formats without hidden dependencies.

Learn this term

Get a Personalized Demo

Schedule a Call with a Pomerium Engineer

Get a Demo