Encryption middleware

The encryption middleware provides end-to-end encryption for events, step output, and function output. Only encrypted data is sent to Inngest servers: encryption and decryption happen within your infrastructure.

Installation

Install the @inngest/middleware-encryption package (GitHub) and configure it as follows:

import { encryptionMiddleware } from "@inngest/middleware-encryption";

const inngest = new Inngest({
  id: "my-app",
  middleware: [
    encryptionMiddleware({
      // your encryption key string should not be hard coded
      key: process.env.MY_ENCRYPTION_KEY,
    }),
  ],
});

By default, the following will be encrypted:

  • All step data
  • All function output
  • Event data placed inside data.encrypted

encryptionMiddleware(options)

Returns a Middleware.Class that can be passed to the middleware array on a client or function.

Options

  • Name
    key
    Type
    string
    Required
    required
    Description

    The encryption key used to encrypt and decrypt data. This should be a secret value stored in an environment variable.

  • Name
    decryptOnly
    Type
    boolean
    Required
    optional
    Description

    When true, disables encryption but continues to decrypt existing data. Useful when migrating away from encryption.

  • Name
    eventEncryptionField
    Type
    string
    Required
    optional
    Description

    The field within event.data to encrypt. Defaults to "encrypted".

  • Name
    fallbackDecryptionKeys
    Type
    string[]
    Required
    optional
    Description

    Additional keys to try when decrypting. Useful during key rotation.

  • Name
    encryptionService
    Type
    EncryptionService
    Required
    optional
    Description

    A custom encryption service instance. If not provided, the default LibSodium-based service is used.

  • Name
    legacyV0Service
    Type
    object
    Required
    optional
    Description

    Options for backward compatibility with v0 AES encryption format.

Changing the encrypted event.data field

Only select pieces of event data are encrypted. By default, only the data.encrypted field.

This can be customized using the eventEncryptionField option:

encryptionMiddleware({
  key: process.env.MY_ENCRYPTION_KEY,
  eventEncryptionField: "sensitive",
});

Decrypt only mode

To disable encryption but continue decrypting, set decryptOnly: true. This is useful when you want to migrate away from encryption but still need to process older events.

encryptionMiddleware({
  key: process.env.MY_ENCRYPTION_KEY,
  decryptOnly: true,
});

Key rotation

To attempt decryption with multiple keys, set the fallbackDecryptionKeys option. This is useful when rotating keys, since older events may have been encrypted with a different key:

// 1. Start with the current key
encryptionMiddleware({
  key: process.env.MY_ENCRYPTION_KEY,
});

// 2. Deploy all services with the new key as a decryption fallback
encryptionMiddleware({
  key: process.env.MY_ENCRYPTION_KEY,
  fallbackDecryptionKeys: ["new"],
});

// 3. Deploy all services using the new key for encryption
encryptionMiddleware({
  key: process.env.MY_ENCRYPTION_KEY_V2,
  fallbackDecryptionKeys: ["current"],
});

// 4. Once all data using the old key has passed, phase it out
encryptionMiddleware({
  key: process.env.MY_ENCRYPTION_KEY_V2,
});

Cross-language support

This middleware is compatible with our encryption middleware in the Python SDK. Encrypted events can be sent from Python and decrypted in TypeScript, and vice versa.