Secure secret management in Next.js and Node.js with AWS Secrets Manager and Docker Secrets

Step by step we will show how to protect API keys and other sensitive data in Next.js and Node.js applications using AWS Secrets Manager and Docker Secrets.

Bezpieczne zarządzanie sekretami w Next.js i Node.js z AWS Secrets Manager i Docker Secrets

Data security in web applications is not just about choosing strong passwords. For engineering teams, proper management of secret keys—ranging from API keys and JWT tokens to database credentials—is crucial. In this article we present a threat model, describe how AWS Secrets Manager and Docker Secrets work, and demonstrate practical integration with the Next.js framework and the Node.js environment. All based on OWASP A3 – Sensitive Data Exposure guidelines and the principle of least‑privilege.

Threat model – where do secrets most often leak?

In a typical Next.js/Node.js stack, secrets can leak at several levels: in source code (e.g., in a Git repository), in environment variables set on the server, in Docker images, and also in application logs. An attacker who gains access to any of these elements can take control of external services, tamper with data, or perform unauthorized operations. The threat model assumes three main vectors:

  • Improper storage of secrets in the repository (e.g., in .env files).
  • Exposure of environment variables in Docker containers that are not encrypted.
  • Lack of access control to secret‑management services (e.g., misconfigured IAM policies in AWS).

How does AWS Secrets Manager work?

AWS Secrets Manager is a managed service for storing and rotating secrets. Secrets are encrypted using KMS, and access is controlled via IAM policies. Key components:

  • Encrypt‑at‑rest – each secret is encrypted while stored.
  • Secure transmission – access occurs over HTTPS with AWS Signature V4 signing.
  • Automatic rotation – optional rotation every 30‑90 days, reducing the vulnerability window.

In the context of Next.js, we typically retrieve secrets during server startup (e.g., in next start) or within API functions, so they are never stored in code.

Docker Secrets in Node.js applications

Docker Swarm enables secure delivery of secrets to containers as virtual files under /run/secrets. Secrets are encrypted at rest and decrypted in the container’s memory, minimizing the risk of leakage through the image layer. In Kubernetes environments, similar functionality is provided by Secret and sealed‑secrets, but this article focuses on Docker Swarm because it integrates naturally with the image‑building process in CI/CD.

Integrating AWS Secrets Manager with Next.js

Below is a minimal example of fetching a secret from AWS Secrets Manager in a Next.js application written in TypeScript. We assume the IAM role attached to the EC2 instance or ECS task has secretsmanager:GetSecretValue permission for the selected secret.

import { SecretsManagerClient, GetSecretValueCommand } from "@aws-sdk/client-secrets-manager";

const client = new SecretsManagerClient({ region: "eu-west-1" });

export async function getDatabaseCredentials() {
  const command = new GetSecretValueCommand({
    SecretId: "prod/dbCredentials"
  });
  const response = await client.send(command);
  if (!response.SecretString) {
    throw new Error("Secret is binary or empty");
  }
  return JSON.parse(response.SecretString);
}

// Example usage in an API route
export default async function handler(req, res) {
  const creds = await getDatabaseCredentials();
  // use creds.username and creds.password to connect to the DB
  res.status(200).json({ status: "ok" });
}

The key is to ensure the call does not happen during static site building (next build), because the secret could then be written into the build artifact. Therefore we fetch it only at runtime on the server side.

Docker Secrets in practice – Node.js as a backend API

In Node.js applications running in Docker containers, secrets can be mounted as files and read synchronously at application startup. Example Docker‑Compose defining a secret:

version: "3.8"
services:
  api:
    image: myorg/api:latest
    secrets:
      - api_key
    environment:
      - NODE_ENV=production
    command: ["node", "dist/index.js"]
secrets:
  api_key:
    external: true

In Node.js code we read the secret:

import fs from "fs";

const apiKey = fs.readFileSync("/run/secrets/api_key", "utf8").trim();
// use apiKey for external API calls

It is worth emphasizing that secrets do not appear in environment variables, which reduces the risk of leakage through process logs.

"The best protection for secrets is not placing them in code – but keeping them in services that control access and audit usage."

Mitigation checklist – what the team must do?

  • Create least‑privilege IAM policies for access to specific secrets.
  • Enable automatic rotation in AWS Secrets Manager (e.g., every 60 days).
  • Use Docker Secrets instead of environment variables in .env files.
  • Ensure CI/CD does not log secret values (masking).
  • Audit secret access – CloudTrail for AWS, Docker events for Swarm.

Typical mistakes and trade‑offs

1. Hard‑coding secrets – the most common error, easily caught by code scanners. Instead, use runtime secret‑fetching functions.

2. Storing secrets in public repositories – even encrypted values can reveal application structure. Apply git‑ignore for .env files and secrets/ directories.

3. Granting broad IAM permissions – assigning AdministratorAccess to an application undermines the least‑privilege principle. Define precise policies.

4. Lack of rotation – secrets used for a long time increase the risk of leakage. Automate rotation and code updates.

5. Logging secret values – some libraries debug the entire configuration. Disable debug mode in production and mask sensitive fields.

Summary and next steps

Implementing secure secret management in a Next.js and Node.js stack requires combining two proven solutions: AWS Secrets Manager for centralized, auditable storage and Docker Secrets for container isolation. By following the checklist, we avoid common pitfalls and meet OWASP A3 requirements as well as least‑privilege principles. If you need assistance with deploying this architecture, optimizing CI/CD, or conducting a security audit, contact Coderia.it – we’ll help you adopt best practices and give peace of mind to your engineering team.

Let’s start

Got a project in mind?

Describe it in a few sentences. I reply within 24 hours with a free quote and a proposed stack.