OpenShift Secrets for Spring Boot
Learn how to securely manage passwords, API keys, certificates, and sensitive configuration in OpenShift using Secrets. Integrate Secrets with Spring Boot applications using environment variables and mounted files.
Introduction
Every enterprise application contains sensitive information that should never be stored in source code.
Examples include:
- Database passwords
- API Keys
- JWT Secrets
- OAuth Client Secrets
- AWS Access Keys
- SSL Certificates
- Kafka Credentials
Unfortunately, many beginners hardcode these values directly in their Spring Boot applications.
spring.datasource.password=MyPassword123
This is a major security risk.
OpenShift solves this problem using Secrets, allowing applications to securely consume sensitive information without embedding it in source code or container images.
Learning Objectives
By the end of this article, you will understand:
- What are OpenShift Secrets?
- Why Secrets are important
- Secret architecture
- Secret types
- Environment variable injection
- Mounting Secrets as files
- Spring Boot integration
- TLS certificates
- Secret rotation
- Enterprise security best practices
Why Do We Need Secrets?
Consider the following Spring Boot configuration:
spring.datasource.username=admin
spring.datasource.password=Admin@123
Problems:
- Password exposed in Git
- Visible in Docker image
- Difficult to rotate
- Security compliance violations
Secure Configuration
Instead of storing credentials inside the application:
flowchart LR
Secret[OpenShift Secret]
--> Deployment
--> Pod
--> SpringBoot[Spring Boot Application]
The application reads credentials securely at runtime.
What is an OpenShift Secret?
A Secret is a Kubernetes/OpenShift resource used to securely store sensitive information.
Secrets can store:
- Passwords
- Tokens
- API Keys
- Certificates
- SSH Keys
- OAuth Credentials
- Database Credentials
Unlike ConfigMaps, Secrets are intended only for confidential data.
ConfigMap vs Secret
| ConfigMap | Secret |
|---|---|
| Public configuration | Sensitive information |
| Database URL | Database Password |
| Kafka Host | Kafka Password |
| Logging Level | JWT Secret |
| Feature Flags | API Keys |
| Application Name | TLS Certificates |
Rule
- Configuration → ConfigMap
- Sensitive Data → Secret
Secret Architecture
flowchart TD
Secret
--> Deployment
Deployment
--> Pod1[Spring Boot Pod 1]
Deployment
--> Pod2[Spring Boot Pod 2]
Pod1 --> Application1[Spring Boot]
Pod2 --> Application2[Spring Boot]
Multiple Pods can consume the same Secret.
Secret Types
OpenShift supports multiple Secret types.
| Type | Purpose |
|---|---|
| Opaque | Generic Secrets |
| kubernetes.io/tls | TLS Certificates |
| kubernetes.io/dockerconfigjson | Image Pull Credentials |
| kubernetes.io/basic-auth | Username & Password |
| kubernetes.io/service-account-token | Service Account Token |
Most Spring Boot applications use Opaque Secrets.
Create Secret Using CLI
oc create secret generic payment-secret \
--from-literal=DB_USERNAME=paymentuser \
--from-literal=DB_PASSWORD=StrongPassword@123
Verify Secrets
oc get secrets
Example:
NAME
payment-secret
Describe Secret:
oc describe secret payment-secret
Secret YAML
apiVersion: v1
kind: Secret
metadata:
name: payment-secret
type: Opaque
stringData:
DB_USERNAME: paymentuser
DB_PASSWORD: StrongPassword@123
Apply:
oc apply -f secret.yaml
Secret as Environment Variables
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: payment-secret
key: DB_USERNAME
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: payment-secret
key: DB_PASSWORD
Secret Injection Flow
flowchart LR
Secret
--> EnvironmentVariables[Environment Variables]
--> SpringBoot[Spring Boot Application]
Spring Boot Configuration
spring.datasource.username=${DB_USERNAME}
spring.datasource.password=${DB_PASSWORD}
Spring Boot automatically reads the environment variables.
Using @Value
@Value("${DB_USERNAME}")
private String username;
@Value("${DB_PASSWORD}")
private String password;
Using ConfigurationProperties
@ConfigurationProperties(prefix="database")
public class DatabaseProperties {
private String username;
private String password;
}
Recommended for enterprise applications.
Mount Secret as Files
Some applications require certificates or private keys as files.
flowchart TD
Secret
--> MountedFile
--> SpringBoot
Mount Secret Example
volumeMounts:
- name: secret-volume
mountPath: /etc/secrets
volumes:
- name: secret-volume
secret:
secretName: payment-secret
The Secret becomes available as files inside the container.
Verify Mounted Secret
Open the Pod.
oc rsh payment-api-xxxxx
List files.
ls /etc/secrets
Output:
DB_USERNAME
DB_PASSWORD
TLS Certificates
TLS certificates are commonly stored as Secrets.
flowchart LR
TLSCertificate
--> Secret
--> OpenShiftRoute
Create TLS Secret:
oc create secret tls payment-cert \
--cert=tls.crt \
--key=tls.key
Using TLS Secret
tls:
termination: edge
certificate: ...
key: ...
The Route uses the Secret to provide HTTPS.
Docker Registry Secret
Private container registries require authentication.
flowchart LR
DockerRegistry
--> ImagePullSecret
--> OpenShift
Create:
oc create secret docker-registry registry-secret \
--docker-server=quay.io \
--docker-username=myuser \
--docker-password=mypassword
Enterprise Banking Example
flowchart TD
Secret
--> PaymentService
Secret
--> FraudService
Secret
--> NotificationService
PaymentService --> OracleDB[(Oracle Database)]
FraudService --> Kafka[(Kafka)]
Each microservice accesses only the Secrets it requires.
Secret Rotation
Passwords should be rotated periodically.
flowchart LR
OldSecret
--> NewSecret
--> RestartPods
--> SpringBoot
Benefits:
- Reduced security risk
- Compliance
- Better operational security
Updating Secrets
Edit Secret:
oc edit secret payment-secret
Or apply a new YAML.
oc apply -f secret.yaml
Restart Deployment:
oc rollout restart deployment/payment-api
Verify Secret Values
Display Secret:
oc get secret payment-secret -o yaml
Decode Base64:
echo "cGFzc3dvcmQ=" | base64 --decode
Note: Kubernetes stores Secret data encoded with Base64, which is encoding—not encryption. Protect Secrets using RBAC, encryption at rest, and secure access controls.
Enterprise Architecture
flowchart TD
SECRET["Secret"]
API["API Gateway"]
PAYMENT["Payment Service"]
CUSTOMER["Customer Service"]
NOTIFY["Notification Service"]
POSTGRES[("PostgreSQL")]
KAFKA[("Kafka")]
REDIS[("Redis")]
SECRET --> API
SECRET --> PAYMENT
SECRET --> CUSTOMER
SECRET --> NOTIFY
PAYMENT --> POSTGRES
NOTIFY --> KAFKA
CUSTOMER --> REDIS
Common Problems
Secret Not Found
oc get secrets
Verify the Secret exists.
Environment Variable Missing
Check Pod environment.
oc rsh payment-api-xxxxx
env
Wrong Secret Name
Ensure:
secretKeyRef:
name: payment-secret
matches the actual Secret name.
Pod Cannot Start
Possible causes:
- Secret missing
- Wrong key name
- Incorrect mount path
Best Practices
- Never hardcode passwords.
- Use one Secret per application.
- Rotate passwords regularly.
- Store TLS certificates as Secrets.
- Use RBAC to restrict Secret access.
- Keep Secrets out of Git repositories.
- Integrate with enterprise secret managers such as HashiCorp Vault or external secret operators.
- Audit Secret usage regularly.
Common Mistakes
❌ Storing passwords in ConfigMaps.
❌ Committing Secret YAML with real passwords to Git.
❌ Sharing one Secret across unrelated applications.
❌ Forgetting to rotate credentials.
❌ Giving every application access to every Secret.
❌ Assuming Base64 encoding is encryption.
Advantages
- Secure credential management
- Centralized secrets
- Better compliance
- Easy password rotation
- Cloud-native security
- Spring Boot integration
- TLS certificate management
- Enterprise ready
Summary
OpenShift Secrets provide a secure mechanism for storing and managing sensitive application data.
Key takeaways:
- Secrets are designed for confidential information.
- Spring Boot can consume Secrets as environment variables or mounted files.
- Secrets should never be stored in source code or container images.
- TLS certificates, API keys, and database credentials belong in Secrets.
- Proper Secret management is essential for production-grade cloud-native applications.
Interview Questions
- What is an OpenShift Secret?
- What is the difference between a Secret and a ConfigMap?
- Why shouldn't passwords be hardcoded?
- How do Spring Boot applications consume Secrets?
- Can Secrets be mounted as files?
- What are the different Secret types?
- Where should TLS certificates be stored?
- Why is Base64 encoding not the same as encryption?
- What is Secret rotation?
- What are the best practices for managing Secrets in OpenShift?