Appearance
login_id 與 email
對應主管要求 ② 零信任 + 無 IdP day-1 部署立場。
核心設計
Argus 把登入識別與聯絡資訊徹底拆開。
login_id | email | |
|---|---|---|
| 必填? | ✅ 必填 | ❌ 可選 |
| 唯一? | ✅ workspace 內唯一 | ❌ 不要求唯一 |
| 可改? | ❌ 一旦建立不可改 | ✅ 可改 |
| 用途 | 登入、IAM binding 指向、audit log actor | 通知、密碼重設、IdP claim 對應 |
| 格式 | [a-z0-9._@-],最長 256,全小寫 | 標準 email |
為什麼這樣設計
1. 私有部署很多人沒有公司 email
- 契約工 / 外部協力:常常只發 employee code,不發 email
- 服務帳號 / 機器人:本來就不是「人」,給 email 沒意義
- 跨集團共用:A 集團的人去 B 集團做專案,沒有 B 集團 email
把 email 當登入識別 = 強制要求公司必須先發 email 才能登入。Argus 不做這個假設。
2. 人會換 email、會改名
| 事件 | 影響(若 email 是識別) | Argus 的處理 |
|---|---|---|
| Alice 結婚改姓 | email 換了 → 所有 IAM binding / audit log 需遷移 | login_id 不變;email 改即可 |
| 員工部門轉移 | email domain 變了 | 同上 |
| 公司 rebrand(換 domain) | 全公司所有人 email 變 | 同上 |
| 員工 email 拼錯 | 改了會影響歷史 | 同上 |
一個穩定的
login_id= 一個穩定的稽核軌跡指向。
3. IdP 整合的時候 mapping 才有意義
當你接 OIDC / SAML 後:
- IdP 傳來的
sub(subject)是穩定識別 - IdP 傳來的
email可能變 - Argus 用
sub對應到本地 user,本地 user 的識別仍是login_id
這樣的好處是 IdP 換廠商(Okta → Entra ID)時,只需要重新 mapping sub,不必把 user 重建。
login_id 的選擇
建議的命名模式
| 模式 | 適合 | 注意 |
|---|---|---|
firstname.lastname | 員工流動低 | 同名衝突要加數字後綴 |
<employee_id> | 員工 ID 穩定 | UX 較差(人記不住) |
<email_prefix> | 與公司 email 對齊 | 改 email 就不一致 |
<purpose>-<id>(服務帳號) | 機器人 / 整合 | 例:bot-slack-notifier |
<vendor>-<id>(契約工) | 外部協力 | 例:vendor-acme-001 |
選定後全公司一致。混用會造成「我是 alice.chen 還是 alice」的長期困擾。
限制
- 字元:
[a-z0-9._@-](全小寫) - 長度:最長 256
- workspace 內唯一(即便是 deactivated 帳號也不能重用)
一旦建好就不可改
理由:
- IAM binding 指向
login_id - Audit log
actor指向login_id - IdP claim mapping 指向
login_id
改 login_id = 全 workspace 範圍的 cascade rename,沒這個 API。
如果真的需要改(極少數情境),唯一作法是:
- deactivate 舊
login_id- 建新
login_id- 重做 IAM binding
- 接受 audit log 上的歷史指向永遠是舊的
email 的角色
| 用途 | 是否需要 email? |
|---|---|
| 登入 | ❌ 用 login_id |
| Audit log actor | ❌ 用 login_id |
| IAM binding 指向 | ❌ 用 login_id |
| 密碼重設信 | ✅ |
| 通知(issue assigned / approved / failed) | ✅ |
IdP 對應的 fallback(先用 sub,沒對到再 fallback email) | ✅(如果 IdP 設成這樣) |
Email + 驗證碼登入(allow_email_code_signin) | ✅(一定要 email) |
沒 email 的 user
完全可用,但失去:
- 密碼重設只能 admin reset
- 通知不會發
- 不能用
allow_email_code_signin
給契約工建帳號時,這通常 OK — 他們也不會用 email 通知功能。
API 視角
User 的 canonical resource name:
text
users/login_id=<login_id>例:
text
users/login_id=alice.chen
users/login_id=vendor-acme-001
users/login_id=bot-slack-notifier不是 users/<email> 或 users/<numeric_id>。
Audit log 上的 actor:
text
user/login_id=alice.chen詳見 Audit Log 欄位。
常見問題
「我可以用 email 登入嗎?」
不行(除非啟用 allow_email_code_signin)。預設登入欄位是 login_id。
把 login_id 設成跟 email 一樣(alice@corp.com)也是可以的,但本質上仍是 login_id 字串,與真實 email mailbox 無關。
「我的 login_id 跟 IdP 傳來的不一樣怎麼辦?」
兩個選項:
- 保留現有
login_id:admin 在 user profile 設external_id對應 IdP 的sub - 同步 IdP 識別:deactivate 舊 user,依 IdP claim 建新 user(會失去歷史 actor 指向)
選 1 較常見。詳見 認證模式 — 接企業 IdP。
「契約工 IdP off-IdP — 怎麼操作?」
照 建立帳號(無 IdP 流程) 建本地帳號,不接 IdP;給 expires_at。
「我們強制全公司一個 email 對應一個 user,會出問題嗎?」
不會。Argus 不阻止你這樣用,只是不強制。
唯一注意:員工換 email 時,要記得更新 user 的 email 欄位(login_id 不動)。
Audit log
bb.user.create payload 含 login_id + email。建議 export 報表時用:
bash
# 列出所有 user 的 login_id + 是否有 email
filter='action:bb.user.create'
# 列出曾改過 email 的 user
filter='action:bb.user.update AND extra.field:email'相關
- 認證模式
- 建立帳號(無 IdP 流程)
- IAM Binding
- 設計文件:
docs/modules/auth-internal-deployment.md(內部)