mcp-oauth2-workshop
Health Uyari
- No license — Repository has no license file
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 7 GitHub stars
Code Gecti
- Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Gecti
- Permissions — No dangerous permissions requested
Bu listing icin henuz AI raporu yok.
MCP Authorization (2025-11-25) workshop with Go and Python labs, instructor-hosted Signet, Claude Code/Codex CLI, PKCE, scopes, revocation, and a final Kong Gateway lab.
MCP OAuth 2.0 Workshop
讓 AI Agent、MCP Server 與 CLI 安全登入的實作工作坊。
90 分鐘主課依序完成 Lab 01–04、06 五個關卡:觀察沒有授權的 MCP Server、透過 OAuth 2.0 + PKCE 登入、驗證 Token 與權限,以及把入口授權集中到 Kong Gateway。Lab 05 的 Token 撤銷保留為課後進階選修。教材以 MCP Authorization 2026-07-28 為基準。
- 活動:Hello World Dev Conference 2026
- 時間:2026/10/14;13:00–13:30 環境準備,13:30–15:00 正式課程(活動頁另列 10/15 同內容場次)
你需要選擇的三件事
| 選擇 | 選項 | 備註 |
|---|---|---|
| 語言 | Go 或 Python | 兩條路線教學行為等價,選一種就好 |
| AI CLI | Claude Code 或 Codex CLI | 需要自己的帳號;範例不需要模型 API key |
| 作業系統 | macOS / Linux / Windows(WSL2) | Windows 請在 WSL2 內操作 |
上課前檢查清單
請在 10/14 前 完成,現場 30 分鐘只留給排除狀況:
- 安裝 Git、curl、編輯器
- (選用)安裝 fx 方便瀏覽 JSON 輸出(
brew install fx,其他平台見 安裝說明) - 安裝 Go 1.26 或 1.27,或 Python 3.12(建議;3.11 以上可用)+ uv
- 安裝 Claude Code 或 Codex CLI,並確認能登入、能對話
- 能登入 Signet(使用現成服務,不需自行安裝)
- 完成下方「快速開始」,並成功看到第一次呼叫(見 預期結果)
- 依 建立自己的 Client App 完成步驟 1–3,取得 active 的 public Client ID,填入
.env;Lab 01 複核設定 - (選做 Lab 04 帳號隔離)課前準備第二個可登入的練習帳號;沒有第二帳號可跟看講師示範,不影響主課驗收
- (選做,要自己操作 Lab 06 才需要)依 Lab 06 課前建置 在自己電腦 build 一次映像
Lab 06 使用 Docker Compose v2 以上與 Python 3 設定產生器。Kong 與 backend 映像沒有預先發佈,要自行操作的學員需安裝並啟動 Docker Engine/Docker Desktop(含 Compose),並在課前於自己電腦完成一次 build,現場不應依賴網路建置;不操作的學員可跟看講師展示。
快速開始
1. 取得程式碼並設定環境變數
git clone https://github.com/go-training/mcp-oauth2-workshop.git
cd mcp-oauth2-workshop
cp .env.example .env
chmod 600 .env
編輯 .env:
| 變數 | 怎麼填 |
|---|---|
SIGNET_ISSUER |
保持預設 https://signet.wu-boy.com(結尾不要加斜線) |
OAUTH_CLIENT_ID |
填入你自己的 Client App ID(課前建立並確認 active 後取得);設定尚未完成時可先用講師提供的備援 ID |
GATEWAY_SHARED_SECRET |
先留空,Lab 06 才使用 |
每開一個新終端都要重新載入
.env,否則 Lab 會讀不到設定:cd mcp-oauth2-workshop # 一律在 repo 根目錄執行 set -a; source .env; set +a
scripts/不會自動讀取.env,所以每個終端都要自己載入。
2. 安裝依賴(選一種語言)
# Go
(cd go && go mod download)
# 或 Python
uv sync --project python --frozen
3. 啟動 Lab 01 並呼叫看看
終端 A — 啟動 Server(保持執行):
./scripts/lab.sh 01 go # 或:./scripts/lab.sh 01 python
終端 B — 另開一個終端,載入 .env 後呼叫:
./scripts/oauth.sh go call --token-file .tokens/anonymous.json
# Python 路線:./scripts/oauth.sh python call --token-file .tokens/anonymous.json
兩種語言的 Server 都使用 port 8000,同一時間只能跑一個。要換語言或換關,請先在終端 A 按
Ctrl-C停掉舊的。記憶體中的筆記會隨之清空,這是正常的。
預期結果
終端 B 成功呼叫並印出 MCP 工具回應,代表環境就緒。如果失敗,先看 故障排除(常見原因:忘了載入 .env、port 8000 被占用、沒有在 repo 根目錄執行)。
提示:用 fx 看 JSON。
metadata指令輸出的是 JSON(Go 版為單行),可以 pipe 給 fx 互動瀏覽、展開與搜尋:./scripts/oauth.sh go metadata | fx # 只看某個欄位:./scripts/oauth.sh go metadata | fx .token_endpoint
call的輸出前面帶有 HTTP status code 與WWW-Authenticate,不是純 JSON,無法直接 pipe 給 fx。
之後依 Claude Code / Codex CLI 設定 把 AI CLI 連上你的 Server,再從 Lab 01 開始。
課程路線
主課順序為 01 → 02 → 03 → 04 → 06;保留原編號,Lab 05 為課後選修。每一關都可以獨立啟動,不依賴前一關對程式碼的修改。只有 Lab 04 會同時開 A/B 兩個 Server。
| Lab | 你要做什麼 | 完成的標準 | 時間 |
|---|---|---|---|
| 01 | 呼叫沒有授權的 MCP;複核課前建立的 public Client App | 工具呼叫成功(因為沒有保護);App active 且設定完整(或備援 ID 就緒) | 10 分 |
| 02 | 從 401 一路追到 Protected Resource Metadata,再到 Signet metadata | 能說出「Client 怎麼知道要去哪裡登入」 | 15 分 |
| 03 | PKCE 登入,並看 Server 如何驗 Token | 登入後呼叫成功;知道驗了簽章、issuer、audience、expiry、access type | 25 分 |
| 04 | 觀察 scope 與 resource 隔離 | 缺少寫入權限被擋;A 的 Token 打不進 B | 20 分 |
| 06 | 把入口授權交給 Kong Gateway | 對照「Server 自己授權」與「Gateway 集中授權」的差異 | 10 分 |
主課實作共 80 分鐘,另留 5 分鐘排錯緩衝與最後 5 分鐘 Q&A。
Lab 04 的第二帳號隔離為選做;Lab 06 主課只做啟動/入口檢查、成功呼叫與 read-only 寫入拒絕,跨 audience 與網路邊界檢查留作延伸。未完成 Docker 課前準備者跟看講師示範。
課後進階選修:Lab 05:撤銷同一顆 Token,沿用既有 public Client 練習撤銷,不需 secret 或額外 App,不列入主課驗收。
Token 撤銷後,本地驗 JWT 的 Server 不一定立即知道;需要即時撤銷時,再進一步研究 introspection。
關於你的 Client App:Signet 可自行填入 notes scopes 與 allowed resources,註冊頁明示立即啟用。課前建立後,Lab 01 務必重新開啟詳情/編輯頁複核,Lab 03 使用自己的 ID。若現場顯示 pending 或設定有問題,請助教協助,必要時使用備援 ID。
先備概念速查
不熟這些詞也沒關係,Lab 會逐一示範。
| 名詞 | 一句話 |
|---|---|
| Authorization Server (Signet) | 負責讓你登入、發 Token 的服務 |
| Resource Server (MCP Server) | 持有資料/工具,收到 Token 後決定放不放行 |
| Client (Claude Code / Codex) | 代表你去登入、帶 Token 呼叫 MCP 的程式 |
| PKCE | 防止授權碼被攔截後冒用的機制,public Client 沒有 secret 時必備 |
| scope | Token 被允許做的事,如 notes:read、notes:write |
| audience / resource | Token 是發給哪一個 Server 用的,A 的 Token 不能拿去打 B |
| JWKS | Server 用來驗證 Token 簽章的公鑰集合 |
架構
flowchart TD
C[Claude Code / Codex CLI] -->|登入、同意授權、PKCE| S[Signet HTTPS]
C -->|主課 Labs 01–04:HTTP MCP| M[筆電上的 Go 或 Python MCP Server]
M -->|metadata / JWKS| S
C -->|Lab 06| K[Kong + mcp-oauth2 plugin]
K -->|私有網路、可信任身分| B[MCP Backend:保留工具授權]
K -->|JWKS| S
Client、Authorization Server、Resource Server 各自有清楚的責任。登入永遠由 Client 自己完成,Kong 不會代替使用者登入。Kong 只在主課最後的 Lab 06 出現,Lab 01–04 與課後選修 Lab 05 不需要安裝。
程式碼怎麼讀
這是完整可執行的完成版。你的任務不是手刻 OAuth 或 JWT,而是修改設定、觀察請求,並驗證各種拒絕情境。每關的 README 會標出該閱讀哪些函式。
| 內容 | Go | Python |
|---|---|---|
| 六個可執行 Lab 入口 | go/labs | python/labs |
| MCP 與授權實作(共用) | server.go | server.py |
| PKCE / MCP 呼叫 / 撤銷的參考 Client | oauth/main.go | oauth.py |
Server 提供三個工具:whoami、list_notes、create_note。筆記只存在記憶體、依使用者隔離,不涉及真實資料。
卡住了怎麼辦
- 先查 故障排除。
- 確認這四件事:在 repo 根目錄、已載入
.env、舊的 Server 已Ctrl-C、SIGNET_ISSUER沒有結尾斜線。 - 舉手找助教,並告訴他:你在第幾關、執行了什麼指令、看到什麼錯誤(不要貼完整 Token)。
- 如果 Claude Code / Codex 的瀏覽器登入有狀況,可改用參考 Client(
./scripts/oauth.sh)完成該關練習。
安全注意事項
- Token 檔案權限為 0600 且已被 Git 忽略。不要把完整 Token 貼進聊天、截圖或投影片。
.env含有憑證,不要提交。- 課後請只移除這次新增的 workshop MCP 設定,不要動到其他專案的 server 設定。
設計取捨(進階,可課後閱讀)
- 授權與 MCP 傳輸層皆以 2026-07-28 為準:授權流程(discovery、PKCE、
resource參數、iss檢查、scope 與 403insufficient_scope)照授權規範;傳輸層已取消initialize交握,每個請求都帶MCP-Protocol-Version、Mcp-Method、Mcp-Name與_meta。Go 使用 go-sdk v1.8.0(Stateless: true),Python 使用mcp2.3.0(stateless_http=True)。Claude Code / Codex CLI 的實際連線與工具呼叫結果見驗證紀錄;Client 可能使用 SDK 提供的舊版相容路徑,不能只憑 Connected 推論所用協定版本。 - 參考 Client 依 RFC 9207 檢查回呼的
iss:Signet 宣告authorization_response_iss_parameter_supported時,缺少iss就拒絕;有iss時必須與記錄的 issuer 完全相同。 - Lab 01 刻意沒有授權;Lab 02 刻意只回 discovery challenge、尚不接受 Token。這兩關是明確的教學中間狀態,不是 bug。
- Labs 03–05 使用 RS256 + JWKS,這是本教材的選擇,MCP 規範並未強制使用 JWT。所有受保護關卡從一開始就驗證 audience。
- Signet access token 必須是
type=access,refresh token 或 ID token 不能呼叫 MCP。 - 課後選修 Lab 05 以 public Client ID 撤銷 access token;Server 入口沿用 Lab 04 的離線 JWT 與 scope 檢查,不查詢 introspection。
- Lab 06 的 Kong plugin 是離線 JWT 驗證,不保證即時得知撤銷狀態。實務上需決定在哪一層提供撤銷檢查,Gateway 不會自動解決所有授權問題。
notes:read控制入口,notes:write控制寫入工具;MCP Server 始終保留工具與資料的業務權限。- 本機範例僅允許 loopback HTTP,遠端 issuer 一律 HTTPS。
ALLOW_INSECURE_ISSUER=1只供本機測試 fixture,不能用來跳過遠端 TLS。 - Device Flow 列為後續延伸主題,不在主課內。
文件與驗證
- 登入 Signet、建立自己的 Client App
- Claude Code / Codex CLI 設定
- 故障排除
- 驗證紀錄:真實 Signet、兩套 AI CLI 登入與 Kong 容器的彩排狀態。本機測試通過不等於現場整合已完成。
想確認本機環境沒問題,可以跑自動測試(不需要現場帳密):
./scripts/check.sh
它會啟動 Go / Python 的六個 Lab 與本機測試用 issuer,涵蓋協定呼叫、PKCE、錯誤 Token、scope、audience、使用者隔離、public Client 撤銷及離線驗證限制與 Gateway 信任邊界。
GitHub Actions 在 push、pull request 或手動執行時,會分別跑 Go 格式檢查、go vet 與 go test -race,以及 Python lint、pytest 和兩種 Compose profile 驗證。pytest 會同時測試 Go / Python,因此測試環境需要兩種語言。
獨立的 Trivy workflow 會在 push、pull request 或手動執行時,掃描 repository 的 Go / Python 相依套件漏洞與 secrets;發現 HIGH 或 CRITICAL 問題即失敗,包含尚無修復版本的漏洞。結果顯示於 Actions log,可透過上方 Trivy badge 獨立追蹤;此掃描不涵蓋建置後的容器映像。
其他可替代的 IdP
本課使用 Signet,課後若想自架 Authorization Server,以下方案可作為參考:
| 方案 | 語言 | 特色 |
|---|---|---|
| Keycloak | Java | 最常被推薦的全功能方案,內建使用者管理、登入頁與管理介面,支援 SAML、LDAP 等企業整合。 |
| Ory Hydra | Go | 通過 OpenID 認證的 OAuth2 / OIDC provider,採 headless API,本身不含使用者管理,登入與同意頁需自行接上(例如 Ory Kratos 或既有帳號系統)。v25.4.0 起正式支援 Device Authorization Grant(RFC 8628),但驗證碼輸入頁需自行實作。 |
| ZITADEL | Go | 通過 OpenID 認證的全功能方案,內建可自訂的登入頁、自助註冊與管理介面,原生支援多租戶(Organization / Project),並支援 SAML 2.0、LDAP 與 Device Authorization Grant。後端使用 PostgreSQL,授權為 AGPL-3.0。 |
換用其他 IdP 時,請確認它支援本課依賴的能力:PKCE、RFC 8707 resource 參數(audience 綁定)、Authorization Server Metadata,以及 RFC 9207 回呼 iss。
參考
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi