n8n Credential Yönetimi ve Güvenli API Bağlantısı

Otomasyon dünyasında en çok canımı sıkan şey nedir biliyor musunuz? Kimlik bilgilerinin workflow’ların içine gömülü halde bulunması. GitHub’da n8n export’larını ararsanız, düzinelerce repoda API anahtarlarının, şifrelerin ve token’ların açıkça yazıldığını görebilirsiniz. Bu bir ihmal meselesi değil, credential yönetiminin nasıl yapılması gerektiğini tam olarak anlamamaktan kaynaklanıyor. Bu yazıda n8n’in credential sistemini gerçek üretim ortamlarında nasıl kullanmanız gerektiğini, nelere dikkat etmeniz gerektiğini ve hangi hataların sizi gece uyandıracağını anlatacağım.

n8n Credential Sistemi Nasıl Çalışır?

n8n, kimlik bilgilerini veri tabanında şifrelenmiş olarak saklar. Varsayılan olarak AES-256-CBC algoritması kullanılır ve şifreleme anahtarı N8N_ENCRYPTION_KEY environment variable’ı üzerinden alınır. Bu anahtarı kaybederseniz, tüm credential’larınız erişilemez hale gelir. Yedeklemek bir öneri değil, zorunluluk.

Sistemin temel bileşenlerini anlamak önemli:

  • Encryption Key: Tüm kimlik bilgilerini şifreleyen master anahtar
  • Credential Types: Her servis için önceden tanımlanmış şema (OAuth2, API Key, Basic Auth vb.)
  • Scope: Credential’ların hangi workflow’lardan erişilebileceği
  • Credential Sharing: Multi-user kurulumlarında kimin neye erişebileceği

Temel sorun şu: n8n’i Docker ile ayağa kaldırıp hiç yapılandırmadan kullanmaya başlarsanız, şifreleme anahtarı rastgele oluşturulur ve genellikle container yeniden başlatıldığında değişir. Üretim ortamında bu kabul edilemez.

Ortam Değişkenleri ile Güvenli Kurulum

Docker Compose ile n8n kuruyorsanız, credential güvenliğini baştan doğru kurmak için şu yapıyı kullanın:

# .env dosyası - asla git'e commit etmeyin
N8N_ENCRYPTION_KEY=en-az-32-karakter-rastgele-bir-anahtar-buraya
DB_TYPE=postgresdb
DB_POSTGRESDB_HOST=localhost
DB_POSTGRESDB_PORT=5432
DB_POSTGRESDB_DATABASE=n8n_prod
DB_POSTGRESDB_USER=n8n_user
DB_POSTGRESDB_PASSWORD=guclu-bir-sifre-buraya
N8N_BASIC_AUTH_ACTIVE=true
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_PASSWORD=admin-sifre-buraya

Şifreleme anahtarı üretmek için:

# Güçlü bir encryption key üretme
openssl rand -hex 32

# Ya da Python ile
python3 -c "import secrets; print(secrets.token_hex(32))"

# Çıktıyı direkt .env'ye yaz
echo "N8N_ENCRYPTION_KEY=$(openssl rand -hex 32)" >> .env

Docker Compose dosyanızı environment variables referanslarıyla yapılandırın:

# docker-compose.yml içindeki n8n servisi için kritik kısım
# Anahtarı doğrudan compose dosyasına YAZMAYIN
# Her zaman .env'den okuyun

docker-compose --env-file .env up -d n8n

# Container'ın encryption key'i doğru aldığını kontrol edin
docker exec n8n-container env | grep N8N_ENCRYPTION_KEY
# Çıktı görmemek normaldir - güvenlik için maskeli olabilir
# Alternatif olarak n8n log'larını kontrol edin
docker logs n8n-container 2>&1 | grep -i encryption

Credential Yedekleme ve Taşıma

Yedekleme konusunu ciddiye almazsanız, bir gün gelecek ve o günü hiç unutmayacaksınız. Bunu teorik olarak söylemiyorum.

# Credential'ları n8n API üzerinden listeleyin
curl -s -u admin:sifre http://localhost:5678/api/v1/credentials 
  -H "Content-Type: application/json" | jq '.data[].name'

# Encryption key'i güvenli bir yere yedekleyin
# HashiCorp Vault kullanıyorsanız:
vault kv put secret/n8n encryption_key="$(cat .env | grep N8N_ENCRYPTION_KEY | cut -d'=' -f2)"

# Vault'tan okumak için:
vault kv get -field=encryption_key secret/n8n

Veritabanı yedeklemesini credential’larla birlikte yapın:

#!/bin/bash
# n8n-backup.sh
BACKUP_DIR="/opt/backups/n8n"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_PATH="${BACKUP_DIR}/${DATE}"

mkdir -p "${BACKUP_PATH}"

# PostgreSQL dump
pg_dump -h localhost -U n8n_user -d n8n_prod 
  --no-password 
  -f "${BACKUP_PATH}/n8n_db.sql"

# Encryption key'i ayrı ve şifreli sakla
echo "${N8N_ENCRYPTION_KEY}" | gpg --symmetric 
  --cipher-algo AES256 
  --output "${BACKUP_PATH}/encryption_key.gpg"

# Yedeği sıkıştır
tar -czf "${BACKUP_DIR}/n8n_backup_${DATE}.tar.gz" 
  -C "${BACKUP_DIR}" "${DATE}"

# Geçici dosyaları temizle
rm -rf "${BACKUP_PATH}"

echo "Yedekleme tamamlandı: ${BACKUP_DIR}/n8n_backup_${DATE}.tar.gz"

API Credential’larını Programatik Oluşturma

Büyük ortamlarda onlarca servis entegrasyonu olabilir. Her birini UI’dan tek tek oluşturmak hem zaman alıcı hem de tutarsızlıklara yol açar. n8n API’sini kullanarak credential’ları kod ile yönetin:

# n8n API üzerinden yeni credential oluşturma
# Örnek: Slack API credential

N8N_URL="http://localhost:5678"
N8N_API_KEY="your-api-key-here"

curl -s -X POST "${N8N_URL}/api/v1/credentials" 
  -H "X-N8N-API-KEY: ${N8N_API_KEY}" 
  -H "Content-Type: application/json" 
  -d '{
    "name": "Slack Production Bot",
    "type": "slackApi",
    "data": {
      "accessToken": "xoxb-your-slack-bot-token"
    },
    "nodesAccess": [
      {
        "nodeType": "n8n-nodes-base.slack"
      }
    ]
  }' | jq '.id'

Bu yaklaşımı Infrastructure as Code prensibiyle birleştirin. Yeni ortam kurduğunuzda credential’ları otomatik olarak oluşturun:

#!/bin/bash
# provision-credentials.sh
# HashiCorp Vault'tan oku, n8n'e yükle

N8N_URL="${N8N_URL:-http://localhost:5678}"
N8N_API_KEY=$(vault kv get -field=api_key secret/n8n)

# Slack credential
SLACK_TOKEN=$(vault kv get -field=bot_token secret/slack/production)
curl -s -X POST "${N8N_URL}/api/v1/credentials" 
  -H "X-N8N-API-KEY: ${N8N_API_KEY}" 
  -H "Content-Type: application/json" 
  -d "{
    "name": "Slack Production",
    "type": "slackApi",
    "data": {"accessToken": "${SLACK_TOKEN}"}
  }"

# GitHub credential
GITHUB_TOKEN=$(vault kv get -field=token secret/github/n8n-bot)
curl -s -X POST "${N8N_URL}/api/v1/credentials" 
  -H "X-N8N-API-KEY: ${N8N_API_KEY}" 
  -H "Content-Type: application/json" 
  -d "{
    "name": "GitHub API",
    "type": "githubApi",
    "data": {
      "user": "n8n-bot",
      "accessToken": "${GITHUB_TOKEN}"
    }
  }"

echo "Credential provisioning tamamlandi"

OAuth2 Credential’larında Dikkat Edilmesi Gerekenler

OAuth2, en sık sorun yaşanan credential türü. Token yenileme mekanizmasını n8n halleder, ama bazı köşe vakalar var.

Google API’leri için servis hesabı kullanmak, OAuth2’nin token süresi dolma sorunlarını ortadan kaldırır:

# Google Service Account JSON'unu environment'a encode edin
# Dosyayı doğrudan kullanmak yerine base64 encode edin
SERVICE_ACCOUNT_JSON=$(cat service-account.json | base64 -w 0)

# n8n environment'ına ekleyin
# docker-compose.yml'de:
# environment:
#   - GOOGLE_SERVICE_ACCOUNT=${SERVICE_ACCOUNT_JSON}

# Sonra n8n'de credential oluştururken bu değeri kullanabilirsiniz
# Service account key dosyasını container dışında tutun
docker cp service-account.json n8n-container:/tmp/sa.json
# HAYIR! Bu yöntemi kullanmayın.
# Bunun yerine Vault veya Secret Manager kullanın

Gerçek ortamda OAuth token’larının durumunu izlemek için basit bir kontrol scripti:

#!/bin/bash
# check-oauth-tokens.sh
# Süresi dolmak üzere olan token'ları tespit et

N8N_URL="http://localhost:5678"
N8N_API_KEY="your-api-key"

# Tüm OAuth2 credential'larını listele
CREDENTIALS=$(curl -s "${N8N_URL}/api/v1/credentials" 
  -H "X-N8N-API-KEY: ${N8N_API_KEY}" | 
  jq -r '.data[] | select(.type | contains("OAuth2")) | "(.id) (.name)"')

echo "OAuth2 Credential Listesi:"
echo "${CREDENTIALS}"

# n8n bu işi otomatik yapar ama bazı legacy entegrasyonlarda
# manuel token yenileme gerekebilir
# Böyle durumlarda workflow tetikleyerek test edin:
curl -s -X POST "${N8N_URL}/api/v1/workflows/WORKFLOW_ID/run" 
  -H "X-N8N-API-KEY: ${N8N_API_KEY}" 
  -H "Content-Type: application/json" 
  -d '{"startNodes": [], "destinationNode": "Test Connection Node"}'

Credential Scope ve Erişim Kontrolü

Enterprise veya team kurulumlarında kim hangi credential’a erişebilmeli? Bu soruyu önceden yanıtlamazsanız, sonradan düzeltmek çok daha zor olur.

n8n’de credential paylaşımı birkaç seviyede çalışır:

  • Owner Only: Credential’ı oluşturan kişi kullanabilir
  • Specific Users: Belirli kullanıcılarla paylaşılır
  • All Users: Tüm ekip erişebilir (dikkatli kullanın)

Hangi credential’ların kimlerle paylaşıldığını düzenli olarak denetleyin:

#!/bin/bash
# audit-credential-sharing.sh
# Tüm credential paylaşım durumunu raporla

N8N_URL="http://localhost:5678"
N8N_API_KEY="your-api-key"

echo "=== N8N Credential Audit Raporu ==="
echo "Tarih: $(date)"
echo ""

curl -s "${N8N_URL}/api/v1/credentials" 
  -H "X-N8N-API-KEY: ${N8N_API_KEY}" | 
  jq -r '.data[] | "Credential: (.name)n  Tip: (.type)n  ID: (.id)n  Olusturan: (.ownedBy.email // "bilinmiyor")n"'

# Bu raporu Slack veya e-posta ile haftalık gönderin
# Beklenmedik paylaşımları erkenden yakalayın

Gerçek Dünya Senaryosu: Çoklu Ortam Yönetimi

Tipik bir setup şöyle görünür: Development, Staging, Production. Her ortamda farklı API anahtarları var. n8n’de bunu yönetmenin en pragmatik yolu environment-specific credential isimlendirmesi:

# Credential isimlerinde ortam prefix'i kullanın
# dev-Slack Notifications
# staging-Slack Notifications  
# prod-Slack Notifications

# Workflow'ları export ederken hangi credential kullanıldığına dikkat edin
curl -s "${N8N_URL}/api/v1/workflows/WORKFLOW_ID" 
  -H "X-N8N-API-KEY: ${N8N_API_KEY}" | 
  jq '.nodes[].credentials'

# Export edilen workflow'u başka ortama import etmeden önce
# credential referanslarını güncelleyin
WORKFLOW_JSON=$(curl -s "${N8N_URL}/api/v1/workflows/WORKFLOW_ID" 
  -H "X-N8N-API-KEY: ${N8N_API_KEY}")

# dev-> prod credential adı değişimi
echo "${WORKFLOW_JSON}" | 
  sed 's/dev-Slack/prod-Slack/g' | 
  sed 's/dev-GitHub/prod-GitHub/g' > workflow_prod.json

Ortamlar arası geçişte deployment pipeline’ınıza credential mapping adımını ekleyin:

#!/bin/bash
# deploy-workflow.sh ENVIRONMENT WORKFLOW_FILE
ENVIRONMENT=$1
WORKFLOW_FILE=$2

if [ -z "${ENVIRONMENT}" ] || [ -z "${WORKFLOW_FILE}" ]; then
  echo "Kullanim: $0 <environment> <workflow_json_file>"
  exit 1
fi

N8N_URL=$(vault kv get -field=url "secret/n8n/${ENVIRONMENT}")
N8N_API_KEY=$(vault kv get -field=api_key "secret/n8n/${ENVIRONMENT}")

# Credential adlarini ortama gore guncelle
UPDATED_WORKFLOW=$(cat "${WORKFLOW_FILE}" | 
  python3 -c "
import sys, json, re
data = json.load(sys.stdin)
env = '${ENVIRONMENT}'
# Credential referanslarini guncelle
workflow_str = json.dumps(data)
# dev-> hedef ortam
workflow_str = re.sub(r'"dev-', f'"{env}-', workflow_str)
print(workflow_str)
")

# Workflow'u hedef ortama deploy et
curl -s -X POST "${N8N_URL}/api/v1/workflows" 
  -H "X-N8N-API-KEY: ${N8N_API_KEY}" 
  -H "Content-Type: application/json" 
  -d "${UPDATED_WORKFLOW}"

echo "Workflow ${ENVIRONMENT} ortamina deploy edildi"

Güvenlik Kontrol Listesi

Üretime almadan önce şu maddeleri kontrol edin:

  • Encryption Key: Rastgele, en az 32 karakter ve güvenli bir yerde yedekli
  • API Key Authentication: n8n API’sine erişim için mutlaka API key aktif olsun
  • Network Isolation: n8n’in veritabanı portu dışarıya açık olmasın
  • HTTPS: Webhook URL’leri ve UI erişimi için TLS zorunlu
  • Credential Rotation: API anahtarlarını düzenli olarak yenileyin ve n8n’i güncelleyin
  • Log Monitoring: Credential erişim loglarını merkezi log sisteminize gönderin
  • Minimal Permission: Her servis için minimum gerekli izinlere sahip API anahtarı kullanın
  • Secret Scanning: Git hook’larıyla credential’ların kod tabanına karışmasını engelleyin

n8n log’larından şüpheli aktiviteleri izlemek için:

# n8n credential erişim loglarini izle
docker logs -f n8n-container 2>&1 | 
  grep -E "(credential|auth|token|error)" | 
  grep -v "debug"

# Başarısız kimlik doğrulama girişimlerini say
docker logs n8n-container 2>&1 | 
  grep -c "401|403|Unauthorized|Forbidden"

# Logları merkezi sisteme gönder (örnek: journald üzerinden)
# /etc/docker/daemon.json'a ekleyin:
# {"log-driver": "journald"}
journalctl -u docker CONTAINER_NAME=n8n-container -f | 
  grep -i credential

Sonuç

n8n’in credential sistemi, doğru yapılandırıldığında gerçekten güçlü ve kullanışlı. Ama varsayılan kurulumla üretime geçmek, kapıyı kilitsiz bırakmak gibi. Bu yazıda anlattıklarımı üç ana başlıkta özetleyebilirim.

Şifreleme anahtarı her şeyden önce gelir. N8N_ENCRYPTION_KEY olmadan güvenli bir kurulum düşünülemez. Bu anahtarı Vault gibi bir secret manager’da saklayın ve yedeğini alın. Kaybettiğinizde çözüm yoktur.

Credential’ları kod gibi yönetin. Infrastructure as Code prensibini credential yönetimine de uygulayın. Manuel UI işlemleri yerine API ve otomasyon scriptleri kullanın. Böylece yeni ortam kurduğunuzda saatler değil, dakikalar içinde hazır olursunuz.

Denetim ihmal edilmez. Kim hangi credential’a erişiyor, hangi workflow hangi anahtarı kullanıyor, bunları düzenli olarak gözden geçirin. n8n enterprise değilseniz bile basit shell scriptleriyle bu denetimi yapabilirsiniz.

Credential yönetimi seksi bir konu değil, ben de biliyorum. Ama bir gece telefon açılıp “API anahtarımız ifşa olmuş” denildiğinde, bu konuya harcanan saatler anlamsız görünmez. Önlem sonradan pişmanlıktan her zaman daha ucuzdur.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir