intermediate~2h

Spring Boot + Secrets Manager & Parameter Store

Externalizing Spring Boot configuration and secrets to AWS Secrets Manager and Systems Manager Parameter Store, instead of properties files or environment variables baked into an image.

Want a visual for this topic?

Generate a diagram tailored to Spring Boot + Secrets Manager & Parameter Store — the AI picks whichever visual (architecture, flowchart, ER diagram, etc.) best fits this specific AWS concept.

Sign in to generate a visual →
0
Subtopics

🎓 Learning objectives

  • Explain the difference between Parameter Store and Secrets Manager, and when to use each
  • Configure Spring Cloud AWS to load configuration from Parameter Store/Secrets Manager at startup
  • Understand automatic secret rotation and its implication for already-running application instances
  • Explain why baking secrets into a container image or Kubernetes ConfigMap is a mistake

What is it?

Integrating Spring Boot with Secrets Manager and Parameter Store means externalizing configuration values and secrets out of the application's packaged artifact (JAR/container image) entirely, loading them instead at runtime via Spring Cloud AWS's spring.config.import support — Parameter Store for general configuration and simple secrets (lower cost, SecureString support), Secrets Manager specifically for credentials that benefit from built-in automatic rotation (database passwords, API keys) with native rotation Lambda functions for common database engines.

Why it exists

This pattern exists because baking secrets into build artifacts or plaintext configuration was, for a long time, the default and clearly problematic way applications handled credentials — image layers and committed config files are effectively permanent and often more widely accessible than the secret warrants. Parameter Store and Secrets Manager exist to give applications a runtime-fetched, IAM-controlled, auditable (via CloudTrail) alternative, with Secrets Manager specifically adding the rotation automation that credentials genuinely benefit from and Parameter Store didn't originally provide.

Problem it solves

It solves keeping secrets and configuration out of build artifacts and source control entirely, replacing that risk with IAM-controlled, audited, runtime-fetched values — and, for Secrets Manager specifically, solves the operational burden of manually rotating database credentials by automating it end-to-end.

Intuition

The core principle: nothing sensitive should ever be baked into an artifact that gets built once and potentially lives forever (an image layer, a committed config file) — configuration and secrets should be fetched at runtime from a system whose access is IAM-controlled and whose values can change independently of any redeploy.

Analogy

Parameter Store is a labeled filing cabinet for configuration values and simple secrets — reliable, low-cost, gets the job done for most things. Secrets Manager is a purpose-built safe specifically for things that need to be periodically and automatically re-keyed (rotated) without anyone manually swapping the lock — worth the extra cost specifically for credentials where rotation genuinely matters, like a database password.

Technical explanation

Spring Cloud AWS's spring.config.import: aws-secretsmanager: and aws-parameterstore: prefixes register a custom PropertySource that resolves at Spring Boot's configuration-loading phase (before bean creation), meaning values from these sources are available exactly as early as any other property source, including for @ConfigurationProperties binding at context startup — this is what makes them indistinguishable from local properties to the rest of the application's code. Secrets Manager's rotation Lambda functions implement a documented four-step rotation protocol (createSecret, setSecret, testSecret, finishSecret) that first creates a new credential version without disrupting the currently-active one, verifies the new credential actually works against the target database, and only then marks it as the current version — this staged approach is why rotation can happen safely without a coordinated application restart, though an application still needs its own mechanism (or the Secrets Manager JDBC wrapper) to actually notice and start using the newly-current version rather than continuing to use a cached one from before rotation.

Architecture

At application startup, Spring Cloud AWS's config-import mechanism calls the Parameter Store/Secrets Manager APIs (using the application's IAM role credentials, resolved the same way as any other AWS SDK call) to fetch the referenced parameters/secrets, merging their values into the Spring Environment alongside values from application.yml and other property sources — from the application code's perspective, a value pulled from Secrets Manager is indistinguishable from one defined in a local properties file. Secrets Manager's automatic rotation works by periodically invoking a configured Lambda function (AWS provides ready-made ones for common database engines) that creates a new credential, updates the database to accept it, and updates the secret's stored value — all orchestrated by Secrets Manager on a schedule, independent of whether any application is currently reading that secret.

Workflow

  1. Store configuration values in Parameter Store (as String or SecureString parameters under a hierarchical path like /myapp/prod/...) and credentials needing rotation in Secrets Manager. 2) Add the Spring Cloud AWS config-import dependencies. 3) Reference them via spring.config.import in application.yml, using the aws-parameterstore:/aws-secretsmanager: prefixes. 4) Grant the application's IAM role (task role/IRSA role/instance profile) ssm:GetParameter(s) and/or secretsmanager:GetSecretValue permissions scoped to exactly the specific paths/secrets it needs. 5) For secrets that rotate, plan for how running instances pick up new values — either accepting a restart-based refresh cadence, wiring a scheduled refresh, or using the Secrets Manager JDBC wrapper for database credentials specifically.

Example

A Spring Boot application's application.yml includes spring.config.import: aws-secretsmanager:prod/myapp/db-credentials,aws-parameterstore:/config/myapp/, pulling the database password from a rotating Secrets Manager secret and general feature-flag/configuration values from a Parameter Store path — neither value is ever present in the container image, a Kubernetes manifest, or source control.

Real-world usage

Nearly every production Spring Boot application on AWS handling database credentials, third-party API keys, or other sensitive configuration uses Secrets Manager or Parameter Store rather than plaintext configuration, and this is frequently an explicit compliance/audit requirement (SOC 2, PCI DSS) rather than just a best practice — auditors specifically look for the absence of plaintext secrets in source control and container images, and Secrets Manager's CloudTrail-logged access plus automatic rotation is commonly cited as direct evidence of meeting that control.

Trade-offs

Parameter Store's standard tier is free and simpler, but lacks Secrets Manager's built-in rotation Lambda functions — implementing rotation for a Parameter Store SecureString value requires building that automation yourself. Secrets Manager costs a per-secret monthly fee plus API call charges, which adds up for a large number of simple configuration values that don't actually need rotation — using Secrets Manager for every single config value regardless of whether it needs rotation is needlessly expensive compared to using Parameter Store for the ones that don't.

Visual explanation

Picture a building where nobody carries their own keys pre-cut and stapled to their badge (baked-in secrets) — instead, everyone requests the correct key from a monitored key desk (Parameter Store/Secrets Manager) each time they need it, the desk logs every request (CloudTrail), and for the highest-security doors, the desk automatically swaps the lock on a schedule (Secrets Manager rotation) without needing anyone to manually walk around re-cutting keys.

Advantages

  • Secrets and configuration are never baked into a container image, JAR, or committed config file, closing off an entire class of credential-leak risk

  • IAM-scoped access to specific parameters/secrets, fully audited via CloudTrail, rather than a shared file anyone with repo/image access could read

  • Secrets Manager's built-in rotation Lambda functions for RDS/Aurora/DocumentDB/Redshift automate credential rotation with no custom automation to build

  • Spring Cloud AWS's spring.config.import integration means application code reads these values exactly like any other Spring property — no AWS-specific code required in business logic

Disadvantages

  • A naive startup-only read of a rotating secret means already-running application instances keep using the stale credential until restarted or redeployed

  • Secrets Manager's per-secret cost adds up if used indiscriminately for every configuration value rather than reserved for genuinely sensitive, rotation-worthy credentials

  • Adding a new external dependency (Parameter Store/Secrets Manager availability) to application startup means an outage or misconfigured IAM permission there can prevent the application from starting at all

  • Managing the hierarchical Parameter Store path structure and Secrets Manager secret naming convention across multiple environments/applications requires a deliberate, consistent naming scheme to stay manageable at scale

Common mistakes

  • Storing a rotating credential as a plain Parameter Store String (or SecureString) with no rotation automation, when Secrets Manager's built-in rotation would have handled it natively

  • Assuming a running application instance automatically picks up a rotated secret's new value without any refresh mechanism, when a naive startup-only read leaves it using the stale value indefinitely

  • Granting an application's IAM role broad secretsmanager:GetSecretValue access to all secrets instead of scoping the policy to the exact secret ARN(s) it actually needs

  • Still baking a fallback/default secret value into application.yml 'just in case,' reintroducing exactly the plaintext-secret risk this whole pattern exists to eliminate

In the AWS Console

  1. 1

    Systems Manager → Parameter Store → Create parameter, selecting type SecureString

    Store a configuration value as a SecureString parameter in Parameter Store, encrypted with KMS.

  2. 2

    Secrets Manager → Store a new secret → Credentials for RDS database, then Rotation configuration

    Create a secret in Secrets Manager for database credentials and enable automatic rotation with the built-in RDS rotation function.

  3. 3

    IAM → Roles → [task/IRSA/instance role] → Add permissions → Create inline policy

    Attach an IAM policy to the application's execution role scoped to exactly the parameter path or secret ARN it needs.

🎤 Interview questions

What's the practical difference between Parameter Store and Secrets Manager, given that both can store a string value? (Listen for: Parameter Store is a general-purpose, lower-cost configuration store (standard tier is free) supporting plain and SecureString parameters, well suited for configuration values and simple secrets; Secrets Manager costs more per secret but adds purpose-built secret features — automatic rotation with built-in Lambda rotation functions for RDS/DocumentDB/Redshift, versioning, and cross-account resource policies — making it the better fit specifically for credentials that need to rotate)

How does Spring Cloud AWS load configuration from Parameter Store or Secrets Manager into a Spring Boot application? (Listen for: via a spring.config.import entry (e.g., aws-parameterstore: or aws-secretsmanager: prefix) that Spring Cloud AWS resolves at application startup, pulling matching parameters/secrets into the Spring Environment as if they were properties — application code accesses them the same way as any other @Value or @ConfigurationProperties-bound property, with no AWS-specific code in the business logic)

If Secrets Manager rotates a database secret automatically, does a Spring Boot application that read that secret once at startup automatically pick up the new value? (Listen for: no — a naive startup-only read caches the old value in the Spring Environment for the life of the running instance; correctly handling rotation requires either restarting/redeploying instances after rotation, using a mechanism to periodically refresh the configuration, or (for database credentials specifically) using the Secrets Manager JDBC driver wrapper that fetches fresh credentials per new connection rather than relying on Spring's cached config value at all)

Why is baking a secret directly into a Docker image or a plain Kubernetes ConfigMap a security mistake? (Listen for: a Docker image layer is effectively permanent and often pushed to a registry accessible to more people/systems than should see the secret, and image layers can be inspected/extracted even after later layers overwrite files; a plain ConfigMap (unlike a Kubernetes Secret, and even Secrets are only base64-encoded, not encrypted, without additional configuration) is visible to anyone with read access to it — Secrets Manager/Parameter Store SecureString centralizes secrets with proper encryption (via KMS) and access control (via IAM), auditable through CloudTrail, none of which a baked-in value provides)

How would you grant an ECS task or EKS Pod permission to read a specific Secrets Manager secret, without granting broader access? (Listen for: attach an IAM policy to the task role (ECS) or the IRSA-associated IAM role (EKS) scoped to secretsmanager:GetSecretValue on the specific secret's ARN, following least privilege — never granting account-wide Secrets Manager access when only one specific secret is actually needed)

💬 Deep Dive with AI

Related concepts

kms-encryptionspring-boot-rds-integrationiam-fundamentals

Next Step

Continue to CI/CD Pipeline for Spring Boot on AWS