Credential 관리와 보안 — 프로덕션 환경 구축
워크플로우가 동작하면 기쁘지만, 보안이 뚫리면 끝이다. API 키 하나가 유출되면 수백만 원의 피해가 발생할 수 있다. 프로덕션 보안은 선택이 아닌 필수다.
Credential 암호화
N8N_ENCRYPTION_KEY
n8n은 모든 Credential을 AES-256-CBC로 암호화하여 DB에 저장한다. 이 암호화의 키가 N8N_ENCRYPTION_KEY다.
# docker-compose.yml
environment:
- N8N_ENCRYPTION_KEY=your-random-256bit-key-here
| 규칙 | 설명 |
|---|---|
| 반드시 설정 | 미설정 시 자동 생성되지만 컨테이너 재생성 시 Credential이 복호화 불가 |
| 충분한 길이 | 최소 32자 이상의 랜덤 문자열 |
| 절대 변경 금지 | 변경하면 기존 모든 Credential이 복호화 불가 |
| 백업 필수 | 별도 안전한 곳에 보관 (1Password, Vault 등) |
# 안전한 키 생성
openssl rand -hex 32
# → e.g. 4a7d1ed414474e4033ac29ccb8653d9b...
환경 변수로 민감 정보 관리
Credential에 API 키를 직접 입력하는 대신 환경 변수를 활용하면:
- 코드와 비밀값이 분리된다
- 환경별(개발/스테이징/프로덕션) 다른 값 사용 가능
- Git에 비밀값이 커밋되지 않는다
.env 파일 사용
# .env
N8N_ENCRYPTION_KEY=4a7d1ed414474e4033ac29ccb8...
DB_PASSWORD=super-secure-db-password
OPENAI_API_KEY=sk-proj-...
SLACK_BOT_TOKEN=xoxb-...
GITHUB_TOKEN=ghp_...
# docker-compose.yml
services:
n8n:
env_file:
- .env
n8n 전역 변수 ($vars)
n8n UI에서 Variables 메뉴를 통해 전역 변수를 설정할 수 있다.
Variables:
SLACK_CHANNEL_ALERTS: C0123456789
DEFAULT_TIMEZONE: Asia/Seoul
MAX_RETRIES: 3
워크플로우에서 참조:
{{ $vars.SLACK_CHANNEL_ALERTS }}
💡 $env vs $vars:
$env는 시스템 환경 변수(서버 관리자만 설정),$vars는 n8n UI에서 설정(워크플로우 작성자도 사용).
네트워크 보안
HTTPS 설정 (리버스 프록시)
프로덕션에서는 반드시 HTTPS를 사용해야 한다. Nginx 또는 Caddy를 앞에 두자.
Caddy (자동 HTTPS):
# Caddyfile
n8n.yourdomain.com {
reverse_proxy n8n:5678
}
Nginx:
server {
listen 443 ssl;
server_name n8n.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/n8n.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/n8n.yourdomain.com/privkey.pem;
location / {
proxy_pass http://localhost:5678;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket 지원 (에디터에 필요)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
IP 화이트리스트
n8n 관리 페이지에 접근 가능한 IP를 제한한다:
location / {
allow 203.0.113.0/24; # 회사 IP 대역
allow 198.51.100.5; # VPN IP
deny all;
proxy_pass http://localhost:5678;
}
Webhook IP는 허용
외부 Webhook은 모든 IP에서 접근 가능해야 하므로 별도 경로 설정:
location /webhook/ {
# Webhook은 모든 IP 허용
proxy_pass http://localhost:5678;
}
location /webhook-test/ {
# Test Webhook도 허용
proxy_pass http://localhost:5678;
}
사용자 권한 관리
n8n은 역할 기반 접근 제어(RBAC)를 지원한다.
| 역할 | 권한 |
|---|---|
| Owner | 모든 권한 (설정, 사용자 관리) |
| Admin | 워크플로우, Credential 관리 |
| Member | 자신의 워크플로우만 관리 |
Credential 공유
Credential을 팀원과 공유할 때:
- 사용 권한: 워크플로우에서 Credential을 사용할 수 있지만, 값(API 키)은 볼 수 없음
- 편집 권한: Credential 값을 수정할 수 있음
💡 최소 권한 원칙: 팀원에게는 "사용" 권한만 부여하고, "편집"은 관리자만 갖자.
OAuth2 Token 갱신
OAuth2 Credential은 Access Token이 만료되면 자동으로 Refresh Token으로 갱신된다.
주의사항
| 문제 | 해결 |
|---|---|
| Refresh Token도 만료 | Google: 6개월 미사용 시 만료. 정기 실행 워크플로우 유지 |
| OAuth 동의 만료 | Google: 테스트 모드는 7일. Published 상태로 전환 |
| 토큰 저장 실패 | n8n 재시작 후 Credential 재연결 필요할 수 있음 |
보안 체크리스트
프로덕션 환경 구축 시 반드시 확인:
| 항목 | 확인 |
|---|---|
N8N_ENCRYPTION_KEY 안전한 값으로 설정 | □ |
.env 파일에 민감 정보 분리 | □ |
.env 파일 .gitignore에 추가 | □ |
| HTTPS 설정 (리버스 프록시) | □ |
| IP 화이트리스트 (관리 페이지) | □ |
| 사용자별 최소 권한 부여 | □ |
| DB 전용 사용자 생성 (최소 권한) | □ |
| Docker 네트워크 분리 | □ |
| 정기 백업 설정 | □ |
| 실행 데이터 자동 정리(Prune) 설정 | □ |
📝 정리
- [x] 암호화 키:
N8N_ENCRYPTION_KEY로 Credential AES-256 암호화, 절대 변경 금지 - [x] 환경 변수:
.env파일로 민감 정보 분리,$env와$vars활용 - [x] 네트워크: HTTPS 필수, IP 화이트리스트, WebSocket 프록시 설정
- [x] 권한 관리: Owner/Admin/Member 역할, Credential 공유 시 사용 권한만
- [x] OAuth2: Refresh Token 자동 갱신, 장기 미사용 시 만료 주의
다음 편 예고
28편: 성능 최적화 — 대용량 데이터와 고속 실행
Part 5 시작! 수만 건의 데이터 처리, 메모리 관리, 실행 큐 최적화로 n8n을 프로덕션 수준으로 튜닝하자.