Skip to main content

Overview

Security is paramount in a Spring Cloud Config repository. This guide covers best practices for managing sensitive data, authentication, and access control.
Never commit real secrets, passwords, or credentials to Git. Always use environment variables or external secret managers.

Secret Management

Environment Variable Placeholders

All sensitive configuration values must use Spring’s ${VAR_NAME} placeholder syntax, which resolves from environment variables at runtime:
spring:
  datasource:
    url: jdbc:postgresql://${DEV_AUTH_DB_HOST:host.docker.internal}:${DEV_AUTH_DB_PORT:5432}/${DEV_AUTH_DB_NAME}
    username: ${DEV_AUTH_DB_USERNAME}
    password: ${DEV_AUTH_DB_PASSWORD}
You can provide default values using the colon syntax: ${VAR_NAME:default_value}. This is useful for non-sensitive values like hostnames or ports.

Critical Secrets to Protect

The following secrets must never be committed in plain text:

Database Credentials

  • DEV_AUTH_DB_USERNAME
  • DEV_AUTH_DB_PASSWORD
  • DEV_USER_DB_PASSWORD

OAuth2 & JWT

  • SGIVU_GATEWAY_SECRET
  • JWT_KEYSTORE_PASSWORD
  • JWT_KEY_PASSWORD

Service Authentication

  • SERVICE_INTERNAL_SECRET_KEY
  • REDIS_PASSWORD

Cloud Provider Keys

  • AWS_ACCESS_KEY
  • AWS_SECRET_KEY

OAuth2 Client Security

Gateway OAuth2 Configuration

The API Gateway uses OAuth2 authorization code flow to authenticate users. The client secret must be stored securely:
spring:
  security:
    oauth2:
      client:
        registration:
          sgivu-gateway:
            provider: sgivu-auth
            client-id: sgivu-gateway
            client-secret: ${SGIVU_GATEWAY_SECRET}
            client-authentication-method: client_secret_basic
            authorization-grant-type: authorization_code
1

Generate a Strong Secret

Use a cryptographically secure random generator to create the client secret:
openssl rand -base64 32
2

Store in Environment

Add the secret to your .env file (never committed to Git):
SGIVU_GATEWAY_SECRET=your_generated_secret_here
3

Reference in Config

Use the environment variable placeholder in your YAML files:
gateway-client:
  url: ${SGIVU_GATEWAY_URL:http://sgivu-gateway:8080}
  secret: ${SGIVU_GATEWAY_SECRET}

JWT Keystore Management

The sgivu-auth service uses a Java KeyStore for JWT signing. All keystore credentials must be externalized:
sgivu:
  jwt:
    keystore:
      location: ${JWT_KEYSTORE_LOCATION}
      password: ${JWT_KEYSTORE_PASSWORD}
    key:
      alias: ${JWT_KEY_ALIAS}
      password: ${JWT_KEY_PASSWORD}

Keystore Setup

1

Generate the Keystore

Create a new Java KeyStore with RSA key pair:
keytool -genkeypair -alias sgivu-jwt \
  -keyalg RSA -keysize 2048 \
  -keystore sgivu-jwt.jks \
  -validity 3650
2

Store Securely

Place the keystore file in a secure location outside the repository:
  • Development: /etc/sgivu/secrets/sgivu-jwt.jks
  • Docker: Mount as a volume
  • Production: Use secret management service (AWS Secrets Manager, HashiCorp Vault)
3

Configure Environment Variables

Set the keystore location and passwords:
JWT_KEYSTORE_LOCATION=file:/etc/sgivu/secrets/sgivu-jwt.jks
JWT_KEYSTORE_PASSWORD=your_keystore_password
JWT_KEY_ALIAS=sgivu-jwt
JWT_KEY_PASSWORD=your_key_password

Service-to-Service Authentication

Microservices use a shared secret key for internal API calls:
service:
  internal:
    secret-key: "${SERVICE_INTERNAL_SECRET_KEY}"
This key should be:
  • At least 32 characters long
  • Randomly generated using a cryptographic generator
  • Shared across all microservices via environment variables
  • Rotated periodically (at least every 90 days)
All services (user, client, vehicle, purchase-sale) must use the same SERVICE_INTERNAL_SECRET_KEY to authenticate with each other.

Redis Session Security

The API Gateway stores sessions in Redis. Protect Redis with authentication:
spring:
  data:
    redis:
      host: ${REDIS_HOST:sgivu-redis}
      port: ${REDIS_PORT:6379}
      password: ${REDIS_PASSWORD}
Redis passwords should be set in your Redis configuration and passed via environment variables. Never use Redis without authentication in production.

AWS Credentials

Services that integrate with AWS (like sgivu-vehicle for S3 storage) require AWS credentials:
aws:
  s3:
    vehicles-bucket: ${AWS_VEHICLES_BUCKET}
  access:
    key: ${AWS_ACCESS_KEY}
  secret:
    key: ${AWS_SECRET_KEY}
  region: ${AWS_REGION}

Best Practices for AWS

Use IAM Roles

In production, prefer IAM roles over access keys. Assign roles to EC2 instances or ECS tasks.

Principle of Least Privilege

Grant only the minimum permissions required (e.g., S3 read/write to specific bucket).

Rotate Keys Regularly

If using access keys, rotate them every 30-90 days and invalidate old keys.

Never Commit Keys

Double-check that .env files containing AWS keys are in .gitignore.

Repository Access Control

Git Repository Permissions

1

Keep Repository Private

The config repository must be private. Never make it public.
2

Restrict Write Access

Only authorized team members should have write access. Use branch protection rules.
3

Enable Audit Logging

Track all changes through Git history and require meaningful commit messages.
4

Use Pull Requests

Require code review for all configuration changes, especially in production profiles.

Config Server Authentication

The Spring Cloud Config Server should authenticate clients before serving configuration:
# In Config Server application.yml
spring:
  security:
    user:
      name: ${CONFIG_SERVER_USERNAME}
      password: ${CONFIG_SERVER_PASSWORD}
Microservices must then provide these credentials when fetching config:
# In microservice bootstrap.yml
spring:
  cloud:
    config:
      username: ${CONFIG_SERVER_USERNAME}
      password: ${CONFIG_SERVER_PASSWORD}

Encryption at Rest and in Transit

In Transit (TLS)

In production, always use HTTPS/TLS for:
  • Config Server endpoints
  • Eureka Discovery Server
  • All microservice communication
  • OAuth2 authorization endpoints
Configure TLS in production profiles:
server:
  ssl:
    enabled: true
    key-store: ${SSL_KEYSTORE_PATH}
    key-store-password: ${SSL_KEYSTORE_PASSWORD}
    key-store-type: PKCS12

At Rest (Spring Cloud Config Encryption)

Spring Cloud Config supports encrypting sensitive values in Git:
# Encrypted value format
spring:
  datasource:
    password: '{cipher}AQA3FlZHr8/ykQZPyKvQKzU8...'
To enable:
1

Configure Encryption Key

Set the encryption key in Config Server:
ENCRYPT_KEY=my-secret-encryption-key
2

Encrypt Values

Use the Config Server encrypt endpoint:
curl http://localhost:8888/encrypt -d mysecretvalue
3

Use Encrypted Values

Prefix encrypted values with {cipher} in YAML files.
While encryption at rest adds a layer of security, it’s still recommended to use environment variables for the most sensitive secrets.

Security Checklist

Before committing configuration changes:
  • All passwords use ${VAR_NAME} placeholders
  • No API keys or tokens in plain text
  • .env files are in .gitignore
  • OAuth2 client secrets are externalized
  • JWT keystore credentials are not committed
  • Service internal secret key is not exposed
  • AWS credentials use IAM roles or are externalized
  • Redis password is externalized
  • Database credentials are externalized
  • Production config has been reviewed by security team

Configuration Refresh

Learn how to refresh secrets without restarting services

Validation

Validate configuration before deploying

Monitoring

Monitor security-related metrics and health

Environment Profiles

Understand how profiles separate environments

Build docs developers (and LLMs) love