About ページの総代理店情報
総代理店向けの DuDuClaw ビルドでは、ダッシュボードの About ページ(/about)に、正規総代理店の情報ブロックを 1 つ表示できます。位置は固定のベンダー表記ブロックの上です。公開ビルドにはこのブロックがなく、About ページと about.get の応答は従来どおりです。
内容は総代理店自身がライセンスコンソールの「総代理店情報」ページで管理します(責任者ロール)。顧客のダッシュボードへは 2 つの経路で届きます。
- 実行時の更新:ライセンスのある gateway は起動から約 1 分後、その後 6 時間ごとに、ライセンスを発行した総代理店の現在の内容をコントロールプレーンに問い合わせます。応答はライセンスと同じ鍵で署名され、そのライセンスに紐づいています。gateway は署名を検証し、もう一度サニタイズしてから表示し、署名済み文書を
<home>/distributor_notice.jsonに保存します。このファイルを書き換えても署名が無効になり、組み込み版に戻るだけです。総代理店が保存した内容は、オンラインの顧客には新しいビルドなしで約 6 時間以内に届きます。 - ビルド入力:リリース時にビルドパイプラインがコントロールプレーンから内容を取得し、バイナリに組み込みます。オフライン環境や、まだコントロールプレーンに接続していない gateway 向けです。内容を持つ有効な総代理店が 1 社だけのときに組み込み、複数あるときは共有イメージには組み込みません(顧客は実行時に自分の総代理店の内容を受け取ります)。
両方あるときは実行時の内容が優先され、「総代理店が内容を消去した」という署名済みの結果も組み込み版より優先されます。インストール済みのシステムでは設定や RPC でこのブロックを変更できず、エンドユーザーは差し替えられません。
ホワイトラベル機能(製品名・ロゴ・色の変更)は削除されたままです。white-label.md を参照してください。このブロックは、ページ上の製品名、ベンダー表記、バージョン、ライセンス階層を変更しません。
DUDUCLAW_DISTRIBUTOR_NOTICE_PATH=/absolute/path/to/notice.html \ cargo build --release -p duduclaw-cliこの変数は crates/duduclaw-gateway/build.rs が読み取ります。
- 未設定:総代理店情報なし(すべての公開ビルド)。
- 設定あり:通常ファイルを指す絶対パス(シンボリックリンクは拒否)、UTF-8(先頭の BOM は除去)、埋め込み画像を含めて 64 KB 以下である必要があります。変数が空文字列、ファイルが存在しない、その他の規則違反の場合は、理由を示してビルドが失敗します。
- ファイルまたは変数が変わると cargo が再ビルドします。
- HTML はビルド時にサニタイズされます(規則は下記)。除去された内容は cargo の出力に
warning: distributor notice: …として列挙されます。表示できる内容が何も残らない場合、またはサニタイズ後に 64 KB を超えた場合(各リンクにrelとtargetが付きます)、ビルドは失敗します。
この入力は DUDUCLAW_INSTALLATION_POLICY_PATH とは別です。インストールポリシーはチャネル・runtime・プロバイダのブロックにのみ使い、識別情報を含めてはいけません。
残る HTML
Section titled “残る HTML”- 要素:
p、br、h1–h4、ul、ol、li、strong、em、u、s、a、blockquote、code、pre、hr、img、div、span、table、thead、tbody、tr、th、td。<script>と<style>は中身ごと除去され、それ以外の要素はタグを除去してテキストを残します。 - 属性:
a[href]、img[src]、img[alt]のみ。style、class、id、すべてのon*ハンドラは除去されます。コメントも除去されます。 - リンク:絶対 URL の
http://、https://、mailto:のみで、ユーザー:パスワード@を含まないもの。すべてのリンクにrel="nofollow noopener noreferrer" target="_blank"が付きます。 - 画像:
data:image/png、data:image/jpeg、data:image/webpの base64 URI のみで、中身が宣言した形式と一致し、1 枚 512 KB 以下(通常は文書全体の 64 KB 上限が先に効きます)。SVG と外部画像は除去されます。
gateway は組み込まれた HTML を最初に返す前にもう一度サニタイズします。2 回目で拒否された場合、about.get はこのフィールドを含めず、gateway が警告を記録します。
ダッシュボードでの表示
Section titled “ダッシュボードでの表示”- ベンダー表記ブロックの上にカードを表示し、固定の見出し「総代理店情報」と説明「正規総代理店による提供」を付けます(中国語・英語の画面では各言語の表記)。見出しは製品側の文言で、総代理店の内容には含まれません。
- 内容は
sandbox="allow-same-origin allow-popups allow-popups-to-escape-sandbox"の iframe の中だけに表示されます。スクリプトは実行できず、フォーム送信やページ全体の遷移もできません。リンクは新しいタブで開きます。iframe 内のコンテンツセキュリティポリシーがすべてのネットワーク要求を止めるため、画像は data URI で埋め込む必要があります。 - ここで
allow-same-originを許可しても安全な理由:allow-scriptsがないため、iframe の中では何も実行できません(<script>、インラインのイベント属性、javascript:URL はいずれも動きません)。そのため iframe はダッシュボードのオリジンを利用できず、この権限はダッシュボードが描画後の高さを読み取ってカードの大きさを合わせるためだけに使われます。allow-scriptsは絶対に追加しないでください。両方がそろうと iframe が自分で sandbox を外せてしまいます。 - iframe の高さは内容に合わせて調整されます(読み込み時、内容のサイズ変化時、画像の読み込み後に再計測)。範囲は 64 px〜600 px で、それを超える内容は iframe 内でスクロールします。高さの変化には短いアニメーションが付きますが、システムで視差効果を減らす設定にしている場合は表示しません。
- iframe はダッシュボードのライト/ダークテーマに従います。総代理店の内容自体のスタイルは除去され、ダッシュボードの基本スタイルが適用されます。
ビルドの確認
Section titled “ビルドの確認”ログイン済みのダッシュボード接続から about.get を呼び出します。総代理店向けビルドは distributor_notice(サニタイズ済み HTML)を返し、公開ビルドにはこのキーがありません。
実行時の更新の詳細
Section titled “実行時の更新の詳細”- エンドポイント:
POST /v1/license/distributor-notice。subscription_id、machine_fingerprint、毎回新しく生成したnonceを送ります。コントロールプレーンはnonceをそのまま返し、一致しない応答は破棄されます(リプレイ対策)。 distributor_noticeがnullならライセンスに総代理店がなく、gateway は組み込み版に戻ります。それ以外は署名済み文書です(kind、subscription_id、distributor_id、version、htmlまたはnull、sha256、issued_at、public_key_id、signature)。- 拒否される場合:署名や鍵が不正、別のライセンス向け、
htmlとsha256の不一致または 64 KB 超過、表示中より古いバージョン、サニタイザーが受け付けない HTML。拒否時は表示中の内容を保ち、警告を記録します。 - ライセンスの差し替えや失効時はキャッシュファイルを削除し、次の問い合わせまで組み込み版を表示します。
- 無効化された総代理店には、署名済みの「表示しない」が返ります。