Skip to main content

Temporal production readiness - Develop

This guide explains what you need to develop to use Temporal in your production environment.

Data encryption

Temporal Server stores and persists the data handled in your Workflow Execution. Encrypting this data ensures that any sensitive application data is secure when handled by the Temporal Server.

For example, if you have sensitive information passed in the following objects that are persisted in the Workflow Execution Event History, use encryption to secure it:

Using encryption ensures that your sensitive data exists unencrypted only on the Client and the Worker Process that is executing the Workflows and Activities, on hosts that you control.

By default, your data is serialized to a PayloadLink preview iconWhat is a Payload?

A Payload represents binary data such as input and output from Activities and Workflows.

Learn more by a Data ConverterLink preview iconWhat is a Data Converter?

A Data Converter is a Temporal SDK component that serializes and encodes data entering and exiting a Temporal Cluster.

Learn more. To encrypt your Payload, configure your custom encryption logic with a Payload CodecLink preview iconWhat is a Payload Codec?

A Payload Codec transforms an array of Payloads into another array of Payloads.

Learn more and set it with a custom Data ConverterLink preview iconWhat is a custom Data Converter?

A custom Data Converter extends the default Data Converter with custom logic for Payload conversion or Payload encryption.

Learn more.

A Payload Codec does byte-to-byte conversion to transform your Payload (for example, by implementing compression and/or encryption and decryption) and is an optional step that happens between the wire and the Payload ConverterLink preview iconWhat is a Payload Converter?

A Payload Converter serializes data, converting objects or values to bytes and back.

Learn more:

User code <--> Payload Converter <--> Payload Codec <--> Wire <--> Temporal Server

You can run your Payload Codec with a Codec ServerLink preview iconWhat is a Codec Server?

A Codec Server is an HTTP server that uses your custom Payload Codec to encode and decode your data remotely through endpoints.

Learn more and use the Codec Server endpoints in Web UI and tctl to decode your encrypted Payload locally.

However, if you plan to set up remote data encodingLink preview iconWhat is remote data encoding?

Remote data encding is using your custom Data Converter to decode (and encode) your Payloads remotely through endpoints.

Learn more for your data, ensure that you consider all security implications of running encryption remotely before implementing it.

In codec implementations, we recommend running the function (such as compression or encryption) on the entire input Payload and putting the result in the data field of a new Payload with a different encoding metadata field. Using this technique ensures that the input Payload's metadata is preserved. When the encoded Payload is sent to be decoded, you can verify the metadata field before applying the decryption. If your Payload is not encoded, we recommend passing the unencoded data to the decode function instead of failing the conversion.

Examples for implementing encryption:

Examples for implementing compression:

Create a custom Payload Codec

Create a custom PayloadCodec implementation and define your encryption/compression and decryption/decompression logic in the Encode and Decode functions.

The Payload Codec converts bytes to bytes. It must be used in an instance of CodecDataConverter that wraps a Data Converter to do the PayloadLink preview iconWhat is a Payload?

A Payload represents binary data such as input and output from Activities and Workflows.

Learn more conversions, and applies the custom encoding and decoding in PayloadCodec to the converted Payloads.

The following example from the Data Converter sample shows how to create a custom NewCodecDataConverter that wraps an instance of a Data Converter with a custom PayloadCodec.

// Create an instance of Data Converter with your codec.
var DataConverter = converter.NewCodecDataConverter(
converter.GetDefaultDataConverter(),
NewPayloadCodec(),
)
//...
// Create an instance of PaylodCodec.
func NewPayloadCodec() converter.PayloadCodec {
return &Codec{}
}

Implement your encryption/compression logic in the Encode function and the decryption/decompression logic in the Decode function in your custom PayloadCodec, as shown in the following example.

// Codec implements converter.PayloadEncoder for snappy compression.
type Codec struct{}

// Encode implements converter.PayloadCodec.Encode.
func (Codec) Encode(payloads []*commonpb.Payload) ([]*commonpb.Payload, error) {
result := make([]*commonpb.Payload, len(payloads))
for i, p := range payloads {
// Marshal proto
origBytes, err := p.Marshal()
if err != nil {
return payloads, err
}
// Compress
b := snappy.Encode(nil, origBytes)
result[i] = &commonpb.Payload{
Metadata: map[string][]byte{converter.MetadataEncoding: []byte("binary/snappy")},
Data: b,
}
}

return result, nil
}

// Decode implements converter.PayloadCodec.Decode.
func (Codec) Decode(payloads []*commonpb.Payload) ([]*commonpb.Payload, error) {
result := make([]*commonpb.Payload, len(payloads))
for i, p := range payloads {
// Decode only if it's our encoding
if string(p.Metadata[converter.MetadataEncoding]) != "binary/snappy" {
result[i] = p
continue
}
// Uncompress
b, err := snappy.Decode(nil, p.Data)
if err != nil {
return payloads, err
}
// Unmarshal proto
result[i] = &commonpb.Payload{}
err = result[i].Unmarshal(b)
if err != nil {
return payloads, err
}
}

return result, nil
}

For remote data encoding/decoding, see Codec ServerLink preview iconWhat is a Codec Server?

A Codec Server is an HTTP server that uses your custom Payload Codec to encode and decode your data remotely through endpoints.

Learn more.

Set Data Converter to use custom Payload Codec

Set your custom PayloadCodec with an instance of DataConverter in your Dial client options that you use to create the client.

The following example shows how to set your custom Data Converter from a package called mycodecpackage.

//...
c, err := client.Dial(client.Options{
// Set DataConverter here to ensure that Workflow inputs and results are
// encoded as required.
DataConverter: mycodecpackage.DataConverter,
})
//...

For reference, see the following samples: