> ## Documentation Index
> Fetch the complete documentation index at: https://developers.authlete.com/llms.txt
> Use this file to discover all available pages before exploring further.

# OAuth Client ID Metadata Document (CIMD)

> OAuth Client ID Metadata Document (CIMD) 仕様と Authlete の実装の説明

## はじめに

[RFC 6749 The OAuth 2.0 Authorization Framework][RFC_6749]
で定義される認可リクエストでは、`client_id`
リクエストパラメータを用いてクライアントアプリケーション (以降『クライアント』)
の識別子 (以降『クライアント ID』) を指定しなければなりません。また、認可サーバは
`redirect_uri` リクエストパラメータで指定されたリダイレクト URI
が当該クライアントのものとして登録済みかどうか (当該クライアントの
`redirect_uris` メタデータにそのリダイレクト URI が含まれているかどうか)
を確認しなければなりません。

これらの要件を考慮すれば、クライアントが認可サーバにリクエストを送信するのに先立ち、当該クライアントの識別子やメタデータが認可サーバに事前に登録されている必要があることが分かります。

[OpenID Connect Dynamic Client Registration 1.0][OIDC_DYNREG] (DCR) や
[RFC 7591 OAuth 2.0 Dynamic Client Registration Protocol][RFC_7591] (DCR)、
[OpenID Federation 1.0][OIDFED] ([解説記事][OIDFED_ARTICLE]) の
[Explicit Registration][OIDFED_EXPLICIT_REG]
など、クライアントを事前に登録のための標準仕様が幾つか存在します。
認可サーバがこれらの標準仕様をサポートするかどうかは任意です。

<Note>
  上記の標準仕様をサポートしている場合でも、認可サーバの実装が独自のクライアント登録方法
  (静的設定ファイルや Web コンソールなど) を提供するのはよくあることです。Authlete
  も、これらの標準仕様に加え、Web コンソールや `/client/create`
  API によるクライアント登録をサポートしています。
</Note>

認可リクエストを投げる際に必要となるので、アプリケーションは認可サーバから割り当てられたクライアント
ID を保持しておかなければなりません。もしもそのアプリケーションが複数の認可サーバのクライアントとして動作する場合、通信相手となる認可サーバの数だけ異なるクライアント
ID を管理することになります。この状態は決して珍しいことではありません。
『[GAIN POC 中間報告 (2023年春)][GAIN_POC_REPORT]』の『現行のエコシステムアーキテクチャ』で紹介している通り、イギリスのオープンバンキングを参考に構築されたエコシステムは、概ねこのような状況となっています。

<img src="https://mintcdn.com/authlete/EJDZNZMvOu_9CJHJ/configuration-reference/endpoints/dynamic_client_registration.png?fit=max&auto=format&n=EJDZNZMvOu_9CJHJ&q=85&s=183f89979b2d6fd427c4d306f30df7b2" alt="" width="1920" height="1080" data-path="configuration-reference/endpoints/dynamic_client_registration.png" />

DCR を活用するこの仕組みは機能するものの、認可サーバ毎にクライアント ID
を使い分けなければならず、認可サーバの数が増えてくると識別子管理が厄介になってきます。
アプリケーションの立場からすれば、可能であれば一つのクライアント ID
を全ての認可サーバで共通して使い回したいところです。

実は、クライアント ID を全ての認可サーバで共通化する仕組みは、[OpenID Federation 1.0][OIDFED]
という仕様で既に実現されています。同仕様では、クライアント ID
はグローバルで一意となる、`https://` ではじまる URL となります。
そして、当該クライアントのメタデータは、その URL に
`/.well-known/openid-federation`
を付加した場所から提供されます
(下図は[解説文書][OIDFED_ARTICLE]から抜粋したものです)。

<img src="https://mintcdn.com/authlete/U02sYmcLE8xIcCKt/protocols-and-flows/compliance-profiles/oidcfed_md_rp.png?fit=max&auto=format&n=U02sYmcLE8xIcCKt&q=85&s=6f833da2078e9c55c14fb99e7c5d7d43" alt="" width="1920" height="1080" data-path="protocols-and-flows/compliance-profiles/oidcfed_md_rp.png" />

[OpenID Federation 1.0][OIDFED] をサポートする認可サーバは、認可リクエストの `client_id`
リクエストパラメータで指定された識別子に対応するクライアントが未登録であり、そしてその識別子が
`https://` で始まる URL の場合、その URL に
`/.well-known/openid-federation`
を追加した場所からクライアントメタデータを取得し、クライアントを自動的に登録します
([Automatic Registration][OIDFED_AUTOMATIC_REG])。
そして、何事もなかったかのように認可リクエストの処理を継続します。

<Note>
  トラストチェーンの検証やメタデータポリシーの適用などがあるため、クライアントメタデータの算出処理は、実際はかなり複雑です。
  詳細は[解説記事](https://www.authlete.com/developers/oidcfed/)を参照してください。
</Note>

このような先行仕様があるところに、**[OAuth Client ID Metadata Document][CIMD]** (**CIMD**)
という新しい仕様が提案されました。この仕様でも、クライアント ID は `https://`
で始まる URL であり、クライアントメタデータはその URL が指す場所から提供されます。

[OpenID Federation 1.0][OIDFED] に比べると、[CIMD][CIMD] はかなり単純な仕様です。
おかげでクライアントやサーバの実装は楽になります。しかし、その単純さと引き換えに、[CIMD][CIMD]
仕様には、クライアントが信頼できる通信相手であるかどうかを確認する方法が定義されていません。
そのため、認可サーバの実装が何らかの独自機能で制限をかけない限り、[CIMD][CIMD]
をサポートする認可サーバには誰でも勝手にクライアントを登録できてしまいます。
これは、トラストチェーンを用いてエンティティ間の信頼関係を築く方法を具体的に定めている
[OpenID Federation 1.0][OIDFED] とは対照的です。

この記事では、[CIMD][CIMD] 仕様と、それを補完する Authlete の独自機能について説明します。

## 仕様

### 概要

[CIMD][CIMD] 仕様を簡潔に説明すると、「クライアント識別子を `https://` で始まる
URL とする。クライアントメタデータは、その URL が指す場所から取得する」、となります。

順を追って見ていきましょう。まず、クライアントが認可サーバに認可リクエストを送信します。
認可リクエストには `client_id` リクエストパラメータを含めますが、その値として
`https://` で始まる URL を指定します。

<img src="https://mintcdn.com/authlete/EJDZNZMvOu_9CJHJ/configuration-reference/endpoints/cimd_0.png?fit=max&auto=format&n=EJDZNZMvOu_9CJHJ&q=85&s=87263b488669d266ca53c61380f91223" alt="" width="1600" height="900" data-path="configuration-reference/endpoints/cimd_0.png" />

認可サーバは受け取った認可リクエストを解析します。そして、クライアント ID が
`https://` で始まることを認識します。

<img src="https://mintcdn.com/authlete/EJDZNZMvOu_9CJHJ/configuration-reference/endpoints/cimd_1.png?fit=max&auto=format&n=EJDZNZMvOu_9CJHJ&q=85&s=890883692d6e042cc080189c799c1944" alt="" width="1600" height="900" data-path="configuration-reference/endpoints/cimd_1.png" />

そのクライアント ID に該当するクライアントが未登録であれば、認可サーバはその
URL が指す場所にアクセスします。

<img src="https://mintcdn.com/authlete/EJDZNZMvOu_9CJHJ/configuration-reference/endpoints/cimd_2.png?fit=max&auto=format&n=EJDZNZMvOu_9CJHJ&q=85&s=dadd9be458b00340badf74724a0c3a30" alt="" width="1600" height="900" data-path="configuration-reference/endpoints/cimd_2.png" />

アクセスした場所から、クライアントメタデータが JSON 形式で返されます。

<img src="https://mintcdn.com/authlete/EJDZNZMvOu_9CJHJ/configuration-reference/endpoints/cimd_3.png?fit=max&auto=format&n=EJDZNZMvOu_9CJHJ&q=85&s=5fd81bb9b766512c75b6ebc976ce92d6" alt="" width="1600" height="900" data-path="configuration-reference/endpoints/cimd_3.png" />

認可サーバは、そのクライアントメタデータを元にクライアントを自身に登録し、認可リクエストの処理を継続します。

<img src="https://mintcdn.com/authlete/EJDZNZMvOu_9CJHJ/configuration-reference/endpoints/cimd.png?fit=max&auto=format&n=EJDZNZMvOu_9CJHJ&q=85&s=37689159f9c59f1bc2c9c874a42c6b89" alt="" width="1600" height="900" data-path="configuration-reference/endpoints/cimd.png" />

### クライアント ID の要件

* スキームは `https` でなければならない
* パス部を含まなければならない
* パスセグメントに `.` や `..` を含んではならない
* フラグメント部を含んではならない
* ユーザ名やパスワードを含んではならない
* クエリー部を含めるべきではない

### クライアントメタデータの制限

* メタデータの URL と、そこから得られるメタデータ内の `client_id` の値は一致しなければならない
* `client_secret_basic`、`client_secret_post`、`client_secret_jwt`
  などの対称鍵系クライアント認証方式を `token_endpoint_auth_method` に指定してはならない
* `client_secret`、`client_secret_expires_at` を使ってはならない

## サービス設定

Authlete では、バージョン 3.0.22 以降で [CIMD][CIMD] をサポートします。
このセクションでは、[CIMD][CIMD] サポートのためにサービスに追加されたプロパティ群と、関連する
API リクエストパラメータについて紹介します。

### clientIdMetadataDocumentSupported プロパティ

[CIMD][CIMD] をサポートするかどうかを示す新しい真偽値プロパティ
`clientIdMetadataDocumentSupported` がサービスに追加されました。
このプロパティのデフォルト値は `false` なので、[CIMD][CIMD] を利用する場合は明示的に
`true` に設定する必要があります。

```json theme={null}
{
  "clientIdMetadataDocumentSupported": true
}
```

`clientIdMetadataDocumentSupported`
プロパティは、[CIMD][CIMD] 仕様が定義するサーバメタデータの
`client_id_metadata_document_supported` に対応しています。
`clientIdMetadataDocumentSupported` が `true`
に設定されている場合、Authlete の `/service/configuration` API
が生成するディスカバリ文書 ([OpenID Connect Discovery 1.0][OIDC_DISCOVERY])
に次のエントリが追加されます。

```json theme={null}
{
  "client_id_metadata_document_supported": true
}
```

### メタデータポリシー

CIMD（Client ID Metadata Document）で取得したクライアントメタデータを、利用前にどのように処理・検証するかを制御する設定です。有効にすると、ここで定義したポリシーがクライアント ID URI から取得したメタデータに適用され、その結果がクライアント登録として保存されます。

`cimdMetadataPolicyEnabled` プロパティを `true` にし、`cimdMetadataPolicy` プロパティに JSON 形式のポリシー定義を指定すると、この機能が有効になります。

メタデータポリシーは [OpenID Federation 1.0 仕様（Section 6.1 – Metadata Policy）](https://openid.net/specs/openid-federation-1_0.html#name-metadata-policy) に従い、`add`、`subset_of`、`superset_of`、`one_of`、`default`、`value`、`essential` などの演算子をサポートします。

#### 設定例

```json theme={null}
{
  "cimdMetadataPolicyEnabled": true,
  "cimdMetadataPolicy": {
    "id_token_signed_response_alg": {
      "default": "ES256",
      "one_of": ["ES256", "ES384", "ES512"]
    },
    "redirect_uris": {
      "add": [
        "http://localhost:12345/redirect"
      ]
    }
  }
}
```

#### サービス API ペイロード例

メタデータポリシーを有効にすると、サービス API のペイロードにはポリシーが JSON 文字列として含まれます。

```json theme={null}
{
  "cimdMetadataPolicyEnabled": true,
  "cimdMetadataPolicy": "{\"redirect_uris\":{\"add\":[\"http://localhost:12345/redirect\"]},\"id_token_signed_response_alg\":{\"default\":\"ES256\",\"one_of\":[\"ES256\",\"ES384\",\"ES512\"]}}"
}
```

#### 動作

`cimdMetadataPolicyEnabled` を `true` にすると、Authlete は CIMD で取得したメタデータをクライアント登録として保存する前に、定義したポリシーを適用します。ポリシーでは、OpenID Federation 1.0 のメタデータポリシー文法に従い、値の追加、オプションの制限、デフォルトの設定、メタデータフィールドの検証などが行えます。

ポリシーを無効にした場合、取得したクライアントメタデータは変更されずに保存されます。

### 許可リスト

クライアント ID として許可する URL を、許可リストを用いて制限することができます。
許可リストはサービスの `cimdAllowlist` プロパティで指定します。
また、許可リストによる制限を有効化するために
`cimdAllowlistEnabled` プロパティに `true` を設定します。

```json theme={null}
{
  "cimdAllowlistEnabled": true,
  "cimdAllowlist": [
    "https://example.com/a/b"
  ]
}
```

<Note>
  `cimdAllowlistEnabled` プロパティを `false`
  のまままにしておくと、誰でも好き勝手にクライアント登録できる状態のままとなります。
</Note>

`cimdAllowlist` プロパティの値は文字列の配列で、各要素は有効な
URL でなければなりません。

クライアント ID は、許可リスト内の URL のどれか一つとマッチすれば、有効とみなされます。
マッチするかどうかの判定は単純な文字列比較ではなく、次の要領で行われます。

|     | コンポーネント | 比較処理                                      |
| :-: | :------ | :---------------------------------------- |
|  1  | スキーム    | スキーム部が一致する                                |
|  2  | オーソリティ  | オーソリティ部が一致する (単純文字列比較であり、デフォルトポートは考慮されない) |
|  3  | パス      | クライアント ID のパスが許可リスト内の URL のパスを完全に含む       |
|  4  | クエリー    | 許可リスト内の URL がクエリー部を含む場合、クエリー部が一致する        |

パス部の比較はセグメント単位で行われます。例えば許可リストが
`https://example.com/a/b`
を含んでいる場合、`https://example.com/a/b/c`
は有効なクライアント ID とみなされますが、`https://example.com/a`
や `https://example.com/a/bb` は無効とみなされます。

### 常時取得

認可サーバは取得したクライアントメタデータをある程度の期間キャッシュします。
その期間が切れるまではメタデータの再取得を行わず、キャッシュされたものを参照し続けます。

この動作は一般的には好ましいですが、時にはキャッシュの期限切れを待たずに認可サーバにクライアントメタデータの再取得をしてもらいたいこともあるでしょう。
特に、クライアントアプリケーションの開発中にクライアントメタデータの内容を頻繁に変更している場合などです。
あなたが Web サイトのコンテンツ制作に関わった経験があるならば、Web ブラウザの Super Reload
を有用だと感じたことがあるでしょう。クライアントメタデータの強制再取得機能は、いわば Super Reload
のようなものです。

[OpenID Federation 1.0][OIDFED] では、`trust_chain`
リクエストパラメータを使うことで、キャッシュの期限切れ前に認可サーバにクライアントメタデータの更新を促すことができます。
一方、[CIMD][CIMD] にはそのような仕組みはありません。
そこで、「クライアントメタデータの再取得を促す方法を標準化してはどうか」と提案してみました
([CIMD ISSUE 59][CIMD_ISSUE_59])。
しかし、賛同を得られる見込みがほとんどなかったため、Authlete 独自の仕組みを作り込むことにしました。

サービスの `cimdAlwaysRetrieved` プロパティに `true`
を設定しておくと、Authlete は常にクライアントメタデータを再取得するようになります。
正確に言うと、認可フローの開始リクエストの際に常に再取得をおこないます。
「認可フローの開始リクエスト」が意味するところは、具体的には次のとおりです。

* 認可コードフロー (などの認可エンドポイントへのリクエストから開始するフロー)
  では認可リクエストの際に再取得を実行するが、後続のトークンリクエストでは再取得を実行しない
* クライアントクレデンシャルズフロー (などのトークンエンドポイントへのリクエストから開始するフロー)
  ではトークンリクエストが開始リクエストなので、トークンリクエストのタイミングで再取得を実行する
* CIBA フロー ([CIBA Core][CIBA_CORE]) ではバックチャネル認証リクエストの際に再取得を実行するが、後続のトークンリクエストでは再取得は実行しない
* デバイスフロー ([RFC 8628][RFC_8628]) ではデバイス認可リクエストの際に再取得を実行するが、後続のトークンリクエストでは再取得は実行しない

常に再取得をおこなう機能は、開発中は有用でしょう。
しかし、システムが安定稼働してクライアントメタデータが更新されることがほとんどなくなった場合、常時再取得はやり過ぎです。
そのため、システムが安定稼働し始めたら、`cimdAlwaysRetrieved`
プロパティに `false` を設定することになるでしょう。

とは言っても、システム安定稼働開始後も強制再取得を実行したい事情が発生することはありえます。
そのため、幾つかの Authlete API、具体的には下記の API 群は、リクエストパラメータとして
`cimdOptions.alwaysRetrieved` を受け付け、その値が
`true` の場合、サービス設定の `cimdAlwaysRetrieved` が
`false` の場合でも、クライアントメタデータの再取得を (キャッシュが有効か否かに関わらず)
実行します。

| API                                            | 説明                |
| :--------------------------------------------- | :---------------- |
| `/api/{service-id}/auth/authorization`         | 認可リクエストの処理        |
| `/api/{service-id}/auth/token`                 | トークンリクエストの処理      |
| `/api/{service-id}/backchannel/authentication` | バックチャネル認証リクエストの処理 |
| `/api/{service-id}/device/authorization`       | デバイス認可リクエストの処理    |

このランタイム時の機能を用い、認可サーバは独自のクライアントメタデータ強制再取得機能を実装することができます。

### HTTP スキーム許可

[CIMD][CIMD] 仕様では、クライアント ID を示す URL のスキームは `https` でなければなりません。

しかし、サービスの `cimdHttpPermitted` フラグに `true`
を設定すると、Authlete は `http` スキームも許容するようになります。
この機能をオンにすることで、TLS による保護を省いた Web
サーバをクライアントメタデータをホスティングするサーバとして用いることができます。
この機能は開発中に利用されることを想定しています。

`cimdAlwaysRetrieved` プロパティに対応する
`cimdOptions.alwaysRetrieved`
リクエストパラメータが存在するのと同様、
`cimdHttpPermitted` プロパティに対応する
`cimdOptions.httpPermitted`
リクエストパラメータも存在します。

### クエリー部許可

[CIMD][CIMD] 仕様では、クライアント ID を示す URL はクエリー部を持つべきではない
(SHOULD NOT) とされています。Authlete は、デフォルトでは、クエリー部を含む URL
を [CIMD][CIMD] のクライアント ID として受け入れません。

クエリー部を含む URL を [CIMD][CIMD] クライアント ID として Authlete
に受け入れさせるためには、サービスの `cimdQueryPermitted`
プロパティに `true` を設定する必要があります。

このプロパティにも、対応するリクエストパラメータ
`cimdOptions.queryPermitted`
が存在します。

### HTTP エイリアス禁止

Authlete はクライアントに対して内部的に数値の識別子を割り振ります。
これに加え、クライアント ID エイリアスという機能が存在し、この機能により開発者はクライアントに任意の名前を設定することができます。
Authlete 2.3 まではクライアント ID エイリアス機能のオン・オフを切り替えることができましたが、歴史的な経緯により、Authlete 3.0
ではこの機能は常に有効になっており、オフにすることはできません。

任意の名前を設定することができるので、例えば `https` スキームを持つ URL をクライアント識別子として設定することができます。
しかし、そのようなクライアント識別子は、見た目は [OpenID Federation 1.0][OIDFED] や [CIMD][CIMD]
のクライアント ID に見えるものの、実際はエイリアスにしか過ぎないので、クライアントメタデータの自動更新処理が走ることはありません。

この状況は混乱を招きかねないので、Authlete は新たに `httpAliasProhibited`
というサービスプロパティを導入し、`https://` や `http://`
で始まる文字列をエイリアスとして設定できないようにする機能を提供することにしました。

後方互換性のため、この `httpAliasProhibited` プロパティの初期値は `false`
となっていますが、可能な限り `true` に設定することを推奨します。

<Note>
  Authlete は、認可リクエスト (などの標準仕様のプロトコル) に含まれるクライアント ID
  に対応するクライアントを検索するとき、数値の内部識別子 → エイリアス →
  OpenID Federation 1.0 のエンティティ ID → CIMD のクライアントメタデータ
  URL、という順番 (優先度) で検索します。そのため、クライアント ID
  がエイリアスに合致すると、そのクライアント ID に対して CIMD 機能は動きません。
</Note>

### メタデータポリシー

取得したクライアントメタデータをデータベースに登録する前に、**メタデータポリシー**を適用してメタデータを調整する機能を
Authlete は提供します。これは、[OpenID Federation 1.0][OIDFED] の
[Section 6.1. Metadata Policy][OIDFED_METADATA_POLICY]
で定義されているメタデータポリシーを [CIMD][CIMD] に応用する機能です。

<img src="https://mintcdn.com/authlete/EJDZNZMvOu_9CJHJ/configuration-reference/endpoints/metadata_policy.png?fit=max&auto=format&n=EJDZNZMvOu_9CJHJ&q=85&s=b660e6732fba927ebefc3f39768bb7b6" alt="" width="1600" height="900" data-path="configuration-reference/endpoints/metadata_policy.png" />

例えば、クライアント ID が指す URL から得られるクライアントメタデータの内容が次のものであるとしましょう。

```json theme={null}
{
  "client_name": "Example Client",
  "grant_types": [
    "authorization_code",
    "refresh_token"
  ],
  "response_types": [
    "code"
  ],
  "token_endpoint_auth_method": "none",
  "client_id": "https://example.com/client.json",
  "redirect_uris": [
    "https://example.com/redirect"
  ]
}
```

このクライアントメタデータに対して、次のメタデータポリシーを適用すると、

```json theme={null}
{
  "id_token_signed_response_alg": {
    "default": "ES256",
    "one_of": ["ES256", "ES384", "ES512"]
  },
  "redirect_uris": {
    "add": [
      "http://localhost:12345/redirect"
    ]
  }
}
```

結果として得られるクライアントメタデータは次のようになります。`redirect_uris` に
`http://localhost:12345/redirect`
が追加され、`ES256` という値を持つ
`id_token_signed_response_alg`
プロパティが新しく追加されていることに注目してください。

```json theme={null}
{
  "client_name": "Example Client",
  "grant_types": [
    "authorization_code",
    "refresh_token"
  ],
  "response_types": [
    "code"
  ],
  "token_endpoint_auth_method": "none",
  "client_id": "https://example.com/client.json",
  "redirect_uris": [
    "https://example.com/redirect",
    "http://localhost:12345/redirect"
  ],
  "id_token_signed_response_alg": "ES256"
}
```

<Note>
  [OpenID
  Connect Dynamic Client Registration 1.0](https://openid.net/specs/openid-connect-registration-1_0.html) 仕様は
  `id_token_signed_response_alg`
  プロパティのデフォルト値を `RS256` と定めているため、このプロパティが明示的に含まれていない場合、その値は
  `RS256` になります。結果として、ID トークンの署名アルゴリズムは `RS256` になります。

  しかし、上記のようなメタデータポリシーを用意して適用すれば、当プロパティの値は `ES256`
  となり、結果として ID トークンの署名アルゴリズムは `ES256` になります。
</Note>

この機能を利用するには、サービスの `cimdMetadataPolicyEnabled`
プロパティに `true` を設定し、`cimdMetadataPolicy`
プロパティにメタデータポリシーを設定します。

```json theme={null}
{
  "cimdMetadataPolicyEnabled": true,
  "cimdMetadataPolicy": "{\"redirect_uris\":{\"add\":\"http://localhost:12345/redirect\"},\"id_token_signed_response_alg\":{\"default\":\"ES256\",\"one_of\":[\"ES256\",\"ES384\",\"ES512\"]}}"
}
```

## クライアントプロパティ

Authlete が Authlete API を通じて Authlete 外部にクライアントの情報を伝える際、`[Client][CLIENT]`
というデータ構造が用いられます。[CIMD][CIMD] をサポートするにあたり、このデータ構造に次のプロパティ群が追加されました。

| プロパティ                          | 説明                                          |
| :----------------------------- | :------------------------------------------ |
| `metadataDocumentLocation`     | クライアントメタデータの場所                              |
| `metadataDocumentExpiresAt`    | クライアントメタデータの有効期間終了時刻 (Unix epoch からの経過ミリ秒数) |
| `metadataDocumentUpdatedAt`    | クライアントメタデータの最終更新時刻 (Unix epoch からの経過ミリ秒数)   |
| `discoveredByMetadataDocument` | CIMD により登録されたクライアントかどうかを示す真偽値               |

Authlete は、[CIMD][CIMD] 仕様が言及しているように、HTTP の既存のメカニズム
(参考: [RFC 9111 HTTP Caching][RFC_9111]) を利用してクライアントメタデータの有効期間を算出します。
`metadataDocumentExpiresAt` プロパティは、その有効期間が終了する時刻を示します。

クライアントメタデータをホスティングする Web サーバが `max-age`
等のキャッシュに関する設定をし忘れていたり、極端に長い `max-age`
を設定しているなどの理由で、算出したクライアントメタデータの有効期間が、期待されるクライアントメタデータ更新間隔を大きく超えてしまう可能性があります。
そのような想定をはるかに超える有効期間が設定されてしまうと、クライアントメタデータの更新が適切な時間間隔で検知されなくなってしまいます。
このような事態を避けるため、現在の Authlete の実装では、算出された値に関わらず、有効期間の最大値を 86400 秒 (1日) としています。

<Note>
  Authlete のオンプレミス版を利用されるお客様や Authlete 社内の開発者が、
  Authlete サーバとクライアントメタデータをホスティングする Web
  サーバを両方ともローカルマシン上で動かしながら開発作業をおこなうという特殊ケースを想定し、クライアント
  ID のホスト部がローカルマシンを指している場合、具体的には下記のいずれかに該当する場合、クライアントメタデータの有効期間の最大値は
  600 秒 (10 分) になります。なお、この動作は将来変更されるかもしれません。

  `localhost`
  `127.0.0.1`
  `::1`
  `host.docker.internal`
  `host.minikube.internal`
</Note>

下記はクライアント識別子に関係のあるプロパティ群です。

| プロパティ                          |  型  |        仕様        | 説明                                                          |
| :----------------------------- | :-: | :--------------: | :---------------------------------------------------------- |
| `clientId`                     |  数値 |                  | 数値のクライアント識別子                                                |
| `clientIdAlias`                | 文字列 |                  | クライアント識別子のエイリアス                                             |
| `clientIdAliasEnabled`         | 真偽値 |                  | エイリアス機能が有効かどうか (Authlete 3.0 では常に真)                         |
| `dynamicallyRegistered`        | 真偽値 |        DCR       | DCR により登録されたかどうか                                            |
| `entityId`                     | 文字列 | [OIDFED][OIDFED] | エンティティ ID                                                   |
| `automaticallyRegistered`      | 真偽値 | [OIDFED][OIDFED] | [Automatic Registration][OIDFED_AUTOMATIC_REG] により登録されたかどうか |
| `explicitlyRegistered`         | 真偽値 | [OIDFED][OIDFED] | [Explicit Registration][OIDFED_EXPLICIT_REG] により登録されたかどうか   |
| `metadataDocumentLocation`     | 文字列 |   [CIMD][CIMD]   | クライアントメタデータの場所                                              |
| `metadataDocumentExpiresAt`    |  数値 |   [CIMD][CIMD]   | クライアントメタデータの有効期間終了時刻                                        |
| `metadataDocumentUpdatedAt`    |  数値 |   [CIMD][CIMD]   | クライアントメタデータの最終更新時刻                                          |
| `discoveredByMetadataDocument` | 真偽値 |   [CIMD][CIMD]   | [CIMD][CIMD] により登録されたかどうか                                   |

歴史的な経緯により、クライアントの出所を示す真偽値が複数存在します — すなわち
`dynamicallyRegistered`、`automaticallyRegistered`、`explicitlyRegistered`、`discoveredByMetadataDocument`
という真偽値フラグが存在し、お互いに排他の関係にあります (同時に複数のフラグが真になることはありません)。

相互排他の関係にあるフラグ群が別々に存在しているのは厄介なので、バージョン 3.0.22
以降の Authlete は、これらのフラグに加えて `clientSource`
という文字列プロパティも Authlete API のレスポンスに含めます。
このプロパティは次の値を取ります。

| 値                        | 説明                                                                                     |
| :----------------------- | :------------------------------------------------------------------------------------- |
| `DYNAMIC_REGISTRATION`   | DCR による登録                                                                              |
| `AUTOMATIC_REGISTRATION` | [OpenID Federation 1.0][OIDFED] の [Automatic Registration][OIDFED_AUTOMATIC_REG] による登録 |
| `EXPLICIT_REGISTRATION`  | [OpenID Federation 1.0][OIDFED] の [Explicit Registration][OIDFED_EXPLICIT_REG] による登録   |
| `METADATA_DOCUMENT`      | [CIMD][CIMD] による登録                                                                     |
| `STATIC_REGISTRATION`    | 上記以外 (静的登録)                                                                            |

## レスポンスパラメータ

`/api/{service-id}/auth/authorization` API
など、幾つかの Authlete API のレスポンスには、リクエストで使用されたクライアント
ID の出所に関する情報が含まれます。

| パラメータ                      |  型  |        仕様        | 説明                                |
| :------------------------- | :-: | :--------------: | :-------------------------------- |
| `clientIdAliasUsed`        | 真偽値 |                  | エイリアスがクライアント ID として用いられた          |
| `clientIdAlias`            | 文字列 |                  | エイリアス                             |
| `clientEntityIdUsed`       | 真偽値 | [OIDFED][OIDFED] | エンティティ ID がクライアント ID として用いられた     |
| `clientEntityId`           | 文字列 | [OIDFED][OIDFED] | エンティティ ID                         |
| `metadataDocumentUsed`     | 真偽値 |   [CIMD][CIMD]   | クライアントメタデータの場所がクライアント ID として用いられた |
| `metadataDocumentLocation` | 文字列 |   [CIMD][CIMD]   | クライアントメタデータの場所                    |

## おわりに

MCP (Model Context Protocol) 仕様の 2025 年 11 月 25 日版で、[CIMD][CIMD]
が仕様として取り込まれました
([MCP 2025-11-25 Authorization][MCP_20251125_AUTHORIZATION])。

Authlete は 2025 年 11 月中に [CIMD][CIMD] 仕様を実装し終え、本記事でもご紹介している通り、Authlete
独自機能として次のものも併せて実装しました。

* 許可リスト (`cimdAllowlist`, `cimdAllowlistEnabled`)
* 常時取得 (`cimdAlwaysRetrieved` | `cimdOptions.alwaysRetrieved`)
* HTTP 許可 (`cimdHttpPermitted` | `cimdOptions.httpPermitted`)
* クエリー部許可 (`cimdQueryPermitted` | `cimdOptions.queryPermitted`)
* メタデータポリシー (`cimdMetadataPolicy`, `cimdMetadataPolicyEnabled`)

[CIMD][CIMD] は策定中の仕様であり、今後も進化していくことが予想されます。
また、[CIMD][CIMD] の実装・運用経験が業界に積み上がっていくのはこれからです。
Authlete は、仕様の進化や業界へのフィードバックに合わせて、適宜機能を追加していく予定です。
機能追加のご要望がありましたら、[コンタクトフォーム][CONTACT]でお問い合わせください。

[RFC_6749]: https://www.rfc-editor.org/rfc/rfc6749.html

[RFC_7591]: https://www.rfc-editor.org/rfc/rfc7591.html

[RFC_8628]: https://www.rfc-editor.org/rfc/rfc8628.html

[RFC_9111]: https://www.rfc-editor.org/rfc/rfc9111.html

[OIDC_DISCOVERY]: https://openid.net/specs/openid-connect-discovery-1_0.html

[OIDC_DYNREG]: https://openid.net/specs/openid-connect-registration-1_0.html

[OIDFED]: https://openid.net/specs/openid-federation-1_0.html

[OIDFED_ARTICLE]: /developers/oidcfed/

[OIDFED_AUTOMATIC_REG]: https://openid.net/specs/openid-federation-1_0.html#name-automatic-registration

[OIDFED_EXPLICIT_REG]: https://openid.net/specs/openid-federation-1_0.html#name-explicit-registration

[OIDFED_METADATA_POLICY]: https://openid.net/specs/openid-federation-1_0.html#name-metadata-policy

[CIBA_CORE]: https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html

[CIMD]: https://datatracker.ietf.org/doc/draft-ietf-oauth-client-id-metadata-document/

[CIMD_ISSUE_59]: https://github.com/oauth-wg/draft-ietf-oauth-client-id-metadata-document/issues/59

[MCP_20251125_AUTHORIZATION]: https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization

[GAIN_POC_REPORT]: https://qiita.com/TakahikoKawasaki/items/3c65d546627e9e1fabd0

[CLIENT]: https://authlete.github.io/authlete-java-common/com/authlete/common/dto/Client.html

[CONTACT]: /ja/contact/
