You're designing at-rest secret protection for config repos across many services using Spring Cloud Config's {cipher} encryption. What are the key-management, rotation, and threat-model concerns, and when would you move beyond {cipher} entirely?
answer
- key = single point of trust; escrow + custody
- symmetric rotation = re-encrypt everything; keystore aliases ease it
- lock down /decrypt + actuator + logs
- TLS always; choose decryption locus by trust
- need leasing/rotation/audit -> Vault backend, not {cipher}
basics
~20 sThe encryption key is the single point of trust: protect its custody, plan rotation (which requires re-encrypting values), lock down /decrypt, and use TLS. When you need dynamic secrets, leasing, fine-grained access, and audit, move to a real secrets backend like Vault instead of static {cipher} values.
solid answer
~50 s{cipher} gives at-rest protection but the whole scheme collapses to one asset: the server's key. Design concerns: (1) Custody — keep the key/keystore out of the repo it protects, inject via env or a secret store, restrict who can read it. (2) Rotation — symmetric keys mean re-encrypting every value; keystores with multiple aliases and per-app/salted binding ease staged rotation. (3) Endpoint exposure — /decrypt must be authenticated, restricted, or disabled; secure the whole Config Server. (4) Blast radius — a leaked key exposes all secrets, so consider RSA key separation and per-app binding. (5) Transport — TLS even with client-side decryption. Move beyond {cipher} to a dynamic secrets backend (Spring Cloud Config's Vault integration) when you need short-lived/leased credentials, per-service policies, centralized audit, automatic rotation, or revocation — things static encrypted properties can't provide.
go deeper
Understand the key must be protected and kept out of the repo.
Know rotation implications and that /decrypt must be secured.
Design custody, RSA key separation, per-app binding, and decryption-locus tradeoffs.
Own the org-wide secrets strategy and know precisely when static {cipher} must give way to a dynamic secrets backend like Vault.
`{cipher}` encrypted properties provide **at-rest** protection for secrets stored in a config repo, but at scale the design questions are mostly about **key management and threat modeling**, not syntax. **1) The key is the single point of trust.** Every `{cipher}` value's confidentiality reduces to one asset: the symmetric `encrypt.key` or the RSA keystore private key. Lose it and ciphertext is unrecoverable; leak it and **every** secret across every service is exposed. Treat it as a top-tier secret: inject via environment/secret store, never commit it to the repo it protects, restrict read access, and back it up securely (escrow) so a lost key doesn't brick recovery. **2) Rotation.** - **Symmetric:** rotating `encrypt.key` invalidates all existing ciphertext, so you must **re-encrypt every value** with the new key and roll out atomically — operationally heavy across many repos. - **RSA keystore:** standard keystore tooling plus multiple **aliases** enables staged rotation; you can introduce a new key while old values still decrypt, then re-encrypt gradually. Per-app/**salted** encryption (encrypting under `/encrypt/{name}/{profiles}`, `encrypt.rsa.salt`, `encrypt.rsa.strong=true`) narrows what a single compromised ciphertext reveals and can bind values to an app. **3) Endpoint hardening.** `/encrypt` and especially `/decrypt` are unauthenticated by default. At scale you must: put Spring Security in front of the Config Server, restrict or disable `/decrypt`, prefer minting ciphertext via a locked-down admin instance or the Spring Cloud CLI, and never expose these endpoints to untrusted networks. Also guard actuator endpoints and logs so decrypted values don't leak (`/env`, config dumps). **4) Decryption locus and threat model.** Choose server-side (default, plaintext on the wire, clients key-free) vs client-side (`spring.cloud.config.server.encrypt.enabled=false`, plaintext never leaves the client but the key is distributed everywhere) based on whether you trust the server and transport. TLS is mandatory regardless to protect integrity and the plaintext path. **5) Blast radius controls.** RSA key separation (public encrypts, private decrypts), per-app binding, and keeping decryption capability on as few nodes as possible all shrink the impact of any one compromise. **When to move beyond `{cipher}` entirely.** Static encrypted properties are **static secrets** — the same value sits there until someone rotates it. Move to a **dynamic secrets backend** (Spring Cloud Config supports a **Vault** backend, and clients can use Spring Cloud Vault) when you need: - **Short-lived / leased credentials** (e.g., DB creds minted per request/session with a TTL). - **Automatic rotation and revocation** without redeploying config. - **Fine-grained, per-service access policies** and **centralized audit** of who read what. - **Dynamic backends** (databases, cloud IAM, PKI) issuing credentials on demand. `{cipher}` is excellent for keeping a modest set of static secrets out of plaintext in git with zero extra infrastructure. Once you need lifecycle management, leasing, revocation, and audit across many services, a dedicated secrets manager is the right tool, and `{cipher}` becomes at best a complement (e.g., protecting the bootstrap token). **Summary heuristic:** `{cipher}` = at-rest protection for static secrets, guarding one crown-jewel key. Vault/KMS = lifecycle, leasing, policy, and audit for secrets at scale.
- Give a concrete migration story from {cipher} to Vault-backed secrets and what changes for clients.Stand up Vault and configure the Config Server's Vault backend (or Spring Cloud Vault on clients); replace static {cipher} DB passwords with dynamic, leased DB credentials that Vault mints with a TTL. Clients fetch/renew leases instead of a fixed value, gaining rotation, revocation, and audit; the static encrypt key stops being the single point of failure.
- Why is symmetric-key rotation operationally painful across many repos, and how does an RSA keystore help?A new symmetric key can't decrypt old ciphertext, so every value in every repo must be re-encrypted and rolled out together. A keystore with multiple aliases lets a new key coexist with the old, enabling staged, per-value re-encryption without a big-bang cutover.
saying these in an interview costs you the question
- Treating {cipher} as equivalent to a full secrets manager with rotation/audit
- Assuming rotating a symmetric key is free (it requires re-encrypting all values)
- Leaving /decrypt or actuator env dumps exposed
- Committing the key or keystore into the very repo it protects