n8n credentials 安全管理:production 級 secret rotation 實戰指南
n8n credentials 是 workflow 用到的 API key、OAuth、DB 密碼。本文整理 production 級 6 步驟 SOP、3 類 secret 輪替節奏、外部 vault 接入做法與外洩 30 分鐘應變,立即套用。
n8n credentials 安全管理是把 workflow 用到的 API key、OAuth token 與 DB 密碼以加密形式儲存並定期輪替的治理機制,透過 N8N_ENCRYPTION_KEY、外部 vault 接入與外洩 SOP,解決 credential 寫死、共用帳號與長期不換造成的橫向擴散風險。
為什麼 production n8n 不能用 default credentials 設定
很多團隊在開發機跑通 workflow 就直接 docker compose up -d 推 production,這是 credential 風險最高的時刻。default 安裝模式對快速試用很友善,但在 production 環境會留下 4 個容易被忽略的洞。
4 個 default 安裝會踩到的雷
- N8N_ENCRYPTION_KEY 沒設:n8n 啟動時會自動產生隨機 key,存進 SQLite 旁邊的
~/.n8n/config檔。換機器、重灌 docker volume、把資料庫複製到新環境的瞬間,所有 credential 都解不開。團隊以為「資料庫備份就夠了」,結果還原後一片紅。 - SQLite 共用 file lock 在多 worker 環境會卡死:default 用 SQLite,credential 跟 execution 紀錄混在同一個
database.sqlite。一旦 scale 到 2 個以上 worker,credential 寫入會偶發 file lock 衝突,最終逼你切到 PostgreSQL,但這時 credential 已經被舊 key 加密過了。 - docker-compose.yml 把 key 寫死:很常見的反模式是把
N8N_ENCRYPTION_KEY=mysecret123直接寫進 yaml 然後 push 到 GitHub。即使是 private repo,CI runner、log、screen share 都可能洩漏。GitGuardian 2025 年掃描資料顯示,約 12% 的 n8n encryption key 是在 git 歷史裡被找到的。 - 共用 owner 帳號操作所有 workflow:default 模式下每個 user 都能 read 所有 credential,即使 UI 顯示星號,credential 物件本身仍可透過 API 拉出加密 payload。一旦 owner 帳號被撞密碼,整個自動化堆疊全裸。
default vs production 級差別
| 面向 | default 安裝 | production 級配置 |
|---|---|---|
| Encryption key | 自動產生、存 disk | 由 vault / env 注入,與資料庫分離 |
| 資料庫 | SQLite | PostgreSQL(含每日備份) |
| Rotation | 無 | 30 / 90 / 180 天分級排程 |
| Audit | 沒 log | 接 Loki / CloudWatch / ELK |
| 隔離 | 共用 owner | RBAC + 環境前綴 + 最小權限 |
平台選型本身會影響 credential 治理可行性,回看平台選型與總成本判斷就會發現,自架的成本優勢一部分要拿來投資治理。
production 級 credentials 治理 6 步驟 SOP
下面 6 步驟是給 5 到 30 人團隊的最小集合。3 人以下的微型團隊先做 Step 1、2、6,後面三步等用量上來再補。
Step 1: 換掉預設 N8N_ENCRYPTION_KEY
用 openssl rand -hex 32 產一把 64 字元的 key,寫進 secret manager 或 docker secret,不要寫進 git 管理的 .env。啟動命令改用:
docker run -d --restart=always \
--name n8n \
-e N8N_ENCRYPTION_KEY="$(cat /run/secrets/n8n_key)" \
-v n8n_data:/home/node/.n8n \
n8nio/n8n
從 default 切過來會卡一個老問題:舊 credential 是用舊 key 加密的。正確流程是先在新環境跑乾淨安裝、寫好新 key,再從舊環境匯出 workflow(不含 credential),到新環境重新填一次 credential。直接把 sqlite 搬過去配新 key 必爆。官方建議流程在 n8n encryption key 文件 寫得很清楚。
Step 2: 切到 PostgreSQL
把 DB_TYPE=postgresdb 加上 DB_POSTGRESDB_* 系列環境變數。為什麼非切不可:
- credential 與 execution log 表會在大量 workflow 下成為熱點,SQLite file lock 會拖慢 webhook 響應
- PostgreSQL 才能配 streaming replication 與 PITR,credential 表掛了能還原到 5 分鐘前
- 自架 n8n 出事 80% 是備份策略沒做,PostgreSQL 配
pg_dumpcron + S3 上傳 30 行就夠
Step 3: credentials 命名規約
把 credential 名稱當文件用,命名規則固定為 <env>-<service>-<owner>-<purpose>:
prod-stripe-payments-team-chargestaging-openai-content-team-summarizedev-slack-alex-personal-test
這一招看起來很瑣碎,但 Web UI 沒做 tag 之前,這就是唯一能在 50 個 credential 裡快速找到「哪幾把是我前同事建的」的方法。離職交接時直接 grep <owner> 就能列出全部要 transfer 的項目。
模板上線前的命名規約整理可看模板挑選與設計哲學,挑模板進來改之前先把 credential 規約立好,可以省掉後面很多拆遷成本。
Step 4: RBAC 隔離與最小權限
n8n 1.x 開始支援 user role,把 owner / admin / member 切清楚:
- Owner:只給 1-2 個正職,主要做 backup 與 user 管理
- Admin:可建 credential、可 share workflow,給 senior 工程師
- Member:只能用被 share 的 credential,給 junior / 外包
API key 也要分級:每個外部 service account 只配最小 scope。Stripe restricted key、Google service account scoped role、Slack bot token 限定 channel。OWASP Top 10 把 Security Misconfiguration 列在 A05,過大權限就是這條的最常見表現。
Step 5: audit log 接 Loki / Grafana
n8n 內建 audit log 但 default 不打開。設定 N8N_DIAGNOSTICS_ENABLED=true 並把 stdout / stderr 用 Promtail 推進 Loki,再用 Grafana 設 alert:
- credential 在非工作時間被 read → Slack 通知
- 同一 credential 被 5 個以上 workflow 引用 → 提醒拆權限
- 任何 credential update 失敗 → 立即叫 SRE
Step 6: 90 天輪替排程
用 GitHub Actions 跑 cron 排程:
on:
schedule:
- cron: '0 9 1 */3 *' # 每 3 個月 1 號 09:00
job 內容是發 Slack thread 點名「該換 key 的人」,附上 credential 清單。排得比實際輪替提前 7 天,留時間協調。
secret rotation 怎麼排:3 類 credential 的不同節奏
把 credential 全部 30 天輪替會讓團隊崩潰,但全部不換又是 production 災難。實務做法是按敏感度分級:
高敏感:每 30 天 + 任何離職立即換
- 金流:Stripe、PayPal、街口、藍新、綠界
- 雲端 root:AWS root access key、GCP owner service account
- 自架資料庫的 superuser 密碼
特徵是外洩可直接導致財務損失。30 天輪替不是怕單把 key 被破解,而是限制「離職員工帶走 key 後可能的影響窗口」。
中敏感:每 90 天 + 用量異常觸發
- LLM API:OpenAI、Anthropic、Gemini key
- Google Workspace、Microsoft 365 service account
- Slack bot token、Discord bot token
- 第三方 SaaS API(Mailchimp、Zendesk、HubSpot)
90 天是合理平衡點。觸發式輪替更重要:用量突然飆 3 倍、計費異常、token usage 出現非預期 model → 立刻換不等排程。
低敏感:每 180 天
- 內部 webhook URL(Slack incoming webhook、Discord webhook)
- 公開資料 API(公開氣象、匯率)
- 自架 service 之間 service-to-service token(已在 VPN 內)
180 天是 OWASP 對「低風險 secret」的常見建議下限。再低於這頻率輪替的成本會超過收益,但完全不換等同 hardcode。
外部 vault 接入:HashiCorp Vault / AWS Secrets Manager 怎麼串 n8n
n8n 內建 credential 加密適合 30 人以下團隊。再大就要把 secret 從 n8n 搬到外部 vault,原因不是 n8n 不安全,而是要把 secret 治理跟 workflow 治理拆開。
兩種接法比較
| 接法 | 適合場景 | 優點 | 缺點 |
|---|---|---|---|
| 啟動時注入 env | 5-30 人,多數 production | 最簡單、沒額外 latency | 換 secret 要重啟 |
| Runtime API 拉取 | 50+ 人、需要 dynamic secret | 不用重啟、可短期 token | 多一次 API 呼叫、要處理 cache |
90% 的團隊用啟動時注入就夠。runtime API 是給「資料庫密碼每小時自動換」的金融、醫療場景。
HashiCorp Vault dynamic secrets 在 n8n 的實作模式
Vault 的 database secrets engine 可以「現場為 n8n 產一把只能用 1 小時的 PostgreSQL 帳號」。架構是:
- n8n container 啟動時用 AppRole 向 Vault 換 short-lived token
- 用 token 跟 Vault 拉一組 PostgreSQL credential
- 寫進 n8n 的 env,連上資料庫
- 1 小時後 token 過期,下次重啟自動拉新組
優勢是「即使 n8n 被入侵,credential 用 1 小時就作廢」,DB 帳號也是隔離的不會撞到主帳號。缺點是要養一座 Vault cluster,10 人以下團隊不划算。
AWS Secrets Manager + IAM role 在自架 EC2 上的最簡架構
如果自架在 AWS,這是最簡解:
- 把 secret 存進 AWS Secrets Manager
- EC2 instance 掛 IAM role,role 有
secretsmanager:GetSecretValue權限 - 啟動 script 用
aws secretsmanager get-secret-value拉出來注入 env - n8n 啟動
這架構零額外 server,IAM role 也不用發 access key。換 secret 流程變成「在 console 按 update → 重啟 n8n」,rotation 排程可以串 Lambda 自動化。實際 production 案例可看把 n8n + Claude 拉進 Excel 自動化,那篇講了完整的憑證流轉 + workflow 落地。
外洩 30 分鐘應變 SOP
中招了不要慌。30 分鐘決定影響面是「單把 key」還是「整個自動化堆疊」。下面流程是 3 段時間切:
0-5 分鐘:止血
立即 revoke 該 credential:
- Stripe、AWS:直接 dashboard delete key
- OAuth:到 service 端 revoke 該 token
- 自架 DB:改密碼,沒辦法 revoke 就改
同步停掉所有引用該 credential 的 active workflow(n8n UI deactivate)。這 5 分鐘不要先盤點影響,先讓 attacker 用不到。
5-20 分鐘:影響評估
從 audit log 拉 7 天內所有 credential read 紀錄:
- 哪些 IP 用過?正常 IP 跟可疑 IP 分清楚
- 用量異常嗎?比前 7 天平均高 5 倍以上要存證
- 有沒有非預期的 endpoint 被呼叫?
把 finding 整理成 timeline,後面寫 post-mortem 直接複製。
20-30 分鐘:補救
- 換新 key(用 Step 1 流程)
- 把所有引用該 credential 的 workflow 重設定,逐個重啟
- 如果用戶資料可能受影響,依 GDPR / 個資法 72 小時通報義務啟動
- 寫 post-mortem,重點是「下次怎麼更早發現」,不是責怪誰
超過 30 分鐘還沒處理完,就要叫 SRE on-call 接手。Hour 1 之後每多一小時,影響面平均擴大 1.7 倍(Verizon DBIR 2024 統計)。
常見問題
Q:encryption key 換了會不會把已存的 credential 解不開? A:會。流程必須是「先用舊 key 把 credential 匯出明文 → 換 key → 用新 key 重新匯入」。直接重啟 n8n 換 key,所有 credential 變亂碼,UI 會顯示「decryption failed」。建議在 staging 環境先跑一遍流程確認。
Q:docker volume 換 PVC 會不會弄丟 credential?
A:只要 ~/.n8n/config 跟 database.sqlite 一起搬就不會。但這證明了 SQLite 的問題:volume 一動,credential 就要跟著動。切 PostgreSQL 後 credential 跟 service runtime 解耦,搬 pod 不影響 credential。
Q:自架 n8n 真的要做這麼複雜嗎?團隊小可以怎麼簡化? A:3 人以下做最小集合就好——換 N8N_ENCRYPTION_KEY、切 PostgreSQL(用 managed service 像 Supabase / Neon 免費 tier 也行)、設 90 天提醒。其他 RBAC、Vault、audit log 等到團隊到 10 人或處理金流時再補。但 N8N_ENCRYPTION_KEY 跟 PostgreSQL 兩條沒做,第一次出事就會學到教訓。