🔐 Samenvatting
N8N biedt krachtige mogelijkheden voor het beheren van variables, environment configuration en secrets. Deze gids laat zien hoe je workflow variables gebruikt, environment files configureert, externe secrets integreert met HashiCorp Vault of AWS Secrets Manager, en best practices implementeert voor secure credential management. Perfect voor teams die werken met dev/staging/production environments.
Inhoudsopgave
- Waarom Variables & Secrets Management?
- Types Variables in N8N
- Environment Variables Setup
- Workflow Variables (Enterprise)
- .env Files & Configuration
- External Secrets Integration
- HashiCorp Vault Setup
- AWS Secrets Manager
- Multi-Environment Setup
- Security Best Practices
Waarom Variables & Secrets Management?
Hardcoded credentials en configuration in workflows zijn een security nightmare. Variables en secrets management lossen deze problemen op:
❌ Zonder Proper Management
- • API keys zichtbaar in workflows
- • Passwords in version control
- • Manual changes per environment
- • Geen audit trail
- • Security breaches risico
- • Compliance issues
✅ Met Variables & Secrets
- • Credentials encrypted opgeslagen
- • Environment-specific configs
- • Automatic rotation mogelijk
- • Complete audit logging
- • Zero-trust security
- • GDPR/SOC2 compliant
🎯 Use Cases voor Variables
- • API Endpoints: Verschillende URLs voor dev/staging/prod
- • Feature Flags: Enable/disable functionaliteit per environment
- • Rate Limits: Verschillende limits per omgeving
- • Email Recipients: Test emails naar dev team, prod naar klanten
- • Database Connections: Separate databases per environment
- • Third-party Keys: Sandbox vs production API keys
Types Variables in N8N
N8N kent verschillende soorten variables, elk met hun eigen scope en use case:
| Variable Type | Scope | Access Method | Use Case |
|---|---|---|---|
| System Environment | OS Level | $env | System paths, user info |
| N8N Environment | Application | .env file | Database, webhooks, config |
| Workflow Variables | All workflows | $vars (Enterprise) | Shared constants, API URLs |
| Credentials | Node specific | Credentials UI | API keys, passwords |
| Node Variables | Single node | $json, $input | Runtime data |
Environment Variables Setup
Environment variables zijn de foundation voor N8N configuratie. Ze bepalen alles van database connections tot security settings:
📄 Complete .env Example
# ====================
# CORE CONFIGURATION
# ====================
# Basic Settings
N8N_HOST=localhost
N8N_PORT=5678
N8N_PROTOCOL=https
GENERIC_TIMEZONE=Europe/Amsterdam
# ====================
# DATABASE
# ====================
# PostgreSQL Configuration
DB_TYPE=postgresdb
DB_POSTGRESDB_HOST=postgres.example.com
DB_POSTGRESDB_PORT=5432
DB_POSTGRESDB_DATABASE=n8n_production
DB_POSTGRESDB_USER=n8n_user
DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD} # Reference to secret
DB_POSTGRESDB_SSL=true
DB_POSTGRESDB_SSL_CA=/path/to/ca.pem
# ====================
# SECURITY
# ====================
# Encryption
N8N_ENCRYPTION_KEY=${ENCRYPTION_KEY} # 32-byte hex string
# User Management
N8N_USER_MANAGEMENT_DISABLED=false
N8N_USER_MANAGEMENT_EMAIL_VERIFICATION=true
N8N_USER_MANAGEMENT_JWT_SECRET=${JWT_SECRET}
# Security Headers
N8N_SECURITY_AUDIT_ENABLED=true
N8N_SECURITY_BLOCK_FILE_ACCESS=true
# ====================
# EXECUTION
# ====================
# Process Configuration
EXECUTIONS_PROCESS=main
EXECUTIONS_TIMEOUT=3600
EXECUTIONS_TIMEOUT_MAX=7200
# Data Management
EXECUTIONS_DATA_SAVE_ON_ERROR=all
EXECUTIONS_DATA_SAVE_ON_SUCCESS=none
EXECUTIONS_DATA_SAVE_ON_PROGRESS=false
EXECUTIONS_DATA_MAX_AGE=336 # 14 days
EXECUTIONS_DATA_PRUNE=true
# ====================
# WEBHOOKS
# ====================
WEBHOOK_URL=https://n8n.example.com/
N8N_WEBHOOK_TUNNEL_URL=https://n8n.example.com/
# ====================
# EXTERNAL STORAGE
# ====================
# S3 for Binary Data
N8N_DEFAULT_BINARY_DATA_MODE=s3
N8N_BINARY_DATA_S3_BUCKET=n8n-binary-data
N8N_BINARY_DATA_S3_REGION=eu-west-1
AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY}
AWS_SECRET_ACCESS_KEY=${AWS_SECRET_KEY}
# ====================
# EXTERNAL SECRETS
# ====================
# HashiCorp Vault
N8N_EXTERNAL_SECRETS_ENABLED=true
N8N_EXTERNAL_SECRETS_PROVIDER=vault
VAULT_ADDR=https://vault.example.com:8200
VAULT_TOKEN=${VAULT_TOKEN}
VAULT_NAMESPACE=n8n
# AWS Secrets Manager (Alternative)
# N8N_EXTERNAL_SECRETS_PROVIDER=aws
# AWS_REGION=eu-west-1
# AWS_SECRETS_PREFIX=n8n/
# ====================
# MONITORING
# ====================
# Metrics
N8N_METRICS=true
N8N_METRICS_PREFIX=n8n_
N8N_METRICS_INCLUDE_DEFAULT=true
N8N_METRICS_INCLUDE_API_ENDPOINTS=true
N8N_METRICS_INCLUDE_API_PATH_LABEL=true
# Logging
N8N_LOG_LEVEL=info
N8N_LOG_OUTPUT=console
N8N_LOG_FILE_LOCATION=/var/log/n8n/
# ====================
# ENTERPRISE FEATURES
# ====================
N8N_LICENSE_KEY=${N8N_LICENSE}
N8N_WORKFLOW_VARIABLES_ENABLED=true
N8N_SSO_ENABLED=true
N8N_LDAP_ENABLED=true
⚠️ Security Tips voor Environment Variables
- • Never commit .env files: Add to .gitignore immediately
- • Use references:
${SECRET_VAR}verwijst naar system env - • Rotate regularly: Change secrets elke 90 dagen
- • Minimum permissions: Restrictive file permissions (600)
- • Encrypt at rest: Use encrypted filesystems
Workflow Variables (Enterprise Feature)
Workflow variables ($vars) zijn een Enterprise feature die global variables mogelijk maakt across alle workflows:
🎯 Workflow Variables Setup
1. Enable in Configuration:
N8N_WORKFLOW_VARIABLES_ENABLED=true
2. Define Variables in UI:
Settings → Variables → Add Variable
{
"API_BASE_URL": "https://api.example.com",
"MAX_RETRY_COUNT": "3",
"DEFAULT_TIMEOUT": "30",
"ENVIRONMENT": "production",
"FEATURE_FLAGS": {
"enableNewFeature": true,
"debugMode": false
}
}
3. Use in Workflows:
// In Code node
const apiUrl = $vars.API_BASE_URL;
const maxRetries = parseInt($vars.MAX_RETRY_COUNT);
// In expressions
{{ $vars.ENVIRONMENT === 'production' ? 'prod-endpoint' : 'dev-endpoint' }}
// Access nested values
const debugEnabled = $vars.FEATURE_FLAGS.debugMode;
💡 Alternative voor Non-Enterprise: Static Data Node
Als je geen Enterprise hebt, kun je een workaround gebruiken met Static Data nodes:
// Create een "Config" workflow met Static Data node
{
"apiUrl": process.env.API_URL || "https://api.example.com",
"environment": process.env.NODE_ENV || "development",
"features": {
"newUI": process.env.FEATURE_NEW_UI === "true"
}
}
// Reference in andere workflows via Execute Workflow node
.env Files & Configuration Management
Professionele .env file management voor verschillende environments:
📁 Multi-Environment File Structure
n8n-deployment/
├── environments/
│ ├── .env.development
│ ├── .env.staging
│ ├── .env.production
│ └── .env.example # Template zonder secrets
├── secrets/
│ ├── vault-config.json
│ └── aws-secrets.json
├── docker-compose.yml
├── docker-compose.dev.yml
├── docker-compose.prod.yml
└── scripts/
├── load-env.sh
├── rotate-secrets.sh
└── validate-config.sh
🔧 Dynamic Environment Loading Script
#!/bin/bash
# load-env.sh - Load environment-specific configuration
ENVIRONMENT=${1:-development}
ENV_FILE="./environments/.env.${ENVIRONMENT}"
if [ ! -f "$ENV_FILE" ]; then
echo "Error: Environment file $ENV_FILE not found"
exit 1
fi
# Load base configuration
set -a
source ./environments/.env.base
# Override with environment-specific
source "$ENV_FILE"
# Load secrets from external source
if [ "$ENVIRONMENT" = "production" ]; then
# Fetch from HashiCorp Vault
export DB_PASSWORD=$(vault kv get -field=password secret/n8n/db)
export JWT_SECRET=$(vault kv get -field=jwt secret/n8n/auth)
export ENCRYPTION_KEY=$(vault kv get -field=key secret/n8n/encryption)
else
# Use local development secrets
source ./environments/.env.secrets.local
fi
set +a
echo "✅ Loaded configuration for: $ENVIRONMENT"
echo " N8N_HOST: $N8N_HOST"
echo " DB_TYPE: $DB_TYPE"
echo " ENVIRONMENT: $ENVIRONMENT"
# Start N8N with loaded config
exec n8n start
External Secrets Integration
N8N ondersteunt integratie met externe secret managers voor enterprise-grade security:
🔐 HashiCorp Vault
- • Industry standard
- • Dynamic secrets
- • Audit logging
- • Encryption as service
🔑 AWS Secrets Manager
- • Native AWS integration
- • Automatic rotation
- • Cross-region replication
- • IAM integration
🗝️ Azure Key Vault
- • Azure native
- • HSM support
- • Managed identities
- • Compliance certified
HashiCorp Vault Setup
Complete setup voor HashiCorp Vault integration met N8N:
🔐 Vault Configuration Steps
1. Install & Start Vault:
# Docker deployment
docker run -d \
--name vault \
--cap-add=IPC_LOCK \
-e VAULT_DEV_ROOT_TOKEN_ID=myroot \
-e VAULT_DEV_LISTEN_ADDRESS=0.0.0.0:8200 \
-p 8200:8200 \
hashicorp/vault:latest
# Initialize Vault (production)
vault operator init
vault operator unseal # Repeat 3x with different keys
2. Configure Secrets Engine:
# Enable KV secrets engine
vault secrets enable -path=n8n kv-v2
# Write N8N secrets
vault kv put n8n/database \
host="postgres.example.com" \
port="5432" \
username="n8n_user" \
password="super-secret-password"
vault kv put n8n/encryption \
key="$(openssl rand -hex 32)"
vault kv put n8n/jwt \
secret="$(openssl rand -base64 48)"
3. Create N8N Policy:
# n8n-policy.hcl
path "n8n/*" {
capabilities = ["read", "list"]
}
path "auth/token/renew-self" {
capabilities = ["update"]
}
# Apply policy
vault policy write n8n-policy n8n-policy.hcl
# Create token with policy
vault token create -policy=n8n-policy -ttl=720h
4. N8N Integration:
// Custom Vault integration in Code node
const vault = require('node-vault')({
endpoint: process.env.VAULT_ADDR,
token: process.env.VAULT_TOKEN
});
// Read secret
const dbSecret = await vault.read('n8n/data/database');
const dbPassword = dbSecret.data.data.password;
// Use in connection
const connection = {
host: dbSecret.data.data.host,
port: dbSecret.data.data.port,
user: dbSecret.data.data.username,
password: dbPassword
};
AWS Secrets Manager Integration
AWS Secrets Manager biedt native cloud integration met automatic rotation:
☁️ AWS Secrets Manager Setup
1. Create Secrets in AWS:
# Create database credentials
aws secretsmanager create-secret \
--name n8n/production/database \
--secret-string '{
"username": "n8n_user",
"password": "generated-password",
"host": "rds.amazonaws.com",
"port": 5432
}'
# Create API keys
aws secretsmanager create-secret \
--name n8n/production/api-keys \
--secret-string '{
"stripe": "sk_live_...",
"sendgrid": "SG...",
"openai": "sk-..."
}'
# Enable automatic rotation
aws secretsmanager rotate-secret \
--secret-id n8n/production/database \
--rotation-lambda-arn arn:aws:lambda:... \
--rotation-rules AutomaticallyAfterDays=30
2. IAM Role for N8N:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue",
"secretsmanager:DescribeSecret"
],
"Resource": "arn:aws:secretsmanager:*:*:secret:n8n/*"
}]
}
3. N8N Code Integration:
// AWS SDK integration in Code node
const AWS = require('aws-sdk');
const client = new AWS.SecretsManager({
region: 'eu-west-1'
});
async function getSecret(secretName) {
try {
const data = await client.getSecretValue({
SecretId: secretName
}).promise();
return JSON.parse(data.SecretString);
} catch (error) {
console.error('Failed to retrieve secret:', error);
throw error;
}
}
// Use in workflow
const dbCreds = await getSecret('n8n/production/database');
const apiKeys = await getSecret('n8n/production/api-keys');
// Connect to database
const pgConnection = {
host: dbCreds.host,
port: dbCreds.port,
user: dbCreds.username,
password: dbCreds.password
};
Multi-Environment Setup (Dev/Staging/Prod)
Professionele setup voor het beheren van meerdere environments:
🌍 Complete Multi-Environment Architecture
# docker-compose.override.yml pattern
# Base configuration (docker-compose.yml)
version: '3.8'
services:
n8n:
image: n8nio/n8n:latest
env_file:
- ./environments/.env.${ENVIRONMENT:-development}
volumes:
- n8n_data:/home/node/.n8n
networks:
- n8n_network
# Development override (docker-compose.dev.yml)
version: '3.8'
services:
n8n:
ports:
- "5678:5678"
environment:
N8N_LOG_LEVEL: debug
N8N_DIAGNOSTICS_ENABLED: true
volumes:
- ./workflows:/home/node/.n8n/workflows
- ./custom:/home/node/.n8n/custom
# Staging override (docker-compose.staging.yml)
version: '3.8'
services:
n8n:
environment:
N8N_HOST: staging.n8n.example.com
N8N_WEBHOOK_URL: https://staging.n8n.example.com/
deploy:
replicas: 2
# Production override (docker-compose.prod.yml)
version: '3.8'
services:
n8n:
environment:
N8N_HOST: n8n.example.com
N8N_WEBHOOK_URL: https://n8n.example.com/
EXECUTIONS_DATA_SAVE_ON_SUCCESS: none
deploy:
replicas: 3
resources:
limits:
cpus: '4.0'
memory: 8G
🚀 Deployment Script
#!/bin/bash
# deploy.sh - Smart deployment script
ENVIRONMENT=${1:-development}
case $ENVIRONMENT in
development)
docker-compose \
-f docker-compose.yml \
-f docker-compose.dev.yml \
up -d
;;
staging)
# Load staging secrets
export $(cat environments/.env.staging | xargs)
docker-compose \
-f docker-compose.yml \
-f docker-compose.staging.yml \
up -d --scale n8n=2
;;
production)
# Fetch production secrets from Vault
./scripts/fetch-prod-secrets.sh
# Blue-green deployment
docker-compose \
-f docker-compose.yml \
-f docker-compose.prod.yml \
up -d --no-deps --scale n8n=3 n8n
# Health check
./scripts/health-check.sh || rollback
;;
*)
echo "Unknown environment: $ENVIRONMENT"
exit 1
;;
esac
echo "✅ Deployed to $ENVIRONMENT"
Security Best Practices
Implementeer deze best practices voor maximale security:
🔒 Security Checklist
Secrets Management:
- ☑️ Never hardcode secrets
- ☑️ Use external secret managers
- ☑️ Rotate secrets regularly (90 days)
- ☑️ Unique secrets per environment
- ☑️ Encrypt secrets at rest
- ☑️ Use least privilege principle
Access Control:
- ☑️ Role-based access (RBAC)
- ☑️ MFA for production access
- ☑️ Audit logging enabled
- ☑️ Regular access reviews
- ☑️ Service accounts for automation
- ☑️ Network segmentation
File Security:
- ☑️ .env files in .gitignore
- ☑️ File permissions 600
- ☑️ Encrypted file systems
- ☑️ Secure backup procedures
- ☑️ Version control for configs
Monitoring:
- ☑️ Secret access monitoring
- ☑️ Anomaly detection
- ☑️ Failed auth alerts
- ☑️ Configuration drift detection
- ☑️ Compliance scanning
⚠️ Common Security Mistakes
- • Committing .env files: Always check git status before push
- • Sharing secrets via Slack/Email: Use secure channels only
- • Using same secrets everywhere: Unique per environment
- • No expiration policy: Set TTL on all secrets
- • Broad permissions: Grant minimum required access
- • No backup keys: Always have recovery procedure
🚀 Start met Secure N8N Configuration
Implementeer enterprise-grade secrets management en multi-environment setup voor je N8N installatie. Veilig, schaalbaar en compliant!
Automation Scripts voor Secrets Management
Automatiseer je secrets management met deze utility scripts:
🔄 Automatic Secret Rotation Script
#!/usr/bin/env python3
# rotate-secrets.py - Automatic secret rotation
import os
import json
import boto3
import hvac
from datetime import datetime, timedelta
import secrets
import string
class SecretRotator:
def __init__(self, provider='vault'):
self.provider = provider
if provider == 'vault':
self.client = hvac.Client(
url=os.environ['VAULT_ADDR'],
token=os.environ['VAULT_TOKEN']
)
elif provider == 'aws':
self.client = boto3.client('secretsmanager')
def generate_password(self, length=32):
"""Generate secure random password"""
alphabet = string.ascii_letters + string.digits + '!@#$%^&*'
return ''.join(secrets.choice(alphabet) for _ in range(length))
def rotate_database_password(self):
"""Rotate database password"""
new_password = self.generate_password()
# Update in secret manager
if self.provider == 'vault':
self.client.secrets.kv.v2.create_or_update_secret(
path='database',
mount_point='n8n',
secret={'password': new_password}
)
# Update database user
# postgres.execute(f"ALTER USER n8n PASSWORD '{new_password}'")
# Log rotation
print(f"✅ Database password rotated at {datetime.now()}")
def rotate_api_keys(self):
"""Rotate API keys for external services"""
services = ['stripe', 'sendgrid', 'twilio']
for service in services:
# Call service API to generate new key
# new_key = service_api.regenerate_key()
# Store in secret manager
if self.provider == 'vault':
self.client.secrets.kv.v2.create_or_update_secret(
path=f'api-keys/{service}',
mount_point='n8n',
secret={'key': 'new_key_here'}
)
print(f"✅ {service} API key rotated")
def check_expiration(self):
"""Check which secrets need rotation"""
secrets_to_rotate = []
# Check all secrets
list_response = self.client.secrets.kv.v2.list_secrets(
mount_point='n8n'
)
for secret in list_response['data']['keys']:
metadata = self.client.secrets.kv.v2.read_secret_metadata(
path=secret,
mount_point='n8n'
)
created_time = metadata['data']['created_time']
age_days = (datetime.now() - created_time).days
if age_days > 90:
secrets_to_rotate.append(secret)
return secrets_to_rotate
if __name__ == '__main__':
rotator = SecretRotator()
# Check and rotate expired secrets
expired = rotator.check_expiration()
for secret in expired:
print(f"⚠️ Secret '{secret}' needs rotation")
# Perform rotation
rotator.rotate_database_password()
rotator.rotate_api_keys()
Conclusie
Proper variables en secrets management is cruciaal voor enterprise-ready N8N deployments. Door environment variables, workflow variables en externe secret managers te combineren, creëer je een veilige, schaalbare en maintainable automation platform.
Start met een basis .env setup, implementeer geleidelijk external secrets, en werk toe naar volledig automated secret rotation. Je workflows worden veiliger, je compliance verbetert, en je team kan met vertrouwen automatiseren.
📚 Gerelateerde Resources
Hulp nodig met secure N8N configuration? Contact me voor professional setup en security audit!