Credentials Security & Management¶
Comprehensive guide to credential management tools and security best practices.
Overview¶
n8n credentials store sensitive authentication data (API keys, passwords, OAuth tokens). The MCP server provides 6 credential management tools with strong security protections.
Security Model¶
Security by Design
n8n API blocks credential data retrieval for security: - ✅ Can create credentials - ✅ Can delete credentials - ✅ Can get credential schemas - ❌ Cannot list credentials (security block) - ❌ Cannot read credential data (security block) - ❌ Cannot update credentials directly (immutability)
Tools Summary¶
| Tool | Purpose | Status | Security |
|---|---|---|---|
list_credentials | List credentials | 🚫 Blocked | Security protection |
get_credential | Get credential data | 🚫 Blocked | Security protection |
create_credential | Create new credential | ✅ Allowed | Encrypted storage |
update_credential | Update credential | ⚠️ Guidance | Delete + Create pattern |
delete_credential | Remove credential | ✅ Allowed | Permanent deletion |
get_credential_schema | Get credential schema | ✅ Allowed | Schema only |
get_credential_schema¶
Retrieve the JSON schema for a specific credential type to understand required fields.
Purpose¶
Before creating credentials, get the schema to know what fields are required and their formats.
Input Parameters¶
{
credentialType: string; // Credential type (required)
instance?: string; // n8n instance (optional)
}
Common Credential Types¶
| Type | Purpose | Fields |
|---|---|---|
httpBasicAuth | HTTP Basic Authentication | user, password |
oAuth2Api | OAuth 2.0 | authUrl, accessTokenUrl, clientId, clientSecret |
apiKey | Generic API Key | apiKey, apiKeyLocation |
postgres | PostgreSQL Database | host, database, user, password |
gmail | Gmail API | clientId, clientSecret |
slackApi | Slack API | accessToken |
Usage Example¶
Request: Show me the schema for httpBasicAuth
What Claude does:
Response:
{
"type": "object",
"properties": {
"user": {
"type": "string",
"description": "Username"
},
"password": {
"type": "string",
"description": "Password",
"typeOptions": {
"password": true
}
}
},
"required": ["user", "password"]
}
create_credential¶
Create a new credential with encrypted storage.
Purpose¶
Store authentication data securely for use in workflows. Data is automatically encrypted by n8n.
Input Parameters¶
{
name: string; // Credential name (required)
type: string; // Credential type (required)
data: Record<string, any>; // Credential data (required)
nodesAccess?: Array<{ // Node access control (optional)
nodeType: string;
}>;
instance?: string; // n8n instance (optional)
}
Output Format¶
{
id: string;
name: string;
type: string;
createdAt: string;
updatedAt: string;
nodesAccess: Array<{nodeType: string}>;
}
Note: data field is never returned (security protection)
Usage Examples¶
Credential Data Encryption¶
Automatic Encryption
n8n automatically encrypts all credential data: - AES-256-CBC encryption - Encryption key from N8N_ENCRYPTION_KEY environment variable - Data never stored or transmitted in plain text - Decrypted only when workflow executes
update_credential¶
Update existing credential using DELETE + CREATE pattern.
Why DELETE + CREATE?¶
Immutability by Design
n8n credentials are immutable for security: - Cannot update credential data directly - Prevents accidental exposure - Ensures audit trail integrity
Update Pattern¶
// Step 1: Delete old credential
delete_credential({ id: "old_cred_id" })
// Step 2: Create new credential
create_credential({
name: "Updated Credential Name",
type: "credentialType",
data: {
// Updated credential data
}
})
Usage Example¶
Request: Update credential "API Access" with new password
What Claude does:
// Find credential by name (from previous conversation context)
const credId = "cred_abc123"
// Delete old
delete_credential({ id: credId })
// Create new with updated data
create_credential({
name: "API Access",
type: "httpBasicAuth",
data: {
user: "admin",
password: "new_password_456"
}
})
Important: Workflows using old credential ID will need to be updated.
delete_credential¶
Permanently remove a credential.
Purpose¶
Remove credentials that are no longer needed or need to be replaced.
Input Parameters¶
Usage Example¶
Request: Delete credential cred_abc123
Response:
✅ Successfully deleted credential (ID: cred_abc123)
Warning: Workflows using this credential will fail until updated.
Safety Checks¶
Before Deleting
- Check workflow usage - Identify workflows using this credential
- Create replacement - Have new credential ready
- Update workflows - Assign new credential to workflows
- Test workflows - Verify workflows work with new credential
- Then delete - Remove old credential
list_credentials & get_credential¶
Both tools are blocked by n8n API for security.
Why Blocked?¶
Security Protection
Preventing credential exposure: - Listing credentials could expose credential names - Getting credentials would expose sensitive data - Even encrypted data should not be retrievable - Prevents accidental credential leakage
What Claude Provides Instead¶
When you request credential information, Claude provides:
Educational Guidance:
n8n credentials are protected for security and cannot be listed
or retrieved via API. This prevents accidental exposure of
sensitive authentication data.
To view credentials:
1. Log into n8n web interface
2. Navigate to Credentials section
3. View credentials there
To use credentials in workflows:
- Create credentials via MCP: create_credential
- Reference by ID in workflow nodes
- Credentials automatically decrypted at execution
Alternatives: - Use n8n web UI to view credentials - Create new credentials via MCP - Delete and recreate to update
Security Best Practices¶
Credential Management¶
Best Practices
Creation: - Use descriptive names (e.g., "Production Slack Bot", not "Cred1") - Follow naming convention: [Environment] [Service] [Purpose] - Document credential usage in workflow descriptions
Storage: - Never store credentials in code or config files - Use n8n's encrypted storage exclusively - Set strong N8N_ENCRYPTION_KEY in n8n instance
Access Control: - Limit credential access to specific node types if possible - Use separate credentials per environment - Rotate credentials regularly (90-180 days)
Maintenance: - Document which workflows use each credential - Test after credential updates - Delete unused credentials promptly
Environment Separation¶
Multi-Instance Pattern:
// Production credentials (production instance)
create_credential({
name: "Production API Key",
type: "apiKey",
data: { apiKey: "prod_key" },
instance: "production"
})
// Staging credentials (staging instance)
create_credential({
name: "Staging API Key",
type: "apiKey",
data: { apiKey: "staging_key" },
instance: "staging"
})
Credential Rotation¶
Rotation Workflow:
1. Create new credential with rotated secret
→ create_credential({ name: "API v2", ... })
2. Update workflows to use new credential
→ update_workflow({ nodes: [...] })
3. Test workflows with new credential
→ Verify executions succeed
4. Delete old credential
→ delete_credential({ id: old_id })
Common Credential Types¶
HTTP Authentication¶
Basic Auth:
create_credential({
name: "API Basic Auth",
type: "httpBasicAuth",
data: {
user: "username",
password: "password"
}
})
API Key:
create_credential({
name: "API Key",
type: "apiKey",
data: {
apiKey: "your-api-key",
apiKeyLocation: "header", // or "query"
apiKeyName: "X-API-Key"
}
})
OAuth2:
create_credential({
name: "OAuth2 App",
type: "oAuth2Api",
data: {
authUrl: "https://auth.example.com/oauth/authorize",
accessTokenUrl: "https://auth.example.com/oauth/token",
clientId: "your-client-id",
clientSecret: "your-client-secret",
scope: "read write",
grantType: "authorizationCode"
}
})
Database Connections¶
PostgreSQL:
create_credential({
name: "PostgreSQL DB",
type: "postgres",
data: {
host: "localhost",
port: 5432,
database: "mydb",
user: "dbuser",
password: "dbpass",
ssl: "allow"
}
})
MySQL:
create_credential({
name: "MySQL DB",
type: "mysql",
data: {
host: "localhost",
port: 3306,
database: "mydb",
user: "dbuser",
password: "dbpass"
}
})
Service Integrations¶
Slack:
create_credential({
name: "Slack Bot",
type: "slackApi",
data: {
accessToken: "xoxb-your-bot-token"
}
})
Gmail:
create_credential({
name: "Gmail Account",
type: "gmailOAuth2",
data: {
clientId: "your-client-id",
clientSecret: "your-client-secret"
}
})
Troubleshooting¶
Credential Not Working¶
Check: 1. Credential exists and is properly created 2. Workflow node references correct credential ID 3. Credential type matches node requirements 4. Authentication data is correct 5. Service credentials are valid (not expired)
Workflow Fails After Credential Update¶
Solution: 1. Credential ID changed (DELETE + CREATE pattern) 2. Update workflow to use new credential ID 3. Verify new credential data is correct 4. Test workflow execution
Next Steps¶
- Workflows Management - Use credentials in workflows
- API Reference - Technical details
- Error Reference - Security troubleshooting
Need Help?