Crypto cache transformer
Cache value encryption transformer implementing cache.TransformerPort. It hands every payload to a Piko crypto service that encrypts on write and decrypts on read. Cached payloads stay unreadable at rest in Redis, Valkey, or any other shared backend.
Overview
The crypto transformer wraps a crypto_domain.CryptoServicePort and runs it as a Piko cache transformer. The crypto service encrypts every value before it leaves the process, then decrypts every value after it arrives. The transformer holds no key material of its own. It delegates to the central crypto service, so the cache inherits the same provider configuration and key rotation as the rest of the app. The shippable providers are local AES-GCM, AWS KMS, and GCP KMS.
Reach for the crypto transformer when cached values contain user PII, secrets, or anything you do not want stored as plaintext in a shared cache. That covers on-disk snapshots and replica logs. Skip it when the cache is in-process Otter only. The values never leave the process anyway, and the transformer only costs CPU. The transformer pairs with the Zstd transformer. Compress first (priority 100), encrypt second (priority 250 default), so the entropy of the ciphertext does not defeat compression.
The default priority of 250 puts crypto after compression in the write pipeline. On read, transformers run in reverse priority order, so decryption happens before decompression. If name is empty the transformer registers as "crypto-service". Empty payloads pass through unchanged, so a zero-length value is not encrypted.
Requirements
- A configured Piko crypto service (
crypto_domain.CryptoServicePort), typically the default service fromcrypto.GetDefaultService()after you register a crypto provider (see Local AES-GCM, AWS KMS, GCP KMS). - The cache provider must support the transformer pipeline (Redis, Valkey, Redis Cluster, Valkey Cluster, Otter).
Bootstrap
There is no piko.With* option for cache transformers. Importing the cache_transformer_crypto package registers the crypto-service blueprint through init(), so the builder's Encryption() method resolves it. You do not register anything by hand.
Attach the transformer to a cache through the cache builder when you create a namespace. NewCacheBuilder returns a builder and an error, so handle the error before chaining:
import (
"piko.sh/piko/wdk/cache"
_ "piko.sh/piko/wdk/cache/cache_transformer_crypto"
)
builder, err := cache.NewCacheBuilder[string, User](service)
if err != nil {
return err
}
userCache, err := builder.
Provider("redis").
Namespace("users").
Encryption(). // resolves the registered crypto-service transformer
Build(ctx)
Encryption() pulls the global crypto service from bootstrap at build time. For tests or a non-default crypto service, use builder.EncryptionWithService(service) to inject the service explicitly.
Configuration
To construct the transformer directly, for example to set an explicit name or priority, call New:
import (
"piko.sh/piko/wdk/crypto"
"piko.sh/piko/wdk/cache/cache_transformer_crypto"
)
cryptoService, err := crypto.GetDefaultService()
if err != nil {
return err
}
// name="" defaults to "crypto-service"; priority=0 defaults to 250.
transformer := cache_transformer_crypto.New(cryptoService, "", 0)
The constructor takes positional arguments instead of a Config struct: (cryptoService, name, priority). It returns a cache.TransformerPort. Pass a non-empty name and a non-zero priority to override the defaults.
Transformer limitations
Attaching any transformer, including encryption, stores encoded bytes instead of decoded values. That disables features that need the decoded value:
- Searchable and Query.
Search()andQuery()returnErrSearchNotSupported. - Custom Weigher. The builder ignores a
Weigherfunction. - Custom ExpiryCalculators. Use
WriteExpirationorAccessExpirationfor time-to-live instead. - Deletion callbacks. The builder ignores
OnDeletionandOnAtomicDeletion. - RefreshCalculator. The builder ignores
RefreshCalculator.
The builder logs a warning at build time when you set one of these alongside a transformer.
See also
Other cache transformers and encoders:
- Zstd transformer, compress before encrypting.
- Gob encoder, Go-native value encoding.
- JSON encoder, cross-language value encoding.
Crypto providers (the underlying service):
- Local AES-GCM, in-process AES-GCM with local key material.
- AWS KMS, managed encryption keys on AWS.
- GCP KMS, managed encryption keys on GCP.
- Azure Key Vault, managed keys on Azure.
Framework docs:
- How to use the cache, wiring the cache service end-to-end.
- Cache API reference,
TransformerPortand the cache builder. - About crypto, the crypto service design.