> For the complete documentation index, see [llms.txt](https://docs.maiagent.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.maiagent.ai/org/sso/sso-keycloak.md).

# Keycloak 整合

透過 OpenID Connect 協定整合 Keycloak 開源身分驗證平台

Keycloak 是一套廣泛使用的開源身分驗證與存取管理平台，MaiAgent 支援透過 OpenID Connect 協定與 Keycloak 整合。

**適用對象**：使用 Keycloak 做統一身分管理的企業，或需要以 Realm 為單位管理使用者的組織

**主要優勢**：

* 支援 Keycloak Realm 隔離
* 自動合成虛擬 Email 身分，適用於無 Email 的帳號
* 支援伺服器端 Token 撤銷（Logout）
* 整合 Keycloak 生態系的各項功能

## 設定步驟 <a href="#setup-steps" id="setup-steps"></a>

### 1. 在 Keycloak 中建立 Client <a href="#step-1-create-client" id="step-1-create-client"></a>

1. 登入 Keycloak Admin Console
2. 選擇目標 Realm
3. 在 <mark style="color:blue;">Clients</mark> 中新增一個 Client
4. 設定 Client Protocol 為 `openid-connect`
5. 設定 Access Type 為 `public`（或根據安全需求選擇 `confidential`）
6. 設定 Valid Redirect URIs 為 MaiAgent 的前端域名
7. 記下 Client ID

### 2. 在 MaiAgent 後台填寫 Keycloak 設定 <a href="#step-2-fill-keycloak-settings" id="step-2-fill-keycloak-settings"></a>

選擇 <mark style="color:blue;">Keycloak</mark> 認證類型後，需要填寫以下欄位：

| 欄位                                         | 必填 | 說明                                                                |
| ------------------------------------------ | -- | ----------------------------------------------------------------- |
| <mark style="color:blue;">認證來源名稱</mark>    | 是  | 識別這個認證來源的英文代號，會成為登入連結的一部分，例如 `company-kc`                         |
| <mark style="color:blue;">虛擬信箱網域</mark>    | 是  | 用於合成虛擬 Email 的網域，系統以「帳號@此網域」產生使用者信箱，例如 `company.com`              |
| <mark style="color:blue;">伺服器 URL</mark>   | 是  | Keycloak 伺服器 URL，例如 `https://keycloak.company.com/`               |
| <mark style="color:blue;">Realm 名稱</mark>  | 是  | Keycloak 中貴組織使用的 Realm 名稱，會組合進登入連結的 `realm` 參數                    |
| <mark style="color:blue;">Client ID</mark> | 是  | 步驟 1 在該 Realm 建立的 OIDC Client 的 Client ID，會組合進登入連結的 `clientId` 參數 |

填寫完成後，系統會自動產生 **Login URL**，格式為：

```
https://{前端域名}/auth/keycloak?url={Server URL}&clientId={Client ID}&realm={Realm}
```

### 3. 儲存並測試 <a href="#step-3-save-and-test" id="step-3-save-and-test"></a>

在 MaiAgent 後台點擊 <mark style="color:blue;">儲存</mark>，然後使用產生的 Login URL 測試登入流程。

## Keycloak 虛擬 Email 機制 <a href="#keycloak-virtual-email-mechanism" id="keycloak-virtual-email-mechanism"></a>

由於 Keycloak 的使用者不一定有 Email 地址，MaiAgent 會自動合成虛擬 Email 作為唯一識別：

```
虛擬 Email = {preferred_username}@{email_domain}
```

例如：使用者 `john.doe` 在虛擬信箱網域為 `company.com` 的設定下，會產生 `john.doe@company.com` 作為 MaiAgent 的使用者 Email。

{% hint style="info" %}
此虛擬 Email 僅作為系統內部識別用途，不會用於實際的 Email 發送。
{% endhint %}

## 登入失敗的訊息 <a href="#error-messages" id="error-messages"></a>

使用者開啟 Keycloak 登入連結後，畫面會先顯示「Keycloak 登入中...」；失敗時在下方以紅字顯示原因：

| 畫面訊息                           | 常見原因                                                                             | 處理方式                                                              |
| ------------------------------ | -------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
| 缺少必要的參數 (url, clientId, realm) | 開啟的網址少了 Keycloak 伺服器、Client ID 或 Realm 參數，通常是連結被截斷或手動改過                          | 改用設定頁登入連結卡複製的完整網址                                                 |
| 認證過程發生錯誤，請重試（…）                | 瀏覽器連不上 Keycloak 伺服器，或 Client 設定（Valid redirect URIs、Web origins）不允許 MaiAgent 的網址 | 確認使用者的網路可達 Keycloak；檢查 Client 的 redirect URI 與 Web origins 設定     |
| API 登入失敗                       | Keycloak 驗證成功，但 MaiAgent 沒有回傳登入結果                                                | 確認後台這個認證來源的登入已啟用，再重試一次                                            |
| API 登入過程發生錯誤（…）                | MaiAgent 驗證 Keycloak Token 時出錯，括號內是伺服器回傳的原因                                      | 依括號內訊息處理；常見是連結中的伺服器 URL、Realm 名稱或 Client ID 與後台設定不一致，或認證來源不屬於這個組織 |

## Keycloak 登出 <a href="#keycloak-logout" id="keycloak-logout"></a>

MaiAgent 的 Keycloak 整合支援伺服器端登出。當使用者在 MaiAgent 登出時，系統會同時向 Keycloak 伺服器發送 Token 撤銷請求，確保 Token 在 Keycloak 端也失效。

## 設定欄位速查表 <a href="#settings-quick-reference" id="settings-quick-reference"></a>

| 欄位        | 必填 | 格式                               | 範例                              |
| --------- | -- | -------------------------------- | ------------------------------- |
| 認證來源名稱    | 是  | 小寫英數 + 連字號，max 31 字元             | `company-kc`                    |
| 虛擬信箱網域    | 是  | 網域格式                             | `company.com`                   |
| 伺服器 URL   | 是  | HTTPS URL                        | `https://keycloak.company.com/` |
| Realm 名稱  | 是  | Keycloak Realm 名稱                | `company-sso`                   |
| Client ID | 是  | Keycloak OIDC Client 的 Client ID | `maiagent-portal`               |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.maiagent.ai/org/sso/sso-keycloak.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
