AWS Secrets Manager Integration Plan (NodeJS Docker Deployments)

AWS Secrets Manager Integration Plan (NodeJS Docker Deployments)

Why Secret Management?

The Problem with Hardcoded Secrets

Storing sensitive credentials directly in config.json or environment files poses significant security risks:

  • Accidental exposure - Secrets committed to version control can be leaked publicly
  • No audit trail - No visibility into who accessed secrets or when
  • Difficult rotations - Changing credentials requires redeployment across all environments
  • Compliance violations - Fails security audits and regulatory requirements

Compliance Standards Requiring Secret Management

Standard Requirement
SOC 2 Logical access controls, encryption of sensitive data at rest and in transit
ISO 27001 A.9.4.3 - Password management systems must protect credentials
PCI DSS Requirement 3 - Protect stored cardholder data; Requirement 8 - Strong access controls
GDPR Article 32 - Implement appropriate technical measures to ensure security
HIPAA ยง164.312 - Technical safeguards for access control and encryption

Benefits of Secrets Manager

  • Centralized management - Single source of truth for all secrets
  • Automatic rotation - Schedule credential rotation without downtime
  • Audit logging - CloudTrail tracks all secret access
  • Encryption at rest - All secrets encrypted with KMS

Overview

Inject secrets from AWS Secrets Manager into Docker containers at runtime without modifying Node.js application code.

Configuration Details

Parameter Value
Secret Name your-secret-name
AWS Region your-region
Access Key <your-access-key-id>
Secret Key <your-secret-access-key>

Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    Docker Container Start                    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ”‚
                              โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚              docker-entrypoint.sh executes                   โ”‚
โ”‚  1. Reads AWS credentials from environment                   โ”‚
โ”‚  2. Calls AWS Secrets Manager API                            โ”‚
โ”‚  3. Parses JSON response with jq                             โ”‚
โ”‚  4. Exports each key-value as environment variable           โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ”‚
                              โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚              Node.js Application Starts                      โ”‚
โ”‚         ($ENV contains all secrets)                   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Files to be created

1. docker-entrypoint.sh

Location: Project root (same level as package.json)

Purpose: Fetch secrets from AWS Secrets Manager and export as environment variables before starting the application.

#!/bin/bash
set -e

# Fetch secrets from AWS Secrets Manager
SECRET_JSON=$(aws secretsmanager get-secret-value \
  --secret-id "$AWS_SECRET_NAME" \
  --region "$AWS_REGION" \
  --query 'SecretString' \
  --output text)

# Export each key-value pair as environment variables
for key in $(echo "$SECRET_JSON" | jq -r 'keys[]'); do
  value=$(echo "$SECRET_JSON" | jq -r --arg k "$key" '.[$k]')
  export "$key"="$value"
done

exec "$@"

2. Dockerfile (to be Modified)

Location: web/Dockerfile

# Copy entrypoint script from project root
COPY docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x /docker-entrypoint.sh

# Install AWS CLI and jq for secrets injection
RUN apt-get update && apt-get install -y --no-install-recommends \
    awscli \
    jq \
    && rm -rf /var/lib/apt/lists/*

ENTRYPOINT ["/docker-entrypoint.sh"]

Changes:

  • Added awscli and jq package installation
  • Added entrypoint script copy and chmod
  • Changed from CMD only to ENTRYPOINT + CMD pattern

3. docker-compose.yml (Modified)

Location: docker-compose.yml

Changes: Added environment variables to web service:

environment:
  AWS_ACCESS_KEY_ID: '<your-access-key-id>'
  AWS_SECRET_ACCESS_KEY: '<your-secret-access-key>'
  AWS_REGION: 'your-region'
  AWS_SECRET_NAME: 'your-secret-name'

Deployment Steps on Servers

# Start all services
docker-compose up -f ./.wappler/targets/Development/docker-compose.yml  -d --build

# Verify secrets are loaded (check logs)
docker-compose logs web | grep "Exported:"

# Verify environment variables inside container
docker-compose exec web env | grep -v AWS

Database Connection Integration

Wappler's framework natively supports environment variable substitution using the {{$_ENV.VARIABLE}} syntax. This allows database credentials to be injected from AWS Secrets Manager.

Updated db.json Configuration

Location: app/modules/connections/db.json

The database connection file has been updated to use environment variables:

{
  "name": "db",
  "module": "dbconnector",
  "action": "connect",
  "options": {
    "client": "postgres",
    "connection": {
      "host": "db",
      "port": 5432,
      "user": "db_user",
      "password": "{{$_ENV.DB_PASSWORD}}",
      "database": "it_mng_app"
    },
    "meta": {}
  }
}

Verification Checklist

  • "Secrets loaded successfully" appears in logs
  • All secret keys are exported (check "Exported: " logs)
  • Node.js app can access secrets via process.env same as it was able to access via config.json file aswell using $ENV.VARIABLE

Example Secret Structure in AWS

Your secret should contain JSON key-value pairs like:

{
  "DB_PASSWORD": "your-db-password",
  "API_KEY": "your-api-key",
  "JWT_SECRET": "your-jwt-secret"
}

Each key becomes an environment variable accessible via $ENV.DB_PASSWORD, etc.

5 Likes