Skip to main content
S2 supports stream encryption with a key that you supply at request time. Configure a basin with a cipher for new streams, then provide the same key on append and read on any new streams.

Determined at stream creation

A stream captures its cipher when it is created, through its basin’s configuration.

Key supplied on data plane requests

Encrypted streams require the s2-encryption-key header on REST requests, or pass it using the corresponding CLI environment variable or flags.

Key custody stays with you

S2 does not persist or log the encryption key.

How it works

New streams inherit the stream_cipher configured on the basin at the moment they are created. Reconfiguring the basin later only affects streams created after that change.

What is encrypted

For regular records, S2 encrypts headers and body before storage, and decrypts them only when serving a read with the correct key. Command records stay plaintext because S2 must interpret them to apply service-side operations such as fencing and trimming.
Encrypted records are cryptographically bound to the stream they were written to. S2 includes the stream’s unique identifier as associated data, so ciphertext from one stream cannot be accepted as a record in another stream.

Supported ciphers

Keys are base64-encoded when provided in the s2-encryption-key header or to the CLI. SDKs allow providing either a string or bytes.
A stream configured with aes-256-gcm can have up to 2^32 records (~4.3 billion), and subsequent appends will be rejected. Otherwise, a stream can have up to 2^64 records (effectively unlimited) – so aegis-256 is generally preferable.

Where keys are required

Generate a key

Store the resulting value as a secret to be used for one or more streams. Maintain a mapping of which key was used for which stream, so that it may be specified consistently for appends and reads.

Key management

For coarse-grained access, manage a shared key in your existing Key Management System (KMS) or secrets infrastructure. For finer-grained access, such as a key per stream, use envelope encryption:
  • Keep a Key Encryption Key (KEK) in your KMS.
  • Generate a Data Encryption Key (DEK) per stream, and store the wrapped DEK alongside your stream metadata.
  • At request time, your application unwraps the DEK and passes it to S2 as the stream encryption key.
If you need to rotate the key, create a new stream and cut writers and readers over deliberately. Similarly, to change the cipher used, update the basin configuration and then create a new stream.
Do not rotate a stream key in place by simply changing the request header. S2 will accept the append, but later reads with only one key will fail once they reach records encrypted under a different key.

Configure encryption for new streams

Stream create endpoints do not take a per-stream encryption field. A stream inherits the basin default when it is created, and that cipher is immutable for the lifetime of the stream.

Append and read with the key

The same keying pattern applies to single-request operations, append/read sessions, SSE reads, and S2S sessions. The encryption key is just an HTTP header on the wire.

Inspect cipher config

Errors