From Hardcoded to Secure: Managing Secrets in Java Apps with External Secrets Operator

As Java developers, we've all been there: you need to connect to a database, an external API, or a message broker, and you're faced with the credentials problem. Hardcoding secrets in application.properties is a cardinal sin, and while environment variables or Kubernetes Secrets are better, they still leave us with challenges in management, rotation, and security. The External Secrets Operator (ESO) solves this by bridging the gap between Kubernetes and professional secret managers.

What is the External Secrets Operator?

The External Secrets Operator is a Kubernetes operator that automatically synchronizes secrets from external secret management systems (like AWS Secrets Manager, HashiCorp Vault, Azure Key Vault, etc.) into regular Kubernetes Secrets. It uses a declarative approach—you define what secret you want, and ESO handles the how of fetching and creating it.

Think of it as a "secret injection" system for your Kubernetes deployments. Your Java application remains completely agnostic to where the secrets come from; it just reads them from a standard Kubernetes Secret or Environment Variable as usual.

The Java Developer's Secret Management Journey

Let's trace the evolution of a typical Spring Boot application's database configuration:

Level 0: The Hardcoded Sin (Never do this)

# application.properties
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=admin
spring.datasource.password=SuperSecret123!

Level 1: Environment Variables (Better, but still manual)

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: app
image: my-app:latest
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password

You still have to manually create the db-secret and keep it in sync across environments.

Level 2: External Secrets Operator (The Modern Approach)
Your deployment stays the same, but the secret is automatically populated from AWS Secrets Manager or HashiCorp Vault.

How ESO Works: Declarative Secret Syncing

ESO introduces three main Custom Resource Definitions (CRDs):

  1. SecretStore: Defines where to get secrets from (e.g., which AWS account, Vault server)
  2. ClusterSecretStore: A cluster-wide version of SecretStore
  3. ExternalSecret: Defines which secrets to fetch and how to create them as K8s Secrets

A Practical Example: Spring Boot with PostgreSQL

Let's set up ESO to automatically inject database credentials from AWS Secrets Manager.

Step 1: Define the SecretStore (Platform Team Setup)

First, we tell ESO how to access our external secret manager:

# secret-store.yaml
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: aws-secret-store
namespace: default
spec:
provider:
aws:
service: SecretsManager
region: us-west-2
auth:
secretRef:
accessKeyIDSecretRef:
name: aws-credentials
key: access-key
secretAccessKeySecretRef:
name: aws-credentials
key: secret-key

Note that ESO needs credentials to access AWS. These are stored in a regular Kubernetes Secret:

# aws-credentials-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: aws-credentials
namespace: default
type: Opaque
data:
access-key: <base64-encoded-access-key>
secret-key: <base64-encoded-secret-key>

Step 2: Define the ExternalSecret (Application Developer)

Now, as a Java developer, you declare which specific secrets your application needs:

# external-secret.yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: database-credentials
namespace: default
spec:
refreshInterval: 1h
secretStoreRef:
name: aws-secret-store
kind: SecretStore
target:
name: db-secret  # The K8s Secret that will be created
data:
- secretKey: username  # Key in the K8s Secret
remoteRef:
key: prod/app/database  # Key in AWS Secrets Manager
property: username      # Specific property in the JSON secret
- secretKey: password  # Key in the K8s Secret  
remoteRef:
key: prod/app/database
property: password

In AWS Secrets Manager, the secret prod/app/database would be a JSON object:

{
"username": "app_user",
"password": "SecurePassword123!",
"host": "db-host.region.rds.amazonaws.com"
}

Step 3: Deploy Your Spring Boot Application

Your Java application's deployment remains clean and simple, consuming the automatically created Kubernetes Secret:

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-boot-app
spec:
template:
spec:
containers:
- name: app
image: my-company/spring-boot-app:latest
env:
- name: SPRING_DATASOURCE_USERNAME
valueFrom:
secretKeyRef:
name: db-secret    # Created by ESO!
key: username
- name: SPRING_DATASOURCE_PASSWORD  
valueFrom:
secretKeyRef:
name: db-secret
key: password
- name: SPRING_DATASOURCE_URL
value: jdbc:postgresql://db-host:5432/myapp

Your Spring Boot application can also use the standard Kubernetes volume mount approach:

        volumeMounts:
- name: secrets
mountPath: "/etc/secrets"
readOnly: true
volumes:
- name: secrets
secret:
secretName: db-secret  # Created by ESO!

And in your application.properties:

spring.datasource.username=file:/etc/secrets/username
spring.datasource.password=file:/etc/secrets/password

Advanced Pattern: Template for Complex Java Apps

For more complex applications, ESO can create structured configuration:

# external-secret-with-template.yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: app-config
spec:
# ... secretStoreRef etc ...
target:
name: app-config-secret
data:
- secretKey: api-key
remoteRef:
key: prod/app/external-api
property: key
- secretKey: jwt-secret
remoteRef: 
key: prod/app/auth
property: jwt-secret

Benefits for Java Development Teams

  1. Security: Secrets never touch your Git repository or developer machines
  2. Centralized Management: All secrets are managed in one secure system with proper access controls and audit trails
  3. Automatic Rotation: When a secret is rotated in the external manager, ESO can automatically update the Kubernetes Secret (depending on refresh interval)
  4. Multi-environment Support: Use different SecretStore definitions for dev, staging, and prod that point to different secret paths
  5. Developer Experience: Developers can focus on application code rather than secret management logistics

Integration with Java Application Patterns

With Spring Cloud Kubernetes:

@Configuration
@EnableConfigurationProperties
public class AppConfig {
@Value("${spring.datasource.username}")
private String dbUser;
// Secrets are automatically available as properties
// when mounted as volumes or environment variables
}

In your CI/CD Pipeline:
The pipeline no longer needs secret injection steps—just apply the ExternalSecret manifests, and ESO handles the rest.

Conclusion: Elevating Your Java App's Security Posture

The External Secrets Operator brings enterprise-grade secret management to Kubernetes-native Java applications without complicating your code. By decoupling secret storage from secret consumption, it enables Java developers to:

  • Write applications that are agnostic to the underlying secret infrastructure
  • Eliminate hardcoded credentials and manual secret handling
  • Leverage professional secret managers with minimal complexity
  • Maintain a clean GitOps workflow where secrets are declaratively requested rather than manually managed

For Java teams running in Kubernetes, ESO isn't just a convenience—it's a critical component of a mature, secure supply chain that protects your applications while simplifying developer workflows.

Java Logistics, Shipping Integration & Enterprise Inventory Automation (Tracking, ERP, RFID & Billing Systems)

https://macronepal.com/blog/aftership-tracking-in-java-enterprise-package-visibility/
Explains how to integrate AfterShip tracking services into Java applications to provide real-time shipment visibility, delivery status updates, and centralized tracking across multiple courier services.

https://macronepal.com/blog/shipping-integration-using-fedex-api-with-java-for-logistics-automation/
Explains how to integrate the FedEx API into Java systems to automate shipping tasks such as creating shipments, calculating delivery costs, generating shipping labels, and tracking packages.

https://macronepal.com/blog/shipping-and-logistics-integrating-ups-apis-with-java-applications/
Explains UPS API integration in Java to enable automated shipping operations including rate calculation, shipment scheduling, tracking, and delivery confirmation management.

https://macronepal.com/blog/generating-and-reading-qr-codes-for-products-in-java/
Explains how Java applications generate and read QR codes for product identification, tracking, and authentication, supporting faster inventory handling and product verification processes.

https://macronepal.com/blog/designing-a-robust-pick-and-pack-workflow-in-java/
Explains how to design an efficient pick-and-pack workflow in Java warehouse systems, covering order processing, item selection, packaging steps, and logistics preparation to improve fulfillment efficiency.

https://macronepal.com/blog/rfid-inventory-management-system-in-java-a-complete-guide/
Explains how RFID technology integrates with Java applications to automate inventory tracking, reduce manual errors, and enable real-time stock monitoring in warehouses and retail environments.

https://macronepal.com/blog/erp-integration-with-odoo-in-java/
Explains how Java applications connect with Odoo ERP systems to synchronize inventory, orders, customer records, and financial data across enterprise systems.

https://macronepal.com/blog/automated-invoice-generation-creating-professional-excel-invoices-with-apache-poi-in-java/
Explains how to automatically generate professional Excel invoices in Java using Apache POI, enabling structured billing documents and automated financial record creation.

https://macronepal.com/blog/enterprise-financial-integration-using-quickbooks-api-in-java-applications/
Explains QuickBooks API integration in Java to automate financial workflows such as invoice management, payment tracking, accounting synchronization, and financial reporting.


Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper