Security
Published on: May 19, 2026
10 min read

Mastering Secret Management in Spring Boot (2026): Beyond application.properties

✍️ By Priya Singh (Principal Software Engineer)

Principal Software Engineer

Mastering Secret Management in Spring Boot (2026): Beyond application.properties
By Priya SinghSenior Technical Insights

application.properties is not a secrets store. It is a configuration file that gets committed to version control, baked into Docker images, loaded into JVM memory readable by heap dumps, and distributed across every developer laptop. Every secret stored there is one repository breach, one /actuator/env exposure, or one misplaced Docker push away from compromise. This guide covers the 2026 production path: Spring Cloud Config Server for configuration centralisation, AWS and GCP Secret Manager for managed secrets, HashiCorp Vault for dynamic credentials and Zero Trust RBAC, the CVE-2026-40982 Config Server vulnerability and its patch, and GraalVM Native Image for secure fast-booting microservices.

The question is never "should I stop putting secrets in application.properties?" The answer to that has been no since 2015. The question is what the replacement looks like at each maturity level — from a single Spring Boot service to a multi-team Kubernetes environment with strict compliance requirements. That is what this article is.

Where secrets leak from Spring Boot applications — in order of frequency

GITapplication.properties committed with real credentials — most common
ACTUATOR/actuator/env returns datasource URLs and passwords publicly
DOCKERSecrets baked into image layers, retrievable with docker history
HEAP DUMPIn-memory String values extracted from JVM heap dumps

1. Why application.properties Fails as a Secrets Store

Every Spring Boot developer knows not to commit credentials. And yet, according to GitGuardian's 2025 State of Secrets Sprawl report, millions of new secret leaks were detected in public repositories in 2025 — the majority in configuration files. The problem is not ignorance. It is the path of least resistance: application.properties is where Spring Boot looks for configuration by default, it is where tutorials put examples, and it is where credentials end up when velocity is prioritised over security discipline.

🚫 What I find in production Spring Boot repositories
application.properties · credentials in version control — extremely common
# application-prod.properties — committed to the main branch
spring.datasource.url=jdbc:postgresql://prod-db.internal:5432/orders
spring.datasource.username=orders_service
spring.datasource.password=Pr0d$ecret2024!     # ← in git history forever

jwt.secret=aBcDeFgHiJkLmNoPqRsTuVwXyZ123456    # ← every dev with repo access has this
stripe.api.key=sk_live_AbCdEfGhIjKlMnOp        # ← live payment key on every laptop

# Even after you delete this file and commit,
# git log --all --full-history -- application-prod.properties
# retrieves every version ever committed.

The three vectors that make dangerous beyond the obvious:

  • Git history is permanent. Removing a file does not remove its history. Tools like trufflehog, gitleaks, and GitHub's secret scanning find credentials in commits from years ago. If a repo ever goes public — intentionally or through a misconfigured visibility setting — those historical secrets are exposed.
  • Docker image layers preserve file content. A secret in application.properties that is COPY'd into a Docker image exists in that image layer even if you delete the file in a subsequent layer. docker history --no-trunc and image layer inspection tools expose this reliably.
  • Heap dumps and Actuator expose runtime secrets. JVM heap dumps (from /actuator/heapdump or a crash) contain all String values in memory — including database passwords held in DataSource objects. An exposed Actuator endpoint hands this to any attacker with network access.
GitGuardian's 2025 State of Secrets Sprawl reports that hardcoded secrets remain the most pervasive security risk in software development, with configuration files as the primary source. Source: GitGuardian · State of Secrets Sprawl 2025.

2. The Externalized Configuration Shift — Spring Cloud Config to Cloud Secret Managers

The maturity ladder for secret management in Spring Boot has three levels. Where you operate on that ladder depends on your team size, compliance requirements, and cloud footprint.

SECRET MANAGEMENT MATURITY LADDER — 2026 LEVEL 1 — LOCAL / TEAM Environment variables + .env files (not committed) ✓ Better than .properties ✓ Simple to implement ✗ No audit log ✗ No rotation mechanism ✗ Secrets on dev machines LEVEL 2 — TEAM / PRODUCTION Spring Cloud Config Server + AWS/GCP Secret Manager ✓ Centralised config ✓ Managed rotation (cloud) ✓ Basic audit trails ✗ Devs may have read access ✗ Static long-lived credentials LEVEL 3 — ENTERPRISE / ZERO TRUST HashiCorp Vault + Workload Identity + Dynamic secrets ✓ Dynamic short-lived creds ✓ No standing human access ✓ Full audit trail every access ✓ Automatic rotation ✓ RBAC per workload
Secret management maturity — from environment variables to Zero Trust dynamic credentials. Most production systems should be at Level 2 minimum.

Spring Cloud Config Server — Centralising Configuration

Spring Cloud Config Server centralises application properties across environments, backed by Git, filesystem, or a secrets provider. It is the correct first step from scattered per-service property files toward managed configuration.

pom.xml · Spring Cloud Config Server dependency
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-config-server</artifactId>
</dependency>
Java · ConfigServer application — enable with @EnableConfigServer
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConfigServerApplication.class, args);
    }
}
application.yml · Config Server — Git-backed with encryption
server:
  port: 8888

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/yourorg/config-repo
          # Use SSH key or token — never username/password
          private-key: ${GIT_SSH_PRIVATE_KEY}
          default-label: main
          search-paths:
            - '{application}'   # folder per service name

  # Encrypt property values at rest in the Git repo
  # Clients receive decrypted values over TLS
encrypt:
  key: ${CONFIG_ENCRYPT_KEY}   # AES symmetric key from environment

# CRITICAL: require authentication on all Config Server endpoints
security:
  user:
    name: ${CONFIG_SERVER_USER}
    password: ${CONFIG_SERVER_PASS}
Encrypted value in Git — stored as {cipher}... prefix
# config-repo/orders-service/application-prod.yml
spring:
  datasource:
    # Encrypted with spring encrypt key — plaintext never in Git
    password: '{cipher}AQA7Xm3kJp9...base64encodedencryptedvalue...'
🚨
Config Server must never be publicly accessible

Config Server serves decrypted configuration to any client that knows the URL and credentials. It must be on an internal network only — reachable by your services, not by the public internet. Network policy, VPC configuration, or a private load balancer are non-negotiable requirements for a production Config Server.

AWS Secrets Manager — Managed Rotation and Audit

pom.xml · AWS Secrets Manager + Spring Cloud AWS
<dependency>
  <groupId>io.awspring.cloud</groupId>
  <artifactId>spring-cloud-aws-secrets-manager</artifactId>
</version>3.1.1</version>
</dependency>
application.yml · AWS Secrets Manager integration
spring:
  config:
    import: "aws-secretsmanager:/config/orders-service/"
  # Spring Cloud AWS reads secrets at startup and injects as properties
  # Secret named /config/orders-service/prod maps to properties:
  # spring.datasource.password, jwt.secret, stripe.api.key

aws:
  secretsmanager:
    region: us-east-1
    # Auth via IAM role attached to EC2/ECS/EKS — never hardcode access keys
AWS CLI · create secret with automatic RDS rotation
# Create secret
aws secretsmanager create-secret \
  --name "/config/orders-service/prod" \
  --secret-string '{"spring.datasource.password":"initial-password","jwt.secret":"initial-jwt-key"}' \
  --region us-east-1

# Enable automatic rotation every 30 days for RDS credentials
aws secretsmanager rotate-secret \
  --secret-id "/config/orders-service/prod" \
  --rotation-lambda-arn arn:aws:lambda:us-east-1:123456789:function:SecretsManagerRDSRotation \
  --rotation-rules AutomaticallyAfterDays=30

GCP Secret Manager — Workload Identity and IAM

pom.xml · GCP Secret Manager + Spring Cloud GCP
<dependency>
  <groupId>com.google.cloud</groupId>
  <artifactId>spring-cloud-gcp-starter-secretmanager</artifactId>
  <version>4.8.3</version>
</dependency>
application.yml · GCP Secret Manager — Workload Identity auth
spring:
  config:
    import: "gcp-secretmanager:"
  cloud:
    gcp:
      project-id: your-project-id
      # Workload Identity: GKE pod authenticates as a GCP service account
      # No credentials file needed — identity comes from the Kubernetes pod spec
      secretmanager:
        credentials:
          location: ""  # empty — use Workload Identity from GKE node pool

# Reference secrets using sm:// prefix in any property
# app.db.password=${sm://projects/your-project/secrets/db-password/versions/latest}
Workload Identity is the correct auth pattern for GKE

Workload Identity binds a Kubernetes service account to a GCP service account. Pods running with that Kubernetes service account automatically authenticate to GCP APIs — including Secret Manager — without any credentials file, environment variable, or long-lived API key. This is the Zero Trust approach: the workload's identity is asserted by the platform, not by a stored secret.

3. Solving the 2026 CVEs — Patching CVE-2026-40982

CVE-2026-40982 Spring Cloud Config Server · Critical

Directory Traversal via Unvalidated Application Name / Profile Parameters

Vulnerability: Spring Cloud Config Server versions prior to 4.1.5 and 3.1.9 are vulnerable to a directory traversal attack. An unauthenticated attacker can craft a request where the application name or profile parameter contains path traversal sequences (../, URL-encoded as %2F..%2F). The server resolves these against the filesystem-backed config repository, allowing the attacker to read arbitrary files from the server filesystem — including private keys, OS configuration files, and credentials stored outside the config directory.

Example malicious request: GET /../../etc/passwd/default HTTP/1.1

Affected versions: Spring Cloud Config Server 4.0.x ≤ 4.1.4, 3.1.x ≤ 3.1.8

CVSS Score: 9.1 (Critical) — unauthenticated, network-accessible, low complexity

Immediate Mitigation Steps

pom.xml · patch — upgrade to fixed Spring Cloud Config version
<!-- Spring Cloud BOM — use 2024.0.1+ which includes Config Server 4.1.5+ -->
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-dependencies</artifactId>
      <version>2024.0.1</version>   <!-- includes Config Server 4.1.5 -->
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>
application.yml · defence-in-depth — input validation + access restriction
spring:
  cloud:
    config:
      server:
        # Added in 4.1.5 — validates application and profile params
        # Rejects any value containing path separators or traversal sequences
        validate-application-name: true

        git:
          # Restrict to a specific base directory — traversal cannot escape it
          basedir: /opt/config-repo
          # Force-pull prevents local modification of cloned config
          force-pull: true

# Require authentication on ALL Config Server endpoints
# Even with the CVE patched, unauthenticated Config Server is wrong architecture
management:
  endpoints:
    web:
      exposure:
        include: health, info
  server:
    port: 9090   # Separate internal port — never the same as public port
NGINX · network-level protection — block Config Server from public internet
# nginx.conf · Only allow Config Server access from internal service CIDR
location /config-server/ {
    # Allow only internal service IP ranges
    allow 10.0.0.0/8;
    allow 172.16.0.0/12;
    allow 192.168.0.0/16;
    deny all;  # Everything else rejected at network layer

    proxy_pass http://config-server:8888/;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
🚨
If you cannot upgrade immediately

As a temporary mitigation before patching: add a servlet filter that validates the application and profile path variables against an allowlist regex (^[a-zA-Z0-9_-]+$) and rejects any value containing /, \, .., or URL-encoded equivalents. This is a stop-gap — upgrade to 4.1.5 or 3.1.9 as the definitive fix.

4. Zero Trust Secret Management — Least-Privilege RBAC with HashiCorp Vault

Zero Trust for secrets means: no service or person has standing access to a production credential. Access is granted on-demand, scoped to the minimum required, time-limited, and fully audited. The tool that implements this most completely for Spring Boot environments is HashiCorp Vault.

The key capability that makes Vault different from Secrets Manager: dynamic secrets. Instead of storing a database password, Vault generates a unique temporary username and password pair for each service request. That credential expires in 1 hour. If it is stolen, it expires before it can be reused. No rotation required — the secret never lived long enough to need it.

VAULT DYNAMIC SECRETS — ZERO TRUST CREDENTIAL FLOW SPRING BOOT SERVICE POD 1. Auth with K8s service account 2. Request DB creds 2. Request DB creds 3. Use creds (1hr TTL) 4. Creds auto-expire HASHICORP VAULT Auth: Kubernetes backend Validates K8s JWT → Checks RBAC policy → Generates unique creds → TTL: 1 hour Logs every access POSTGRESQL Managed by Vault Vault creates temp user: v-orders-abc123 GRANT SELECT, INSERT ON orders_schema Auto-drops after TTL AUDIT LOG Every access: WHO requested WHAT secret WHEN issued WHEN expires Immutable log
Vault dynamic secrets — no stored credential. Each service gets a unique, time-limited credential generated on request and expired automatically.
pom.xml · Spring Vault dependency
<dependency>
  <groupId>org.springframework.vault</groupId>
  <artifactId>spring-vault-core</artifactId>
  <version>3.1.2</version>
</dependency>
application.yml · Spring Boot + HashiCorp Vault — Kubernetes auth
spring:
  config:
    import: vault://

  cloud:
    vault:
      host: vault.internal.yourcompany.com
      port: 8200
      scheme: https

      # Kubernetes auth backend — pod authenticates using its service account JWT
      authentication: KUBERNETES
      kubernetes:
        role: orders-service-role          # Vault role mapped to K8s service account
        kubernetes-path: auth/kubernetes   # Vault auth mount path

      # Dynamic database secrets — Vault generates creds, Spring connects
      databases:
        enabled: true
        backend: database               # Vault database secrets engine
        role: orders-service-db-role    # mapped to PostgreSQL GRANT statement

Zero Trust RBAC — Developers Manage Clusters Without Touching Database Credentials

HCL · Vault policy — orders service can only read its own secrets
# vault-policy-orders-service.hcl
# Orders service can ONLY read dynamic DB creds and its own KV secrets
# It CANNOT read payment service secrets, admin credentials, or other service paths

path "database/creds/orders-service-db-role" {
  capabilities = ["read"]   # Request dynamic PostgreSQL credentials
}

path "secret/data/orders-service/*" {
  capabilities = ["read"]   # Read own KV secrets (JWT key, API keys)
}

# Explicit deny — belt-and-suspenders
path "secret/data/payment-service/*" {
  capabilities = ["deny"]
}

path "database/creds/payment-service-*" {
  capabilities = ["deny"]
}

# Deny access to Vault system paths
path "sys/*" {
  capabilities = ["deny"]
}
path "auth/*" {
  capabilities = ["deny"]
}
HCL · Vault policy — developer role (NO production secret access)
# vault-policy-developer.hcl
# Developers can manage dev/staging secrets and view audit logs
# CANNOT read production database credentials or production JWT secrets

path "secret/data/dev/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

path "secret/data/staging/*" {
  capabilities = ["read", "list"]
}

# Production: ZERO access for developers
# Production secrets are readable only by service workload identities
path "secret/data/production/*" {
  capabilities = ["deny"]
}

path "database/creds/production-*" {
  capabilities = ["deny"]
}
What Zero Trust RBAC achieves operationally

A developer who needs to debug a production database issue files an emergency access request. Vault issues a time-limited (2-hour) read-only credential for that specific database. The access is logged. It expires automatically. No production credential ever lives on a developer's machine or in their environment variables. This is the architecture that passes SOC 2 Type II, PCI DSS, and HIPAA audits cleanly.

5. GraalVM Native Image and Quarkus — Secure Fast-Booting Microservices

GraalVM Native Image compiles Spring Boot applications to a native executable at build time, eliminating the JVM. This has direct security implications for secret management — and it changes what "externalize your secrets" means operationally.

Security Implications of Native Image

  • Properties baked at compile time are permanent. Any value in application.properties resolved during the native-image build is embedded in the executable binary. Rotating a hardcoded secret requires a full rebuild and redeployment. This makes compile-time secrets worse in native images than in JVM applications — the argument for externalised secrets becomes even stronger.
  • No JVM heap to dump. The traditional JVM heap dump attack vector — reading String values from a heap dump captured via /actuator/heapdump — is eliminated. Native images have a much smaller and different memory model.
  • Smaller attack surface. Native images do not include the full JDK, reflection capabilities are limited, and unused classes are eliminated at build time. This reduces the surface available for exploitation.
  • Faster secret injection. Native images start in milliseconds. Secrets injected via environment variables at container startup are available near-instantly — enabling short-lived container patterns where the container is replaced frequently.
pom.xml · GraalVM Native Image support for Spring Boot 3
<plugin>
  <groupId>org.graalvm.buildtools</groupId>
  <artifactId>native-maven-plugin</artifactId>
  <version>0.10.3</version>
  <executions>
    <execution>
      <id>build-native</id>
      <goals><goal>compile-no-fork</goal></goals>
      <phase>package</phase>
    </execution>
  </executions>
</plugin>
Dockerfile · native image — secrets via runtime environment, not compile-time
# Stage 1: Build native image
FROM ghcr.io/graalvm/native-image:21 AS builder
WORKDIR /app
COPY . .
RUN ./mvnw -Pnative package -DskipTests

# Stage 2: Minimal runtime image — no JDK needed
FROM ubuntu:22.04
RUN useradd -r -s /bin/false appuser   # non-root user
COPY --from=builder /app/target/orders-service /app/orders-service
RUN chown appuser:appuser /app/orders-service

USER appuser

# IMPORTANT: No ENV instructions for secrets here.
# Secrets are injected at runtime by Kubernetes secretKeyRef or AWS ECS secrets
# They are NEVER baked into the image layer.

ENTRYPOINT ["/app/orders-service"]
Kubernetes deployment · inject secrets at runtime — never in image
apiVersion: apps/v1
kind: Deployment
metadata:
  name: orders-service
spec:
  template:
    spec:
      serviceAccountName: orders-service-sa   # Workload identity for Vault / GCP / AWS
      containers:
      - name: orders-service
        image: your-registry/orders-service:latest
        env:
        # Database credentials from Kubernetes Secret (populated by external-secrets operator)
        - name: SPRING_DATASOURCE_PASSWORD
          valueFrom:
            secretKeyRef:
              name: orders-db-credentials   # K8s secret managed by Vault or AWS SM
              key: password
        - name: JWT_SECRET
          valueFrom:
            secretKeyRef:
              name: orders-jwt-secret
              key: value
        # Application configuration — non-sensitive, in ConfigMap
        - name: SPRING_DATASOURCE_URL
          valueFrom:
            configMapKeyRef:
              name: orders-config
              key: db-url

Quarkus as an Alternative

Quarkus provides native image compilation with a developer experience optimised for Kubernetes from day one. Its secret management integration is direct — no Spring Cloud Config adapter required.

application.properties · Quarkus + HashiCorp Vault integration
# quarkus.properties
quarkus.vault.url=https://vault.internal.yourcompany.com:8200
quarkus.vault.authentication.kubernetes.role=orders-service-role

# Dynamic database secrets — Quarkus reads from Vault at startup
quarkus.datasource.credentials-provider=vault-credentials-provider
quarkus.datasource.credentials-provider-name=database/creds/orders-service-db

# Quarkus config source from Vault KV
quarkus.vault.secret-config-kv-path=secret/data/orders-service
AspectSpring Boot 3 NativeQuarkus Native
Startup time~50–100ms~20–50ms
Vault integrationSpring Cloud Vault (well-documented)Quarkus Vault extension (native-first)
Kubernetes secrets injectionStandard env var injectionStandard env var injection
Team migration costLow (existing Spring knowledge)Medium (Quarkus-specific patterns)
Memory footprint~30–60MB RSS~15–30MB RSS
GraalVM reflection configSpring auto-generates hintsBuilt-in, less manual config

6. Production Secret Management Checklist

  • Zero secrets in any committed configuration file — including encrypted values (rotate any key that was ever committed) Git hygiene
  • Gitleaks or Trufflehog running in pre-commit hooks and CI pipeline Prevention
  • Spring Cloud Config Server upgraded to 4.1.5+ (CVE-2026-40982 patch) CVE patch
  • Config Server accessible only from internal network — never public internet Network
  • Config Server requires authentication on all endpoints Auth
  • Application secrets sourced from AWS Secrets Manager, GCP Secret Manager, or Vault at startup Externalised
  • Production database credentials are dynamic (Vault) or auto-rotating (AWS RDS rotation) Rotation
  • Developers have zero standing access to production credentials — emergency access via time-limited Vault lease Zero Trust
  • Kubernetes workload identity used for cloud auth — no long-lived API keys or service account JSON files Workload identity
  • Vault / Secrets Manager audit logging enabled and sent to SIEM Audit
  • Docker images contain no secrets — verified with docker history --no-trunc before registry push Container
  • Spring Boot Actuator endpoints locked down — /actuator/env and /actuator/heapdump inaccessible publicly Actuator
  • Native image builds inject secrets via Kubernetes secretKeyRef at runtime — never compile-time Native
  • Secret rotation tested — application handles credential refresh without restart Resilience

"A secret that ever existed in version control is not a secret. It is a shared plaintext credential waiting to be found."


FAQ — Spring Boot Secret Management 2026

Why is application.properties unsafe for storing secrets?

application.properties is committed to version control, included in Docker image layers, visible in heap dumps and /actuator/env endpoints, and distributed across developer machines. Any secret stored there is accessible to everyone with repository access, every CI runner, every Docker registry that stores the image, and any process that can read JVM memory. Secrets in application.properties are not secrets — they are shared plaintext credentials with a wide and uncontrolled distribution.

What is the difference between Spring Cloud Config Server and AWS Secrets Manager?

Spring Cloud Config Server is a self-hosted service that centralises application configuration across environments, with optional encryption and Git-backed storage. It handles all configuration — not just secrets. AWS Secrets Manager is a managed cloud service specifically for credentials, with IAM-based access control, automatic rotation for RDS and other AWS services, and CloudTrail audit logging. Production systems often use both: Config Server for non-sensitive environment configuration, Secrets Manager for credentials that require rotation and audit.

What is HashiCorp Vault and when should I use it?

HashiCorp Vault is an open-source secrets management platform providing dynamic secret generation (database credentials that expire automatically), fine-grained RBAC policies, complete audit logging, and support for Kubernetes, AWS IAM, and JWT auth backends. Use Vault when you need cloud-agnostic secrets management, dynamic credentials with automatic expiry, or compliance requirements demanding fine-grained access control and immutable audit trails across multi-cloud or on-premises environments.

What is Zero Trust secret management?

Zero Trust secret management means no service, developer, or system is trusted by default to access a secret — access must be explicitly granted, scoped to the minimum required, and revoked automatically when no longer needed. In practice: developers have no standing access to production database credentials; services receive short-lived dynamic credentials that expire in hours; access is granted by workload identity (Kubernetes service account, AWS IAM role) not long-lived API keys; every secret access is logged for audit.

What is CVE-2026-40982 and how do I patch it?

CVE-2026-40982 is a directory traversal vulnerability in Spring Cloud Config Server where an unauthenticated attacker crafts a request with path traversal sequences in the application name or profile parameter, allowing arbitrary filesystem file reads. CVSS 9.1 — Critical. Mitigation: upgrade to Spring Cloud Config 4.1.5+ (or 3.1.9+), enable spring.cloud.config.server.validate-application-name=true, restrict Config Server network access to internal services only, and require authentication on all Config Server endpoints.

Does GraalVM Native Image affect secret management?

Yes — in two directions. Native images eliminate the JVM heap dump attack vector. But any application.properties value resolved at compile time is baked permanently into the binary — making compile-time secrets harder to rotate than in JVM applications. Native images strengthen the case for runtime secret injection: use Kubernetes secretKeyRef, AWS Secrets Manager, or Vault to inject secrets at container startup via environment variables. Never embed credential values in the native image at build time.

Secret Management Is a Maturity Decision, Not a Single Implementation

There is no single correct answer to "how should my Spring Boot application manage secrets?" There is a maturity ladder, and your position on it should match your team size, compliance requirements, and operational sophistication.

A two-person team shipping a SaaS MVP has a different correct answer than a forty-person platform team operating under PCI DSS. Both need to externalise secrets from application.properties. One needs environment variables and a well-configured Secrets Manager. The other needs Vault dynamic credentials, Zero Trust RBAC, immutable audit logs, and GraalVM native images with Kubernetes workload identity.

The non-negotiable minimum in 2026:

  • No secrets in version control. Gitleaks in CI. Rotate anything that was ever committed.
  • Spring Cloud Config Server patched to 4.1.5+ for CVE-2026-40982. Never publicly exposed.
  • Production credentials from a managed service — AWS Secrets Manager, GCP Secret Manager, or Vault. Not environment variables on the host.
  • Actuator locked down. /actuator/env and /actuator/heapdump inaccessible to unauthenticated callers.

The distance between "secrets in application.properties" and "Zero Trust dynamic credentials with workload identity" is large. But the first step — removing secrets from committed files — is a day's work. Do that first. Build upward from there. — Priya

Audit Your Running API for Secret Exposure

Test whether your /actuator/env endpoint exposes secrets, check your security headers, and verify your error responses don't leak credentials.

Third-Party Links Disclaimer

This article may contain links to third-party websites, documentation, tools, or services for reference and additional information. These external resources are maintained by their respective owners, and LearnHubly does not control or guarantee their availability, accuracy, security, or content. Please review the terms and privacy policies of third-party websites before using their services.

Priya Singh

Java
Spring Boot
React
APIs

Principal Software Engineer • 15+ Years Experience

Priya Singh is a Principal Software Engineer with 15+ years of experience building scalable applications and developer tools. She specializes in backend architecture, APIs, and performance optimization.