開発者フレンドリー · ヘッドレス · Apache 2.0
OAuth 2.1とOpenID Connectを、自分たちの手で。
人、サービス、AIエージェントのための、標準仕様を第一に考えた認可サーバーです。個人のサイドプロジェクトから公的IDの大規模導入まで対応します。設計からヘッドレスで、Interaction API(OpenAPI 3.1、型付きクライアント)の上に独自のログイン画面を作ることも、リファレンスの画面を使うこともできます。PKCEの全面適用、RFC 8693の委任、MCP認可プロファイル、フラグで有効化できるML-DSA-65ハイブリッド署名に対応します。Fastify上のTypeScriptで実装し、PostgreSQLとRedisを使用します。
# Docker 23+(Compose 2)とOpenSSLが必要
❯ git clone https://github.com/qauth-labs/qauth.git && cd qauth
❯ cp .env.docker.example .env
# .envにJWT_PRIVATE_KEY、JWT_PUBLIC_KEY、KEK、DB_PASSWORDを追加
❯ docker compose up -d
❯ curl http://localhost:3000/ready
各値の生成方法はDockerガイドをご覧ください。
現在提供している機能
機能一覧
全機能の一覧と、各スイッチで有効になる内容はステータスページにまとめています。既定でオフ:WALLET_FEDERATION_ENABLED、HYBRID_SIGNING_ENABLED、ID_JAG_ENABLED(エンタープライズ管理の認可)、DPOP_ENABLED(RFC 9449)。
エージェントネイティブな認可
エージェント用のクライアントタイプ、actクレーム付きのRFC 8693 on-behalf-ofトークン交換、クライアントごとに上限を設けるReadOnly / Admin / Execのスコープモード、危険な操作の前のステップアップ認証、エージェントごとの監査ログ。MCPに限らず、あらゆるAPIを呼び出すあらゆるエージェントに使えます。
MCP認可プロファイル
リビジョン2026-07-28:RFC 9728の保護リソースメタデータ、RFC 7591をフォールバックとするClient ID Metadata Documents、オーディエンスバインディング、ステップアップ認証のチャレンジ。リソースサーバー側は@qauth-labs/resource-guardが担います。
OAuth 2.1とOpenID Connectのコア機能
PKCE必須の認可コードフロー、client_credentials、ローテーションするリフレッシュトークン、ディスカバリー、JWKS、IDトークン、userinfo、イントロスペクション、失効(revocation)、RFC 8707のリソースインジケーター、RP-Initiated Logoutとバックチャネルログアウト。
耐量子ハイブリッド署名
既定はEd25519。フラグ1つで、ML-DSA-65 + Ed25519のハイブリッド署名と、AKP+OKPの混在JWKSが加わります。耐量子署名の部分はイントロスペクション経由で提供します。
セルフホスト、マルチテナント
独自のissuerとホストを持つレルム、クライアントとAPIキーを管理する開発者ポータル、暗号化された署名鍵。構造化ログ、Prometheusメトリクス、OpenTelemetryイベントは自社の監視基盤に送られ、当社には何も送信されません。
フェデレーション
現在は、レルムに設定した上流のOpenID Connectプロバイダー経由でログインできます。OID4VP 1.0とSD-JWT VCによるEUデジタルIDウォレットでのログインは、フラグで有効化する形で提供しています。モックウォレットでテスト済みで、実際のウォレットでの検証はまだ完了していません。
コアプロトコル
1つの認可サーバーで、 あらゆるクライアントに対応
エージェントが何かを委任する以前に、QAuthはまずOAuth 2.1とOpenID Connectのサーバーです。ユーザーにはPKCE(S256)必須の認可コードフロー、サービスにはclient_credentials。さらに、リプレイを検知するとファミリーごと失効するローテーション式のリフレッシュトークン、ディスカバリー、JWKS、userinfo、イントロスペクション、失効(revocation)を備えます。インプリシットフローは提供せず、独自SDKも不要です。エージェントの委任とMCPへの対応も、この同じコアの上に成り立っています。
エージェントの認可
動くのはエージェント。 責任を持つのは認可サーバー。
エージェントの認証・認可は、ユーザー認証に手順を足しただけのものではありません。トークンには「ユーザーYの代わりに動くエージェントX」であることを示す必要があるため、RFC 8693のトークン交換で、actクレーム付きの委任トークンを発行します。また、エージェントはクライアントIDを発行してもらうためのチケットも起票できないので、Client ID Metadata Documents(フォールバックはRFC 7591)を使い、機械の速さで自ら登録します。開発用のエージェントが本番環境に届くことはありません。環境がポリシーの軸の1つだからです。これらはすべて現在提供中で、MCPサーバーの前でも、通常のREST APIの前でも同じように動作します。
導入
開発の邪魔をしない、認証・認可
MCPでも通常のRESTでも、リソースサーバーを標準に基づくOAuth 2.1で保護できます。RFC 9728によるディスカバリー、メタデータドキュメントによるクライアント登録、PKCEに対応。SDKは任意で、どのOAuthライブラリでも動作します。
QAuthを起動する
Docker Composeがイメージのビルドとマイグレーションを行い、PostgreSQL 18とRedis 7とともに認可サーバーを起動します。コマンドは上のクイックスタートにあります。
リソースサーバーを保護する
MCPサーバーでは@qauth-labs/resource-guardを登録し、通常のREST APIではJWKSを使ってBearerトークンを自分で検証します。どちらの場合も、トークンはオーディエンスに紐付いています。
クライアントをログインさせる
Claude CodeなどのMCPクライアントは、認可サーバーを検出し、Client ID Metadata Documentで登録して、PKCE付きのauthorization_codeを実行します。サービスの場合は、代わりにclient_credentialsを使います。
import Fastify from 'fastify'
import { resourceGuardPlugin } from '@qauth-labs/resource-guard/fastify'
const app = Fastify()
// Protect your MCP resource server: audience-bound tokens only
await app.register(resourceGuardPlugin, {
resource: 'https://mcp.yourapp.com',
authorizationServer: 'https://auth.yourapp.com',
requiredScopes: ['mcp:read'],
})
app.get('/mcp', { preHandler: app.requireBearer }, async (request) => {
// request.tokenClaims: verified signature, issuer, audience, scope
return { tools: listTools() }
})
// No token → 401 Unauthorized
// WWW-Authenticate: Bearer resource_metadata=
// "https://mcp.yourapp.com/.well-known/oauth-protected-resource"
// The MCP client (e.g. Claude Code) discovers your auth server from
// that document, registers via CIMD or RFC 7591, then runs
// authorization_code + PKCE for an audience-bound access token.
// Authorization: Bearer <token> → resource-guard verifies it → 200 OK
# Plain OAuth 2.1: no MCP, no agent, just your service
❯ curl -X POST https://auth.yourapp.com/oauth/token -d grant_type=client_credentials -d scope=documents:read
耐量子暗号
ML-DSA-65ハイブリッド署名を 現在提供中
署名処理は、アルゴリズムに依存しないインターフェースの背後にあります。SIGNING_ALGORITHM_MODE=ed25519+ml-dsa-65とHYBRID_SIGNING_ENABLED=trueを設定すると、QAuthはEd25519に加えてML-DSA-65でも署名し、混在JWKSを公開して、耐量子署名の部分をイントロスペクション経由で提供します。Ed25519しか知らない検証側も、そのまま動作し続けます。