> For the complete documentation index, see [llms.txt](https://docs.lingoql.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.lingoql.com/sub0/apis-abi/encryption-and-decryption.md).

# Encryption & Decryption

Sub0 provides built-in field-level encryption and decryption capabilities through the `ciphers` configuration inside an operation/actions in each actionable (i.e same level where you'd use and add your `hashables`).

The cipher system is designed for encrypting sensitive application data directly inside JSON payloads without requiring application-level cryptography logic.

Common use cases include:

* Encrypting user emails
* Protecting API keys and secrets
* Encrypting payment information
* Encrypting personal information (PII)
* Protecting credentials before storing data
* Decrypting protected fields before returning data to trusted clients or using them in the next actionables

Sub0 uses authenticated encryption algorithms (AEAD), meaning encrypted values provide both:

1. **Confidentiality** — the original value cannot be read without the encryption key.
2. **Integrity** — modified ciphertext is detected and rejected during decryption.

***

## How Cipher Encryption Works

A cipher definition tells Sub0:

* Which fields should be encrypted or decrypted
* Which encryption algorithm to use
* Which key should protect the data
* How encrypted bytes should be represented

Example:

```json
{
  "ciphers": [
    {
      "operation": "Encrypt", // or "Decrypt"
      "properties": [
        "user.email"
      ],
      "algorithm": "Aes256Gcm", // or "ChaCha20Poly1305", "XChaCha20Poly1305", "XSalsa20Poly1305", "Ascon128a"
      "options": {
        "key": "$ENV.AUTH_KEY" // your encryption key
      }
    }
  ]
}
```

Given this payload:

```json
{
  "user": {
    "email": "john@example.com"
  }
}
```

After encryption:

```json
{
  "user": {
    "email": "d7F8xZ4h0mYwP8Qk9Jm..."
  }
}
```

The encrypted value can safely be stored in a database or transmitted.

During decryption:

```json
{
  "ciphers": [
    {
      "operation": "Decrypt",
      "properties": [
        "user.email"
      ],
      "algorithm": "Aes256Gcm",
      "options": {
        "key": "$ENV.AUTH_KEY"
      }
    }
  ]
}
```

The original value is restored:

```json
{
  "user": {
    "email": "john@example.com"
  }
}
```

***

## Cipher Object

A cipher definition follows this structure:

```json
{
  "operation": "Encrypt", // or "Decrypt"
  "properties": [ // properties to be encrypted or decrypted
    "user.email"
  ],
  "algorithm": "Aes256Gcm",// or "ChaCha20Poly1305", "XChaCha20Poly1305", "XSalsa20Poly1305", "Ascon128a
  "options": {
    "key": "$ENV.AUTH_KEY" // encryption key, without this, we can't decrypt any encrypted data
  }
}
```

| Field        | Type              | Required                      | Description                                                |
| ------------ | ----------------- | ----------------------------- | ---------------------------------------------------------- |
| `operation`  | `CipherOperation` | Yes                           | Defines whether the field should be encrypted or decrypted |
| `properties` | Array of strings  | Yes                           | JSON paths of fields to process                            |
| `algorithm`  | `CipherAlgorithm` | Yes                           | Encryption algorithm to use                                |
| `options`    | Object            | Yes (but `key` property only) | Additional encryption configuration                        |

***

## Properties

`properties` defines which JSON fields should be encrypted or decrypted.

Multiple properties can use the same encryption configuration.

Example:

```json
{
  "operation": "Encrypt",
  "properties": [
    "user.email",
    "user.phone",
    "user.address"
  ],
  "algorithm": "Aes256Gcm",
  "options": {
    "key": "$ENV.AUTH_KEY"
  }
}
```

Input:

```json
{
  "user": {
    "email": "john@example.com",
    "phone": "+123456789",
    "address": "10 Main Street"
  }
}
```

Output:

```json
{
  "user": {
    "email": "encrypted...",
    "phone": "encrypted...",
    "address": "encrypted..."
  }
}
```

***

## Nested Properties

Properties use dot notation.

Example:

```json
{
  "operation": "Encrypt",
  "properties": [
    "account.credentials.api_key"
  ],
  "algorithm": "Aes256Gcm"
}
```

Payload:

```json
{
  "account": {
    "credentials": {
      "api_key": "sk_live_xxxxx"
    }
  }
}
```

Result:

```json
{
  "account": {
    "credentials": {
      "api_key": "encrypted..."
    }
  }
}
```

***

## Arrays

Cipher operations automatically traverse arrays.

Example:

```json
{
  "operation": "Encrypt",
  "properties": [
    "users.email"
  ],
  "algorithm": "Aes256Gcm",
  "options": {
    "key": "$ENV.AUTH_KEY"
  }
}
```

Payload:

```json
{
  "users": [
    {
      "email": "alice@example.com"
    },
    {
      "email": "bob@example.com"
    }
  ]
}
```

Result:

```json
{
  "users": [
    {
      "email": "encrypted_value_1"
    },
    {
      "email": "encrypted_value_2"
    }
  ]
}
```

***

## Cipher Operations

### Encrypt

Encrypt converts plaintext values into protected ciphertext.

Example:

```json
{
  "operation": "Encrypt",
  "properties": [
    "password_reset_token"
  ],
  "algorithm": "ChaCha20Poly1305",
  "options": {
    "key": "$ENV.AUTH_KEY"
  }
}
```

Input:

```json
{
  "password_reset_token": "abc123"
}
```

Output:

```json
{
  "password_reset_token": "encrypted_value"
}
```

***

### Decrypt

Decrypt converts ciphertext back into plaintext.

Example:

```json
{
  "operation": "Decrypt",
  "properties": [
    "password_reset_token"
  ],
  "algorithm": "ChaCha20Poly1305",
  "options": {
    "key": "$ENV.AUTH_KEY"
  }
}
```

Input:

```json
{
  "password_reset_token": "encrypted_value"
}
```

Output:

```json
{
  "password_reset_token": "abc123"
}
```

***

## Supported Cipher Algorithms

Sub0 supports multiple authenticated encryption algorithms.

| Algorithm           | Key Size | Nonce Size | Description                          |
| ------------------- | -------: | ---------: | ------------------------------------ |
| `Aes256Gcm`         | 32 bytes |   12 bytes | AES-256 GCM authenticated encryption |
| `ChaCha20Poly1305`  | 32 bytes |   12 bytes | Modern stream cipher AEAD algorithm  |
| `XChaCha20Poly1305` | 32 bytes |   24 bytes | Extended nonce ChaCha20 variant      |
| `XSalsa20Poly1305`  | 32 bytes |   24 bytes | Libsodium-compatible encryption      |
| `Ascon128a`         | 16 bytes |   16 bytes | Lightweight modern AEAD algorithm    |

***

## AES-256-GCM

AES-256-GCM is a widely deployed encryption standard.

Example:

```json
{
  "operation":"Encrypt",
  "properties":[
    "payment.card_number"
  ],
  "algorithm":"Aes256Gcm",
  "options":{
    "key":"$ENV.PAYMENT_KEY"
  }
}
```

Recommended for:

* General application encryption
* Database fields
* Enterprise applications
* Sensitive customer data

***

## ChaCha20-Poly1305

ChaCha20-Poly1305 is a high-performance AEAD algorithm.

Example:

```json
{
  "operation":"Encrypt",
  "properties":[
    "session.token"
  ],
  "algorithm":"ChaCha20Poly1305",
  "options":{
    "key":"$ENV.SESSION_KEY"
  }
}
```

Recommended for:

* APIs
* Mobile applications
* High-throughput systems

***

## XChaCha20-Poly1305

XChaCha20 provides a larger nonce space than standard ChaCha20.

Example:

```json
{
  "operation":"Encrypt",
  "properties":[
    "documents.content"
  ],
  "algorithm":"XChaCha20Poly1305",
  "options":{
    "key":"$ENV.DOCUMENT_KEY"
  }
}
```

Recommended for:

* Large-scale systems
* Long-lived encrypted data
* Applications requiring safer nonce management

***

## XSalsa20-Poly1305

XSalsa20-Poly1305 provides compatibility with the libsodium ecosystem.

Example:

```json
{
  "operation":"Encrypt",
  "properties":[
    "user.private_notes"
  ],
  "algorithm":"XSalsa20Poly1305",
  "options":{
    "key":"$ENV.NOTES_KEY"
  }
}
```

Useful when integrating with existing libsodium-based applications.

***

## Ascon128a

Ascon128a is a modern lightweight authenticated encryption algorithm.

Example:

```json
{
  "operation":"Encrypt",
  "properties":[
    "device.payload"
  ],
  "algorithm":"Ascon128a",
  "options":{
    "key":"$ENV.DEVICE_KEY"
  }
}
```

Useful for:

* IoT systems
* Lightweight environments
* Embedded applications

***

## Cipher Options

The `options` object controls encryption behaviour.

Example:

```json
{
  "options":{
    "key":"$ENV.AUTH_KEY", // REQUIRED!
    "encoding":"Base64" // or "Base64Url", "Base32", "Base58", "Hex"
  }
}
```

Available options:

| Option     | Type     | Description                                                      |
| ---------- | -------- | ---------------------------------------------------------------- |
| `key`      | String   | Encryption key or environment variable reference                 |
| `nonce`    | String   | Custom nonce (mainly useful for deterministic testing)           |
| `aad`      | String   | Additional authenticated data (e.g user's unique id, email etc.) |
| `encoding` | Encoding | Representation format for encrypted output                       |

***

## Encryption Keys

Keys can be provided directly:

```json
{
  "key":"my-secret-key"
}
```

or loaded from environment variables:

```json
{
  "key":"$ENV.AUTH_KEY"
}
```

Environment variables are recommended for production.

Example:

Environment:

```
AUTH_KEY=0123456789abcdef0123456789abcdef
```

Cipher:

```json
{
  "options":{
    "key":"$ENV.AUTH_KEY"
  }
}
```

***

## Additional Authenticated Data (AAD)

AAD allows additional information to be authenticated without encrypting it.

Example:

```json
{
  "operation":"Encrypt",
  "properties":[
    "user.email"
  ],
  "algorithm":"Aes256Gcm",
  "options":{
    "key":"$ENV.AUTH_KEY",
    "aad":"user-record-v1"
  }
}
```

During decryption, the same AAD must be provided.

If the AAD changes, decryption fails.

***

## Encodings

Encrypted data is binary.

Because JSON does not support raw binary data, Sub0 supports multiple encoding formats.

| Encoding    | Description                | Recommended Use                  |
| ----------- | -------------------------- | -------------------------------- |
| `Base64`    | Standard Base64 encoding   | Default and recommended          |
| `Base64Url` | URL-safe Base64            | URLs and tokens                  |
| `Hex`       | Hexadecimal representation | Debugging and interoperability   |
| `Base32`    | Base32 encoding            | Human-readable identifiers       |
| `Base58`    | Base58 encoding            | Blockchain-style representations |

***

## Base64 Example

Configuration:

```json
{
  "options":{
    "encoding":"Base64"
  }
}
```

Output:

```json
{
  "secret":"QmFzZTY0RW5jcnlwdGVk..."
}
```

***

## Base64URL Example

Useful when encrypted values appear inside URLs.

```json
{
  "options":{
    "encoding":"Base64Url"
  }
}
```

Output:

```json
{
  "token":"eyJhbGciOi..."
}
```

***

## Hex Example

```json
{
  "options":{
    "encoding":"Hex"
  }
}
```

Output:

```json
{
  "secret":"a94f31c82e..."
}
```

***

## Complete Example

Encrypt multiple sensitive fields:

```json
{
  "ciphers":[
    {
      "operation":"Encrypt",
      "properties":[
        "user.email",
        "user.phone",
        "payment.card_number"
      ],
      "algorithm":"Aes256Gcm",
      "options":{
        "key":"$ENV.APP_ENCRYPTION_KEY",
        "encoding":"Base64"
      }
    }
  ]
}
```

Payload:

```json
{
  "user":{
    "email":"alice@example.com",
    "phone":"+123456789"
  },
  "payment":{
    "card_number":"4111111111111111"
  }
}
```

Encrypted:

```json
{
  "user":{
    "email":"h8F0x9...",
    "phone":"a92Lm..."
  },
  "payment":{
    "card_number":"zX92Lp..."
  }
}
```

***

## Using Multiple Encryption Algorithms At Once

You can also apply multiple encryption/decryption algorithms on different fields.

```json
{
  "ciphers":[
    {
      "operation":"Encrypt",
      "properties":["email"],
      "algorithm":"Aes256Gcm"
    },
    {
      "operation":"Encrypt",
      "properties":["phone"],
      "algorithm":"ChaCha20Poly1305"
    },
    {
      "operation":"Encrypt",
      "properties":["notes"],
      "algorithm":"XChaCha20Poly1305"
    }
  ]
}
```

## Recommended Practices

* Use environment variables for encryption keys.
* Never hardcode production keys inside ABI definitions.
* Use AES-256-GCM or ChaCha20-Poly1305 for general application data.
* Use Base64 encoding unless another encoding is required.
* Do not reuse custom nonces in production.
* Keep encryption keys separate from encrypted data.
* Rotate keys periodically using `cronjob` when key management workflows are implemented.&#x20;

{% hint style="info" %}
There are many ways you can go about key rotation. The simplest one is create another ENV Key (new encryption key), deploy your service, then create an endpoint with 2 actionables: one to decrypt data and the other to encrypt back and store in the DB.

Other options involve using cron jobs to the process, with appropriate batching.
{% endhint %}

Sub0's cipher system provides application-level encryption without requiring custom cryptographic code, allowing sensitive fields to be protected consistently across APIs and data workflows.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.lingoql.com/sub0/apis-abi/encryption-and-decryption.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
