JSPM

@bluelamp/auth-sdk

0.1.1
    • ESM via JSPM
    • ES Module Entrypoint
    • Export Map
    • Keywords
    • License
    • Repository URL
    • TypeScript Types
    • README
    • Created
    • Published
    • Downloads 193
    • Score
      100M100P100Q70417F
    • License MIT

    BlueLamp 外部API連携MCP認証SDK: JWKS キャッシュ付き JWT 検証 Express ミドルウェアを提供する

    Package Exports

    • @bluelamp/auth-sdk
    • @bluelamp/auth-sdk/dist/index.js

    This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@bluelamp/auth-sdk) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

    Readme

    @bluelamp/auth-sdk

    BlueLamp 外部API連携 MCP 認証基盤(Phase 31)の検証側 SDK。

    • BlueLamp が発行した短命 JWT を JWKS で検証する Express ミドルウェア
    • aud / iss / exp / 署名 / scope を自動チェック
    • JWKS は内部で 1 時間キャッシュ(jwks-rsa
    • 起動時に jwksUri / audience の HTTPS 強制(開発時 localhost 例外)

    インストール

    npm install @bluelamp/auth-sdk

    Node.js 18+ が必要です。

    クイックスタート(Express)

    import express from 'express';
    import { bluelampAuth } from '@bluelamp/auth-sdk';
    
    const app = express();
    
    app.use('/api/contracts', bluelampAuth({
      jwksUri: 'https://motohi-api-235426778039.asia-northeast1.run.app/.well-known/jwks.json',
      audience: 'https://mikoto-company-api-235426778039.asia-northeast1.run.app',
      requiredScope: 'contract:read',
    }));
    
    app.get('/api/contracts', (req, res) => {
      // req.user は検証済み BlueLamp JWT payload
      res.json({
        customer: req.user?.sub,
        tenant: req.user?.['bl:tenant_id'],
        tenant_rank: req.user?.['bl:tenant_rank'],
      });
    });

    JWT が欠落・署名不正・期限切れなら 401requiredScope 未満なら 403 insufficient_scope

    Fastify(@fastify/express 経由)

    Fastify は Express ミドルウェアを @fastify/express プラグインでそのまま利用できます。

    import Fastify from 'fastify';
    import expressPlugin from '@fastify/express';
    import { bluelampAuth } from '@bluelamp/auth-sdk';
    
    const app = Fastify();
    await app.register(expressPlugin);
    
    app.use('/api/contracts', bluelampAuth({
      jwksUri: process.env.BLUELAMP_JWKS_URI!,
      audience: process.env.API_AUDIENCE!,
      requiredScope: 'contract:read',
    }));
    
    app.get('/api/contracts', async (req) => ({
      customer: (req.raw as any).user?.sub,
    }));

    Hono(Node.js アダプタ経由)

    Hono の Node.js アダプタは Express 互換の middleware を受け取れません。そのため Hono では jsonwebtoken + jwks-rsa を直接使うか、SDK 内部の createJwksResolver を流用してください。将来的に Hono 向けヘルパーを追加予定です。

    暫定例:

    import { Hono } from 'hono';
    import { bearerAuth } from 'hono/bearer-auth';
    import jwt from 'jsonwebtoken';
    import jwksClient from 'jwks-rsa';
    
    const keys = jwksClient({
      jwksUri: process.env.BLUELAMP_JWKS_URI!,
      cache: true,
      cacheMaxAge: 60 * 60 * 1000,
    });
    
    const app = new Hono();
    app.use('/api/contracts/*', async (c, next) => {
      const token = c.req.header('Authorization')?.replace(/^Bearer\s+/, '');
      if (!token) return c.json({ error: 'missing_token' }, 401);
      try {
        const payload = await new Promise((resolve, reject) => {
          jwt.verify(
            token,
            (header, cb) => {
              if (!header.kid) return cb(new Error('missing kid'));
              keys.getSigningKey(header.kid, (err, key) => {
                if (err) return cb(err);
                cb(null, key!.getPublicKey());
              });
            },
            { audience: process.env.API_AUDIENCE, algorithms: ['RS256'] },
            (err, decoded) => (err ? reject(err) : resolve(decoded)),
          );
        });
        c.set('user', payload);
      } catch (e) {
        return c.json({ error: 'invalid_token', message: (e as Error).message }, 401);
      }
      await next();
    });

    Options

    フィールド 必須 説明
    jwksUri string JWKS エンドポイント URL。https:// 必須(localhost は dev のみ)
    audience string 外部 API 自身の audience。JWT aud と厳密一致
    requiredScope string - このエンドポイントで必須の scope。未指定なら scope チェックをスキップ
    cacheMaxAge number - JWKS キャッシュ TTL(秒)。default 3600
    issuer string - iss 一致検証。未指定なら検証しない

    エラーレスポンス

    HTTP body.error 発生ケース
    401 missing_token Authorization ヘッダ欠落
    401 invalid_token 署名不正 / 形式不正 / aud 不一致 / iss 不一致
    401 token_expired exp 経過
    401 token_not_active nbf 未到達
    403 insufficient_scope requiredScope が JWT scope に含まれない

    起動時バリデーション(§11.8 HTTPS 強制)

    bluelampAuth() は呼ばれた時点で以下を検証し、不正なら BluelampAuthConfigError を throw してサーバー起動を止めます:

    • jwksUrihttps:// で始まる(例外: NODE_ENV=development かつ host が localhost / 127.0.0.1 / [::1]
    • audiencehttps:// で始まる(同上)

    本番環境で誤って http:// を設定した場合、アプリ起動時に即エラーになるのでサイレント失敗を防げます。

    動作確認

    BlueLamp portal のリポジトリ内:

    cd packages/auth-sdk
    npm run smoke

    motohi-api の live JWKS / Token Exchange と統合確認します(CLI_TOKEN 環境変数が必要)。

    ライセンス

    MIT