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

  1. What is an OpenShift Secret?
  2. What is the difference between a Secret and a ConfigMap?
  3. Why shouldn't passwords be hardcoded?
  4. How do Spring Boot applications consume Secrets?
  5. Can Secrets be mounted as files?
  6. What are the different Secret types?
  7. Where should TLS certificates be stored?
  8. Why is Base64 encoding not the same as encryption?
  9. What is Secret rotation?
  10. What are the best practices for managing Secrets in OpenShift?