Getting to know the Transit Secrets Engine as Encryption-as-a-Service, creating an encryption key, encrypting sensitive data with base64 plaintext, decrypting it again, and understanding why OpenBao does not store the data.

In episode 4 you saw OpenBao create dynamic database credentials. Episode 5 presents a different role: the Transit Secrets Engine, or Encryption-as-a-Service. This time OpenBao does not store any secret — it acts as an encryption engine serving your applications over the API.
Transit solves a problem backend teams often face: encrypting sensitive data correctly is hard. Algorithms, encryption modes, key management, rotation — all of it is easy to get wrong. Transit moves all of that complexity to OpenBao, while the application simply calls one endpoint.
EaaS is a model where encryption and decryption are provided as a centralized service. Applications send data, OpenBao returns ciphertext — or the reverse — and the data itself is never stored in OpenBao. OpenBao only holds the keys, not the data.
Think of sensitive data such as credit card numbers, national ID numbers, or health data. Instead of every team writing its own encryption logic with independently managed keys, the whole organization uses one centralized cryptographic service with uniform policies.
Compare the two approaches:
| Aspect | In-Application Encryption | Transit EaaS |
|---|---|---|
| Key management | Scattered per application/team | Centralized in OpenBao |
| Key rotation | Manual, easy to miss | Automatic without changing data |
| Standardization | Varied implementations | One service, one policy |
| Audit | Difficult | Tracked via audit log |
| Data in OpenBao | Not relevant | Never stored |
With EaaS, the same key can be used by dozens of services without any of them ever seeing or storing that key.
Like other secrets engines, transit must first be enabled at a mount path:
bao secrets enable transit
bao secrets listOnce enabled at the default transit path, you can immediately create keys.
Keys are the core entity in transit. Create one key for your application:
bao write -f transit/keys/my-app-key
bao read transit/keys/my-app-keybao write -f transit/keys/my-app-key creates a key named my-app-key. The bao read output shows details such as key type, key version, and creation time. Transit supports several key types — from aes256-gcm96 for general symmetric encryption, to chacha20-poly1305, and asymmetric types such as ed25519 for signing.
Now it is time to encrypt sensitive data. Transit expects the plaintext in base64 format:
bao write transit/encrypt/my-app-key \
plaintext=$(echo "data-sensitif" | base64)Notice the flow: echo "data-sensitif" | base64 converts the plaintext to base64, and the result is sent as the plaintext value. OpenBao encrypts it with the my-app-key key and returns ciphertext like this:
Key Value
--- -----
ciphertext vault:v1:8Gh3hRcDvV2eK9mLpQ4sT1xUyZwB5aCbD6...The vault: prefix in the ciphertext indicates the format and key version used — the information transit needs to decrypt it again. This ciphertext is what applications may store in their database: even if the database leaks, the data stays safe as long as the key in OpenBao is not compromised along with it.
Tip
The right habit: store the ciphertext in the application database, not the plaintext. OpenBao does not store your data, so the only place your data lives is your application — make sure what is stored there is already encrypted.
When the data needs to be read back — for example, showing a card number on a profile page — the application sends the ciphertext to transit for decryption:
bao write transit/decrypt/my-app-key \
ciphertext="vault:v1:8Gh3hRcDvV2eK9mLpQ4sT1xUyZwB5aCbD6..."The output is plaintext in base64. You just convert it back to the original text with the reverse command, for example echo "<base64>" | base64 -d. The same key used for encryption is required for decryption — this is the essence of symmetric encryption.
This is transit's greatest advantage and also the answer to a frequently asked question: why is it safe to give sensitive data to OpenBao?
This combination makes transit ideal for compliance such as PCI DSS or personal data protection laws: high-standard encryption, centralized keys, and data that does not settle in a third-party service.
Note
Transit is not a replacement for the KV engine. KV stores secrets for applications to read; transit only serves cryptographic operations. Use both according to their role — KV for storing, transit for encrypting.
In this episode 5, you understood the Encryption-as-a-Service concept and why modern organizations choose this model, enabled the transit engine, created an encryption key with bao write -f transit/keys/my-app-key, encrypted data with base64 plaintext, decrypted it again, and understood why sensitive data is never stored in OpenBao.
Key takeaways:
In the next episode, episode 6, we use OpenBao for a very different role: the PKI Secrets Engine — making OpenBao an internal Certificate Authority that issues TLS certificates on-demand with short TTLs, including practicing bao write pki_int/issue/my-role common_name="api.internal.local". SSL/TLS certificates for internal services will be issued, expire, and rotate automatically without human intervention. See you in episode 6!