mcpField
S
security-trust

security-trust

github.com/bartwaardenburgセキュリティ0176 回インストール1 週間前に更新
リポジトリ

security-trust について

IsAgentReady.com の「Security & Trust」チェック項目を修正するスキルです。サイト運営者向けに、セキュリティヘッダー、API の CORS、WebMCP ツール定義、フォーム動作、OAuth メタデータの確認と検証を案内します。

主な機能

  1. 01HTTPS とセキュリティヘッダーの修正
  2. 02API の CORS ポリシー設定
  3. 03WebMCP ツール定義の確認
  4. 04フォーム自動送信リスクの確認
  5. 05OAuth メタデータと認証情報の公開
  6. 06読み取り専用の検証コマンド

活用シーン

  1. 01Security & Trust スキャンの失敗項目への対応
  2. 02Web サーバーへのヘッダー追加
  3. 03オリジンによる API アクセス制限
  4. 04エージェント向けサイト認証の準備

MCP 対応

WebMCP ツール定義とエージェント認証の準備状況に関するセキュリティチェックを扱います。MCP サーバーではなく、修正を案内するスキルです。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/bartwaardenburg/isagentready-skills --skill security-trust

インストール後、Claude Code で/security-trustを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
checkpoints.md
gotchas.md
security-headers.md
server-configs.md

詳細

セキュリティと信頼性

IsAgentReady.com の「セキュリティと信頼性」カテゴリを改善します。これらのチェックポイントでは、エージェントプロトコルに必要なセキュリティの基本要件と、エージェントがサインインに使用する認証メタデータをテストします。

使用する場合

  • スキャンで「セキュリティと信頼性」に不合格(旧 ID 5.x)が表示される場合。
  • HTTPS、HSTS、CSP、その他のセキュリティヘッダーが設定されていない場合。
  • パブリック API に適切な CORS ポリシーが必要な場合。
  • WebMCP のツール定義に秘密情報が含まれているか、リスクのあるフォームが自動送信される場合。
  • サイトにログイン機能があり、エージェントが OAuth メタデータを見つける必要がある場合。

使用しない場合

  • robots.txt またはクローラーのアクセスについては、ai-content-discovery を使用してください。
  • JSON-LD については、structured-data を使用してください。
  • セマンティック HTML については、content-semantics を使用してください。
  • MCP、A2A、または OpenAPI ドキュメントについては、agent-protocols を使用してください。

手順

  1. スキャン結果から不合格のチェックポイントを取得します。各結果には旧 ID(5.3)と安定 ID(ia.hsts)があります。
  2. ヘッダーのチェックポイント(5.1~5.9)には、references/server-configs.md のサーバー設定を使用してください。これにより、すべてのヘッダーをまとめて修正できます。
  3. その他のチェックポイントについては、安定 ID と同じアンカーを持つ修正ワークフローに進んでください。
  4. example.com をサイトのドメインに置き換えます。検証コマンドを実行してください。すべての検証コマンドは読み取り専用です。
  5. isagentready results <domain> --checkpoint <stable-id> を使うか、isagentready.com で再スキャンします。

$ARGUMENTS が指定されている場合は、修正する URL またはチェックポイントとして使用してください。

チェックポイント

強度は agentready.org の仕様レベル(MUST、SHOULD、MAY)を示します。強度によってスコアは変わりません。

LegacyStable IDNameAR IDsStrength
5.1ia.httpsHTTPSnoneMUST
5.3ia.hstsHSTSnoneMUST
5.4ia.cspContent-Security-PolicynoneMUST
5.5ia.x-content-type-optionsX-Content-Type-OptionsnoneMUST
5.6ia.frame-protectionX-Frame-Options / frame-ancestorsnoneMUST
5.7ia.corsCORSnoneMAY
5.9ia.referrer-policyReferrer-PolicynoneMUST
5.10ia.tool-definition-securityTool definition securitynoneMAY
5.11ia.auto-submit-riskAuto-submit risknoneMAY
5.12ia.oauth-discoveryOAuth discoveryAR-ACT-01SHOULD
5.13ia.oauth-protected-resourceOAuth protected resourceAR-ACT-01SHOULD
5.14ia.agent-auth-readinessAgent auth readinessAR-ACT-01SHOULD

すべてのヘッダーを一括設定

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; frame-ancestors 'none'" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

always を使用すると、Nginx は 3xx、4xx、5xx のレスポンスにもヘッダーを送信します。Apache、Caddy、Vercel、Netlify、Cloudflare、Express、Next.js、Django の設定は references/server-configs.md にあります。

すべてのヘッダーを検証します:curl -sfI https://example.com/ | grep -iE '^(strict-transport|content-security|x-content-type|x-frame|referrer-policy)'

修正ワークフロー

5.1 HTTPS

リダイレクト後の最終 URL が、有効な証明書を使用した https:// であれば合格です。

  1. 証明書を取得します。Let's Encrypt と Nginx の場合:sudo certbot --nginx -d example.com -d www.example.com
  2. HTTP を HTTPS にリダイレクトします:
    server { listen 80; server_name example.com; return 301 https://$host$request_uri; }
    

検証:curl -sfI https://example.com/ | head -1

5.3 HSTS

Strict-Transport-Security の max-age が 31536000 以上の場合に合格します。includeSubDomains を指定すると、より高く評価されます。max-age が短い場合は部分的な評価となります。

  1. ヘッダーを追加します:add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
  2. すべてのサブドメインで HTTPS を使用している場合は、preload を追加し、hstspreload.org でドメインを申請します。

確認方法:curl -sfI https://example.com/ | grep -i '^strict-transport-security'

5.4 Content-Security-Policy

CSP に実際のディレクティブが含まれている場合に合格します。upgrade-insecure-requests だけを含む CSP は部分的な評価となります。

  1. まずレポート専用モードで開始し、サイトで必要なソースを確認します:
    add_header Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self' https://www.googletagmanager.com; report-uri /csp-report" always;
    
  2. レポートに問題がなくなったら、Content-Security-Policy に変更します。ノンスについては references/security-headers.md を参照してください。

確認方法:curl -sfI https://example.com/ | grep -i '^content-security-policy'

5.5 X-Content-Type-Options

値が正確に nosniff の場合に合格します。

  1. ヘッダーを追加します:add_header X-Content-Type-Options "nosniff" always;

確認方法:curl -sfI https://example.com/ | grep -i '^x-content-type-options: nosniff'

5.6 X-Frame-Options / frame-ancestors

X-Frame-Options が DENY または SAMEORIGIN であるか、CSP に frame-ancestors が含まれている場合に合格します。

  1. CSP に frame-ancestors 'none' を追加するか、add_header X-Frame-Options "DENY" always; を追加します。
  2. 信頼できるサイトがページを埋め込む必要がある場合は、frame-ancestors 'self' https://partner.example を使用します。ALLOW-FROM は使用しないでください。

確認方法:curl -sfI https://example.com/ | grep -iE '^x-frame-options|frame-ancestors'

5.7 CORS

4.19 で検証される公開 API 操作に適用されます。プリフライトと GET が一致する Access-Control-Allow-* ヘッダーを返し、認証情報とワイルドカードを併用せず、動的なオリジンには Vary: Origin を指定している場合に合格します。

  1. プリフライトと GET に同じポリシーで応答します:
    const allowed = new Set(["https://app.example.com", "https://agent.example"]);
    app.use("/api", (req, res, next) => {
      const origin = req.get("Origin");
      if (allowed.has(origin)) res.set({ "Access-Control-Allow-Origin": origin, Vary: "Origin" });
      res.set({ "Access-Control-Allow-Methods": "GET", "Access-Control-Allow-Headers": "Accept" });
      return req.method === "OPTIONS" ? res.sendStatus(204) : next();
    });
    
  2. Cookie を使用しない公開 API では、Access-Control-Allow-Origin: * が適切です。* と Access-Control-Allow-Credentials: true を決して併用しないでください。

確認方法:curl -sI -H 'Origin: https://agent.example' https://example.com/api | grep -iE '^(access-control-|vary)'

5.9 Referrer-Policy

Referrer-Policy が存在し、unsafe-url ではない場合に合格します。

  1. ヘッダーを追加します:add_header Referrer-Policy "strict-origin-when-cross-origin" always;

確認方法:curl -sfI https://example.com/ | grep -i '^referrer-policy'

5.10 ツール定義のセキュリティ

ページに WebMCP ツール定義がある場合に適用されます。定義にシークレット(JWT、API キー、トークン、カード番号、パスワード)が含まれず、名前が説明と一致し、読み取り専用ツールに readOnlyHint が設定されている場合に合格します。

  1. toolname、tooldescription、registerTool() コードから各トークンまたはキーを削除します。シークレットはサーバーで読み込みます。
  2. データを変更しないツールにマークを付けます:
    document.modelContext?.registerTool({
      name: "search_products",
      description: "Search the product catalog by keyword",
      annotations: { readOnlyHint: true },
      inputSchema: { type: "object", properties: { query: { type: "string" } }, required: ["query"] },
      execute: async ({ query }) => searchProducts(query),
    });
    

確認方法:curl -sf https://example.com/ | grep -ciE 'tool(name|description)="[^"]*(token|password|secret|api[_-]?key)'(0 が期待値です)

5.11 自動送信のリスク

ページにフォームがある場合に適用されます。toolautosubmit を持つフォームがないか、検索フォームとフィルターフォームだけが持つ場合に合格します。リスクのある操作は部分的な評価となります。自動送信が設定されたパスワード欄またはカード欄がある場合は不合格です。

  1. ログイン、支払い、削除、送信フォームから toolautosubmit を削除します。検索フォームではそのまま使用できます:
    <form action="/search" toolname="search_products" tooldescription="Search the catalog" toolautosubmit>
      <input name="q" toolparamdescription="Search keywords">
    </form>
    

確認方法:curl -sf https://example.com/ | grep -oE '<form[^>]*toolautosubmit[^>]*>'(検索フォームまたはフィルターフォームだけが表示されること)

5.12 OAuth ディスカバリー

サイトに認証関連のシグナルがある場合に適用されます。/.well-known/oauth-authorization-server または /.well-known/openid-configuration に issuer、authorization_endpoint、token_endpoint がある場合に合格します。

  1. メタデータを公開します(RFC 8414):
    {
      "issuer": "https://example.com",
      "authorization_endpoint": "https://example.com/oauth/authorize",
      "token_endpoint": "https://example.com/oauth/token",
      "code_challenge_methods_supported": ["S256"],
      "scopes_supported": ["read", "write"]
    }
    

確認:curl -sf https://example.com/.well-known/oauth-authorization-server | jq -e '.issuer and .authorization_endpoint and .token_endpoint'

5.13 OAuth 保護対象リソース

サイトに認証関連のシグナルがある場合に適用されます。/.well-known/oauth-protected-resource に resource と authorization_servers があるか、ホームページが WWW-Authenticate を送信する場合に合格します。

  1. メタデータを公開します(RFC 9728):
    { "resource": "https://example.com/api", "authorization_servers": ["https://example.com"], "scopes_supported": ["read"] }
    
  2. API から 401 が返された場合、WWW-Authenticate: Bearer resource_metadata="https://example.com/.well-known/oauth-protected-resource" を送信します。

確認:curl -sf https://example.com/.well-known/oauth-protected-resource | jq -e '.resource and (.authorization_servers | length > 0)'

5.14 エージェントの認証対応状況

サイトに認証機能がある場合に適用されます。このチェックでは、PKCE S256、スコープのメタデータ、保護対象リソースのメタデータまたは WWW-Authenticate ヘッダー、有効な /auth.md、エージェントに安全なグラントを組み合わせて確認します。

  1. 5.12 のメタデータに "code_challenge_methods_supported": ["S256"] と scopes_supported を追加します。
  2. 5.13 を公開します。
  3. /auth.md を作成します:
    # Authentication
    
    - Flow: OAuth 2.1 authorization code with PKCE (S256)
    - Agents: use the device code grant or a user-approved token. Do not ask for passwords.
    - Scopes: read (default), write (needs user approval)
    

確認:curl -sf https://example.com/.well-known/oauth-authorization-server | jq -e '.code_challenge_methods_supported | index("S256")'

主な注意点

  1. HSTS の max-age=86400(1日)では部分的な評価になります。1年に設定してください。
  2. upgrade-insecure-requests だけを指定した CSP では、部分的な評価になります。
  3. Nginx の add_header に always がないと、エラーレスポンスが対象外になります。
  4. 認証情報を使う場合の Access-Control-Allow-Origin: * は無効であり、安全ではありません。
  5. 別のドメインにある OAuth メタデータは、このサイトの評価対象になりません。

正しい例と誤った例については、references/gotchas.md を参照してください。

参考資料

コメント