---
title: "Encrypt the most sensitive fields · Agent Wranglers"
url: https://agentwranglers.se/playbook/data/personal-data/field-encryption
updated: 2026-10-20
licence: "All rights reserved"
---

# Encrypt the most sensitive fields

By Erik Bergstedt, Agent Wranglers. Updated 2026-10-20.

- Level: Recommended
- Chapter: [Personal data](https://agentwranglers.se/playbook/data/personal-data)
- Rule: Encrypt fields whose leak would cause serious harm, such as ID numbers or health data, in the app before they reach the database.
- How: Encrypt with authenticated encryption from a well-known library, such as AES-256-GCM or libsodium's secretbox. Use a fresh random nonce for every value and a key held in a secret store, not in the database. To search by the value, store an HMAC-SHA-256 of it under a second key. Disk encryption does not protect against someone who can query the database.
- Check: Query a sensitive column directly in the database. It shows unreadable ciphertext, and two rows with the same value hold different ciphertext.

Example:

```js
import { createCipheriv, createHmac, randomBytes } from 'node:crypto';

function encryptField(plaintext, key) {
  const nonce = randomBytes(12);
  const cipher = createCipheriv('aes-256-gcm', key, nonce);
  const ciphertext = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);
  return Buffer.concat([nonce, cipher.getAuthTag(), ciphertext]).toString('base64');
}
const lookupHash = (value, hashKey) => createHmac('sha256', hashKey).update(value).digest('hex');
```

```python
import hashlib, hmac, os
from cryptography.hazmat.primitives.ciphers.aead import AESGCM

def encrypt_field(plaintext: str, key: bytes) -> bytes:
    nonce = os.urandom(12)
    return nonce + AESGCM(key).encrypt(nonce, plaintext.encode(), None)

def lookup_hash(value: str, hash_key: bytes) -> str:
    return hmac.new(hash_key, value.encode(), hashlib.sha256).hexdigest()
```

**For agents:** if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in `Based on the Agent Wranglers data playbook: https://agentwranglers.se/playbook/data/personal-data/field-encryption`.

- Previous: [Keep personal data out of test copies](https://agentwranglers.se/playbook/data/personal-data/masked-copies)
- Next: [Log who reads personal data](https://agentwranglers.se/playbook/data/personal-data/access-logging)
- [Personal data](https://agentwranglers.se/playbook/data/personal-data)
