skip to content

In a Spring Cloud Config Server property repository, what does the {cipher} prefix on a property value mean, and what happens to it before the client receives the value?

level: juniorimportance: must knowfreq 55%

answer

  1. {cipher}<blob> = encrypted at rest
  2. server holds key, decrypts before responding
  3. client gets plaintext, needs no key
  4. quote it in YAML: '{cipher}...'
  5. undecryptable -> <n/a>, fail fast

basics

~20 s

{cipher} marks a property value as encrypted at rest in the config repo. By default the Config Server decrypts it and sends the plain value to the client, so the secret never sits in git as plaintext.

solid answer

~40 s

Spring Cloud Config lets you keep secrets encrypted in the config git repo by prefixing the value with {cipher}, e.g. spring.datasource.password: '{cipher}AQBc9f...'. The token after {cipher} is the encrypted blob. When a client fetches its configuration, the Config Server (which holds the encryption key) decrypts every {cipher} value before serializing the response, so the client receives normal plaintext and needs no key. This keeps secrets out of version control in readable form. In YAML you must quote the whole value because { starts a flow-map. If the server has no key configured, or cannot decrypt a value, it replaces it with a placeholder like <n/a> and marks the property invalid, so the app fails fast rather than leaking or silently using garbage.

code

yaml · 10 lines
yaml
# application.yml stored in the Config Server's git repo
spring:
  datasource:
    username: app
    # {cipher} marks an encrypted-at-rest value; MUST be quoted in YAML
    password: '{cipher}AQBc9f2hXk1oQ7pR...=='

# The client that pulls this config just sees:
#   spring.datasource.password = <the decrypted plaintext>
# because the Config Server decrypted it server-side before responding.

go deeper

for a junior

Know that {cipher} means the value is encrypted in the repo and the server decrypts it before the client sees it.

for a middle

Explain server-side default decryption, the YAML quoting gotcha, and that the client needs no key.

for a senior

Discuss the spring-security-rsa dependency, <n/a> fail-fast behavior, and the encrypt.enabled toggle for client-side decryption.

for a principal

Frame it in the broader secrets strategy: at-rest protection vs a real KMS/Vault, key custody, and blast radius if the server key leaks.

**The problem.** Spring Cloud Config Server serves application configuration (often from a git repo) to client apps at startup. Storing secrets such as DB passwords or API keys as plaintext in that repo is a security risk (anyone with repo read access sees them). Encrypted properties solve this: secrets are stored **encrypted at rest** in the repo and decrypted just-in-time. **The `{cipher}` convention.** Any property value written as `{cipher}<ciphertext>` is treated as an encrypted value. Example in `application.yml` in the config repo: ```yaml spring: datasource: password: '{cipher}AQBc9f2h...==' ``` The `{cipher}` is a literal marker (not a placeholder to be substituted). The blob after it is Base64 ciphertext produced by the server's `/encrypt` endpoint. **Default behavior: server-side decryption.** By default (`spring.cloud.config.server.encrypt.enabled=true`), when a client requests its config, the Config Server iterates over property sources, finds `{cipher}` values, and **decrypts them using the key it holds**, then returns plaintext to the client. The client therefore needs **no key** and no special code — it just sees `password: mysecret`. This is the common setup. **Requirements.** For encryption/decryption to work the server needs (1) the JCE crypto available (modern JDKs ship unlimited-strength JCE by default; very old JDKs needed the JCE Unlimited Strength policy files), and (2) the `spring-security-rsa` library on the classpath (pulled in transitively by `spring-cloud-config-server`) for the `TextEncryptor` implementations. It also needs a key configured — either a symmetric `encrypt.key` or an RSA keystore. **YAML gotcha.** Because `{` begins a YAML flow mapping, an unquoted `{cipher}...` is a syntax error. Always quote: `'{cipher}...'`. In `.properties` files no quoting is needed. **Failure handling.** If the server has no key, or a value can't be decrypted, the property is rendered as `<n/a>` (or `<n/a: ...>`) and the property source is flagged invalid, causing the client to fail rather than boot with a broken secret. **When to use.** Use `{cipher}` whenever secrets must live in a shared config repo. For higher-assurance setups people instead delegate to a real secrets manager (Vault backend), but `{cipher}` is the built-in, zero-dependency option.

  • Why must a {cipher} value be quoted in a YAML config file but not in a .properties file?
    In YAML a leading { starts a flow mapping, so an unquoted {cipher}... is invalid syntax; quoting makes it a plain string. .properties values are already raw strings, so no quoting is needed.
  • If the config repo is public but properly using {cipher}, what secret does an attacker still need to actually read the passwords?
    The encryption key held by the Config Server (the symmetric encrypt.key or the RSA keystore private key). Without it the ciphertext is useless; that key must be protected and kept out of the repo.

context