Proper credential management and security hardening are essential before running n8n in any production or team environment.
Credentials in n8n are stored encrypted at rest using AES-256 encryption, keyed by N8N_ENCRYPTION_KEY. They are reusable across all workflows and shared across team members (based on access level).
# Creating an API Key credential: 1. Settings → Credentials → New Credential 2. Search for "Header Auth" or the specific service (e.g. "OpenAI") 3. Fill in: Name: My OpenAI Key (your label) Value: sk-proj-abc123... (the actual API key) 4. Save # In a node, select this credential from the dropdown # The key is injected automatically — never visible in workflow JSON
# Example: Google OAuth2 setup 1. Go to Google Cloud Console → Create OAuth2 App - Client ID: xxxxxxxxx.apps.googleusercontent.com - Client Secret: GOCSPX-xxxxxx 2. In n8n Credentials → New → "Google OAuth2 API" Client ID: (paste from GCP) Client Secret: (paste from GCP) Callback URL: https://your-n8n.com/rest/oauth2-credential/callback 3. Add the callback URL to the allowed redirect URIs in GCP 4. Click "Sign in with Google" in n8n → browser opens → grant access 5. Token is stored automatically, refreshed by n8n when it expires # Scopes needed (set in GCP OAuth consent screen): https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/gmail.send
| Variable | Purpose | Example |
|---|---|---|
N8N_ENCRYPTION_KEY | Key used to encrypt credentials at rest | random 32+ char string |
N8N_HOST | Hostname for webhook URLs | n8n.mycompany.com |
N8N_PORT | Port n8n listens on | 5678 |
N8N_PROTOCOL | http or https | https |
DB_TYPE | Database backend | postgresdb |
EXECUTIONS_DATA_MAX_AGE | Days to keep execution logs | 30 |
N8N_BASIC_AUTH_ACTIVE | Enable basic auth on UI | true |
N8N_BASIC_AUTH_USER | Basic auth username | admin |
N8N_BASIC_AUTH_PASSWORD | Basic auth password | strongpassword |
# .env file for Docker Compose N8N_ENCRYPTION_KEY=my-super-secret-32char-key-here! N8N_HOST=n8n.mycompany.com N8N_PROTOCOL=https N8N_BASIC_AUTH_ACTIVE=true N8N_BASIC_AUTH_USER=admin N8N_BASIC_AUTH_PASSWORD=S3cur3P@ssw0rd
| Role | Permissions |
|---|---|
| Owner | Full access: all workflows, credentials, settings, users |
| Admin | All workflows, credentials; can manage users (Enterprise) |
| Member | Own workflows and credentials; limited to shared ones |
# n8n has a public REST API for managing workflows programmatically
# Enable in Settings → n8n API
# Generate an API key and use it as:
X-N8N-API-KEY: your-api-key
GET https://your-n8n.com/api/v1/workflows
POST https://your-n8n.com/api/v1/workflows/{id}/activate
# In Webhook node → Authentication → Header Auth Header Name: X-Webhook-Secret Header Value: my-shared-secret-123 # Sending services must include: curl -H "X-Webhook-Secret: my-shared-secret-123" ...
// Verify HMAC-SHA256 signature (GitHub/Stripe style)
const crypto = require('crypto');
const secret = 'my-webhook-secret';
const body = JSON.stringify($json.body);
const signature = $json.headers['x-hub-signature-256'];
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
if (signature !== expected) {
throw new Error('Invalid webhook signature');
}
return $input.all();
N8N_ENCRYPTION_KEY before first run — changing it later breaks all credentials.n8n folder (or Postgres DB) — this contains encrypted credentials