Credential 관리와 보안 — 프로덕션 환경 구축

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을 프로덕션 수준으로 튜닝하자.