Stop Letting Every MCP Server Collect Its Own PAT: A Unified OAuth2 Front Door with Kong + AuthGate

cover

Once MCP (Model Context Protocol) exploded inside the company, almost every team ended up running an MCP server or two of their own: one fronting Gitea, one for Sentry, one for the internal Wiki, one for a database. They’re genuinely useful — but there’s a question everyone collectively ignored: how do these MCP servers actually authenticate?

The answer is usually unsettling: each one collects its own PAT (Personal Access Token). Every MCP server defines its own token, stuffs it into an environment variable, and validates it itself. So the company quietly accumulates a pile of static tokens — “long-lived, sitting in a file, equivalent to someone’s account” — scattered across dev machines, CI, even pasted into Slack messages. This post is about using Kong together with AuthGate to put a single OAuth2 front door in front of every MCP server and clean up that PAT sprawl in one move.

The full example code lives in go-authgate/kong-mcp-oauth2. This post walks through the motivation, the architecture, the security considerations, and the actual verification steps.

[Read More]

別再讓 MCP Server 各自收 PAT:用 Kong + AuthGate 做企業統一 OAuth2 入口

cover

MCP(Model Context Protocol) 在公司內部爆量之後,幾乎每個團隊都自己跑了一兩個 MCP Server:接 Gitea 的、接 Sentry 的、接內部 Wiki 的、接資料庫的。它們很好用,但有一個被集體忽略的問題——這些 MCP Server 到底是怎麼認證的?

答案多半令人不安:各自收各自的 PAT(Personal Access Token)。每個 MCP Server 自己定義一套 token、自己塞進環境變數、自己驗。於是公司內部出現了一堆「長期有效、放在檔案裡、等同某個帳號權限」的靜態 token,散落在開發機、CI、甚至貼在 Slack 訊息裡。這篇文章要談的,就是怎麼用 Kong 搭配 AuthGate,在所有 MCP Server 前面架起單一的 OAuth2 入口,把這堆 PAT 一次收掉。

完整的範例程式碼在 go-authgate/kong-mcp-oauth2,本文會帶你走過設計動機、架構、安全考量到實際驗證。

[Read More]

Letting Claude Code Talk to Jira Safely: OAuth Login and Refresh Tokens in the New go-jira

cover

More and more developers let AI CLI tools like Claude Code run commands, look things up, and tidy up afterwards right on their own development machines. Wiring that AI workflow into Jira makes it even more powerful: the AI can look up issues, update statuses, leave comments, and map commit messages back to tickets. The star of this post, go-jira (https://github.com/appleboy/go-jira), is a Jira CLI built for exactly this scenario. But there’s a security question that keeps getting underrated — how does the CLI authenticate to Jira?

The most common answer historically is a PAT (Personal Access Token). It’s simple, but on an AI development machine it carries two very real risks:

  1. The AI can read it by accident. A PAT usually lives in .env, a shell rc file, or some config file. The moment you let an AI agent “freely explore the filesystem” on that machine, this long-lived token — which carries your full account permissions — can get pulled into the context, or even written out into some piece of output.
  2. A file that lives forever is an exposure surface that lives forever. A PAT doesn’t rotate. Once leaked, it stays valid until you manually revoke it. We’ve all heard the stories: synced to the cloud, swept into a backup, accidentally committed into a repo.

That’s why “switching CLI auth from a PAT to Jira OAuth” has been pulled back into the spotlight lately. This post documents how the new go-jira uses OAuth Login + refresh tokens to tuck tokens into the operating system’s Keyring, so developers can obtain a token conveniently and store it safely — and so AI CLIs like Claude Code can interact with Jira in a much safer way.

Note: go-jira’s OAuth only supports Jira Data Center, not Jira Cloud (the two use different OAuth flows).

[Read More]

讓 Claude Code 安全地操作 Jira:go-jira 新版 OAuth 登入與 Refresh Token 實戰

cover

越來越多開發者習慣在自己的開發機上,讓 Claude Code 這類 AI CLI 工具幫忙跑指令、查資料、收尾善後。把這條 AI 工作流接到 Jira 之後,威力更大:AI 可以幫你查 issue、更新狀態、補留言、把 commit 訊息對應到工單。本文的主角 go-jirahttps://github.com/appleboy/go-jira)正是為了這個場景打造的 Jira CLI。但這裡有一個一直被低估的安全議題——CLI 要怎麼跟 Jira 認證?

過去最常見的做法是 PAT(Personal Access Token)。它確實簡單,但放在 AI 開發機上有兩個很實際的風險:

  1. AI 可能不小心讀到它:PAT 通常被塞在 .env、shell rc、或某個設定檔裡。當你讓 AI agent 在這台機器上「自由探索檔案」時,這顆等同你帳號權限的長期 token 很可能就被讀進 context、甚至被寫進某段輸出裡。
  2. 以檔案形式長期存在 = 長期暴露面:PAT 不會自動輪替,一旦外洩,在你手動撤銷之前它都是有效的。檔案被同步到雲端、被備份、被誤 commit 進 repo 的故事,大家都聽過。

所以「把 CLI 認證從 PAT 換成 Jira OAuth」這件事,最近被重新拉出來重視。這篇文章記錄 go-jira 新版本如何用 OAuth Login + Refresh Token 把 token 收進作業系統的 Keyring,讓開發者很方便地拿到、並且安全地保存 token,進而讓 Claude Code 等 AI CLI 能以更安全的方式跟 Jira 互動。

注意:go-jira 的 OAuth 只支援 Jira Data Center,不支援 Jira Cloud(兩者是不同的 OAuth 流程)。

[Read More]

Vibe Coding Team Guideline: Holding the Line on SDLC Discipline in the AI Coding Era

cover

Over the past year, the phrase “I wrote it with AI” has gone from “worth mentioning” to “weird if you didn’t” in pull request descriptions. Anthropic internally merged a single PR of 22,000 lines — largely produced by Claude, landing in their production reinforcement-learning codebase. When that story spread, most engineers didn’t react with awe; they reacted with anxiety: if they can pull that off, what’s stopping the wave of “PMs opening Claude Code and writing production code” from hitting our team?

You can’t stop it. But you can manage it. This post is the SDLC guideline I wrote for my own team after working through Erik Schluntz’s talk Vibe coding in prod | Code w/ Claude (Erik is a coding-agent researcher at Anthropic and co-author of Building Effective Agents). The whole thesis is one sentence: enjoy the AI speedup without sacrificing code quality, maintainability, system reliability, or security.

[Read More]

Vibe Coding 團隊規範:在 AI 編程時代守住 SDLC 的工程紀律

cover

過去一年,「我用 AI 寫的」這句話在 Pull Request 描述裡出現的頻率,已經從「值得一提」變成「沒寫才奇怪」。Anthropic 內部曾合併過一個 22,000 行、由 Claude 大量產出、最後跑進正式環境強化學習程式碼庫的 PR——這件事傳出來的時候,多數工程師的第一反應不是讚嘆,而是焦慮:如果他們做得到,那我們團隊憑什麼擋得住「PM 直接開 Claude Code 寫 production code」的浪潮?

擋不住。但可以管好。這篇文章是我整理 Erik Schluntz(Anthropic 編程智能體研究員、《Building Effective Agents》共同作者)演講「Vibe coding in prod | Code w/ Claude」之後,為自己團隊寫的一份 SDLC 規範。核心命題只有一句:在享受 AI 加速的同時,不犧牲程式品質、可維護性、系統穩定性與資安

[Read More]

A Kubernetes Login Story for Small Teams: Building an OIDC Identity Gateway with kubelogin + AuthGate on k3s

cover

Most teams meet Kubernetes for the first time through a single “superuser” kubeconfig — a file with credentials that can wipe out the entire cluster. It then starts bouncing around Slack, email, and laptops, and nobody can say for sure who still has a copy, or whether the kubeconfig belonging to a former employee is still usable.

This post shows how to use kubelogin together with AuthGate to stand up an OIDC login flow on k3s: the moment a user runs kubectl get pods, the browser pops open AuthGate’s login page, the tokens land back in the kubeconfig, and the entire cluster no longer needs that shared admin.kubeconfig.

[Read More]

小團隊的 Kubernetes 登入方案:用 kubelogin + AuthGate 打造 OIDC 身份閘道(以 k3s 為例)

cover

大部分團隊第一次裝 Kubernetes 時,拿到的都是一個「超級使用者」的 kubeconfig,裡面就躺著一組可以幹掉整個叢集的憑證。於是這份檔案開始在 Slack、Email、筆電之間被複製來複製去,沒有人知道目前誰還留著副本、哪個離職員工的 kubeconfig 還能用。

這篇文章要示範如何用 kubelogin 搭配 AuthGate,在 k3s 上建立一條 OIDC 登入流程:使用者打 kubectl get pods 的瞬間,瀏覽器自動跳出 AuthGate 的登入頁面,登入完成 token 寫回 kubeconfig,整個叢集不再需要共用那份 admin.kubeconfig

[Read More]

Optimizing Gitea Act Runner Connection Load: Reducing from 1,300 req/s to 170 req/s

cover

Gitea Act Runner is the execution component of Gitea Actions, responsible for fetching CI/CD tasks from the Gitea Server and reporting execution results. As more teams self-host Gitea, the HTTP request volume between Runners and the Server has become a bottleneck on the Server side. This article documents how we analyzed and resolved this problem, reducing the request volume from approximately 1,300 req/s to approximately 170 req/s for 200 Runners — an 87% reduction.

Update (2026-04-20): This article originally described the design after PR #819 merged. A follow-up, PR #822, revealed during code review that #819 had introduced a concurrency regression for Runners with capacity > 1, and addressed it with a “single poller + semaphore” architecture. See the new section at the end: Follow-up: Single Poller with Semaphore (PR #822).

[Read More]

Gitea Act Runner 連線負載優化:從 1,300 req/s 降到 170 req/s 的實戰紀錄

cover

Gitea Act Runner 是 Gitea Actions 的執行元件,負責從 Gitea Server 領取 CI/CD 任務並回報執行結果。隨著越來越多團隊自架 Gitea,Runner 與 Server 之間的 HTTP 請求量成為了 Server 端的瓶頸。本文記錄我們如何分析並解決這個問題,將 200 個 Runner 的請求量從約 1,300 req/s 降到約 170 req/s,降幅 87%。

更新(2026-04-20):本文原本描述 PR #819 合併後的設計。後續 PR #822 在 code review 中揭露 #819 對 capacity > 1 的 Runner 引入了一個 concurrency regression,並用「單一 poller + semaphore」架構再次修正。請見文末〈後續修正:Single Poller with Semaphore(PR #822)〉章節。

[Read More]