Slack Bot用の認証付きMCPを作成する
概要
弊社ではResponses APIをつかって社内用のSlack Botを構築しています。
今回、この Bot に自作の Remote MCP を組み込み、社内 Slack の情報取得・集約を行う機能を追加する構想を検討しました。
ただし、Remote MCP のエンドポイントは Responses API からアクセスする都合上 publicに公開せざるを得ず、以下の懸念点が生じます。
- Slack Bot 以外からもアクセス可能になる
- 認証情報が漏洩した場合、社内 Slack 情報に不正アクセスされる可能性がある
これらのリスクに対処するため、以下の構成を設計しました。
インフラ
今回採用したアーキテクチャは以下の通りです。
- Secret Manager に Remote MCP 用の認証トークンを保存。トークンは一定期間でローテーションする
- 社内 Bot (Lambda) は Secret Manager から Remote MCP 用トークンを取得し、Slack Access TokenとともにResponses APIにツール登録
- Responses API は Remote MCP 認証トークンとSlack Access Tokenをヘッダーに付与してRemote MCPにリクエスト送信
- Remote MCP 側も Secret Manager から同一のトークンを取得し、ヘッダーに付与された値と照合。一致すれば処理を実行
- 実際の処理はヘッダーに渡された Slack Access Token を用いて実行
メリット
1.認証トークンは定期的にローテーションされ、かつ AWS 内でのみ取得可能なため、セキュリティが強化される。
2. 万が一認証トークンが漏洩しても、Slack Access Token は Lambda 内に保持されるため、社内情報への直接的なアクセスは不可能。
実装
認証処理
/mcp
エンドポイントに対して、認証処理を挟みます。
app.post('/mcp', authenticate, async (req, res) => {
await transport.handleRequest(req, res, req.body);
});
authenticate
関数では、Secret Manager から取得したトークンとヘッダーを突き合わせます。
export const authenticate = async (req: express.Request, res: express.Response, next: express.NextFunction) => {
const accessToken = req.headers['mcp-access-token'] as string;
if (!accessToken) {
return res.status(400).json({
jsonrpc: '2.0',
error: {
code: -32602,
message: 'mcp-access-token ヘッダーが必要です',
},
id: null,
});
}
const command = new GetSecretValueCommand({
SecretId: 'authenticate-key'
});
const secretResponse = await secretsManagerClient.send(command);
const expectedToken = secretResponse.SecretString;
if (!expectedToken || accessToken !== expectedToken) {
return res.status(400).json({
jsonrpc: '2.0',
error: {
code: -32602,
message: '無効なアクセストークンです',
},
id: null,
});
}
next();
};
処理実行側
処理実行側ではextra.requestInfo.headers
からヘッダーを取得し、Slack API 呼び出しに利用します。
server.tool(
"search-slack-messages",
"Slackメッセージを検索する",
{query: z.string().describe("検索クエリ")},
async (args, extra) => {
// ヘッダーの取得と検証
const slackUserToken = extra.requestInfo.headers['slack-user-token'];
// 残りの処理
}
);
まとめ
本記事では、Slack Bot から Remote MCP を利用する際の セキュリティ設計パターンを一例として紹介しました。
Remote MCP では一般的に OAuth 2.1 の利用が推奨されていますが、Bot 連携を前提とした場合の標準的なパターンは未だ確立されていません。
今回の方式は、トークンローテーションと多段階のキー管理によって堅牢性を確保しつつ、漏洩時の被害を最小化できる点が特徴です。
もし、さらに洗練された構成やセキュリティパターンをご存知でしたら、ぜひ共有いただけると幸いです
Bizibl では開発エンジニアを絶賛採用しています!カジュアル面談に興味がある方はこちらから!
Discussion