qub のセキュリティ

発効日: 2026 年 9 月 23 日 バージョン: 1.1 — 実装精度レビュー


研究者向け — クイックリファレンス:

詳細は §12(協調的開示)にあります。


運営者について

qub.social は VSPRY AUSTRALIA PTY LIMITED(ABN 41 631 026 330、Level 38, 71 Eagle Street, Brisbane QLD 4000, Australia)により運営されています。「qub」「当社」「私たち」「私たちの」とは、当該事業体を指します。

セキュリティに関するお問い合わせ: support@qub.social に件名の接頭辞 [SECURITY] を付してご連絡ください。


1. 私たちのアプローチ

qub は信頼インフラです。安全でなければプロダクトは無価値であり、したがってセキュリティは機能ではなく — 基盤です。本ページでは、当社のスタック、あなたのデータ、封印されたコンテンツの完全性をどのように保護しているかを具体的に説明します。

検証可能な時間的コミットメントの価値は、インターネット上のマシン生成コンテンツが増えるほど高まります。検証済みのストレージトランザクションまたは透明性ログのアンカーは、暗号文が遅くともそのブロック時刻には存在したことを確立できます。封印されたアーティファクトは、それとは別に、コンテンツの完全性、drand ラウンドへの結合、および作成者署名があればその署名を証明します。これらの主張を明確に区別することが、本ページの基準です。

私たちはあなたに私たちを信頼してくれと頼みません。私たちに要求される信頼ができるだけ小さくなるように設計し、信頼が必要な場所では、何が信頼されているかとその理由を正確に説明します。

3 つの原則がすべての設計判断を駆動します。


2. 脅威モデル

2.1 防御するもの

2.2 防御できないもの

私たちは限界について正直です。qub は以下を防御できません。


3. クライアントサイド暗号

既定のブラウザメッセージフローでは、アップロード要求より前にコンテンツ暗号化が行われます。明示的に異なる経路が 2 つあります。Builder の /api/v1/seal は、メモリ内での封印のため平文と呼び出し元が生成した K を意図的に Worker へ送ります。約定のステージング / 共同署名は、双方向アーティファクトを完成させるため、署名済みの構造化約定をサービスへ送ります。どちらの例外も、ブラウザ経路の end-to-end 暗号化と混同してはなりません。

3.1 タイムロック暗号化

qub は tlock を使用します — 将来の drand ビーコンラウンドをキーとする ID ベース暗号化です。暗号化は drand ネットワークの公開鍵を使用してブラウザで行われます。復号鍵は、対象のラウンドに到達したときにのみ drand ネットワークによって公開されます。私たちを含め、誰も復号鍵を事前に再構成できません。

私たちは quicknet チェーンをターゲットにします:

quicknet チェーンの公開鍵とジェネシス時刻はクライアントにコンパイルされています。実行時にチェーンパラメータをフェッチしないため、悪意あるノードが当社が制御するチェーンに置き換えることはできません。

3.2 対称暗号化

tlock スキームは AES-256-GCM コンテンツ鍵をラップします。AES-GCM は認証付き暗号化を提供します: 暗号文の 1 ビットがフリップされただけで、密かに破損した平文を生成せず、復号が失敗します。

3.3 正規シリアル化

プロトコル構造は決定論的 CBOR(RFC 8949 §4.2 コア決定論的エンコーディング)でシリアル化されます。同じ論理構造を符号化する 2 つの実装は、同一の CBOR を生成します。完成した封印済みペイロード自体は決定論的ではありません。tlock と外側ラッパーの暗号化は、新しい乱数を使用します。ボディハッシュは生の本文バイト列について計算され、正規符号化により周囲の署名済み / ワイヤ構造が曖昧にならないようにします。

私たちは、汎用シリアル化ライブラリに依存するのではなく、クライアントとサーバーの両方の実装の CBOR エンコーダーを手書きしました — 要件は人間工学ではなく正確性であり、両方の実装でプロパティテストを実行して合意を検証しています。

レグレッションテストは、正規ワイヤーフォーマットがプロトコルプリミティブ qub_id フィールドキー以外の qub ブランドバイト列を含まないことをアサートします。ワイヤーフォーマットは意図的にブランドに依存しません — 適合するビューアー(当社のものでもサードパーティのものでも)は、どのデプロイメントが封印したかにかかわらず、永久ストレージからの任意の qub を描画できます。このテストは、将来の変更が誤ってブランド参照をバイトに焼き込み、それが一度永久ストレージに置かれると書き換えられない事態を防ぐトリップワイヤーです。

3.4 ボディハッシュと公開前完全性

封印された各ペイロードは、生の本文バイト列の SHA3-256 ハッシュを保持します。ハッシュは qub_id に結合され、作成者署名が有効な場合は V2 署名入力にも結合されます。ビューアーは復号後にハッシュを再計算し、一致しなければ拒否します。

32 バイトのコンテンツ識別子 qub_id は、プロトコルバージョン、コンテンツタイプ、作成および解錠タイムスタンプ、任意の outcome タイムスタンプ(またはゼロの番兵値)、対象 drand ラウンド、ボディハッシュ、および任意の NFC 正規化タイトルの SHA3-256 を含む 108 バイトのプリイメージから導出されます。ゲートウェイや CDN は、結合されたどのフィールドも、再導出を通過する形で変更できません。タイトルは 100 NFC コードポイントに制限され、共有の敵対的 / 制御コードポイント群(双方向オーバーライド、ゼロ幅文字、タグブロック、BOM、C0、C1、DEL を含む)があれば拒否されます。

3.5 署名(ML-DSA-65)

作成者署名は ML-DSA-65(FIPS 204)を使用します。これは NIST 標準化されたポスト量子署名スキームです。署名のためにポスト量子プリミティブを意図的に選択しました。封印されたコンテンツは永久であるため: 今日検証する署名は、大規模量子コンピューターが実用化された後を含め、数十年後も検証する必要があります。

署名鍵はブラウザで生成されます。ローカルの秘密情報は、IndexedDB に保存する前に抽出不能な WebCrypto 鍵でラップされます。アカウント単位の端末間復旧機能を使用する場合、AEAD で暗号化された可搬鍵 BLOB がサーバー側に保存されます。その秘密鍵暗号文は不変のアカウント ID に結合され、サービスは公開エンベロープを検証できますが、秘密情報は復号できません。生の秘密鍵バイト列がサーバーへ送られることはありません。公開鍵とアテステーション記録は、検証と ID 表示のため保存されます。

同じブラウザ内 tlock 復号は qub 埋め込み内で適用されます: 封印された qub がサードパーティページ上の <qub-embed> を通じて描画されるとき、復号は依然として閲覧者のブラウザ内の埋め込み iframe で行われます。埋め込みは信頼モデルを変更しません — 平文が qub サーバーで復号されることは決してありません。

3.6 公開帰属 — オプトイン

封印された qub は、作成者が明示的にそれを添付することを選択しない限り、作成者へのオンチェーンポインターを持ちません。qub を封印すると、リファレンスアプリは、日付ピッカーステップで「公開帰属」が有効になっている場合にのみ、Author ストレージタグ(あなたの署名公開鍵の 64 文字の 16 進フィンガープリント)を発行します。トグルがオフ(デフォルト)の場合、Author タグは書き込まれず、qub は永久ストレージ上で無帰属となります: ストレージ上の何も、アップロードをあなたのハンドル、メール、または他の qub にリンクしません。トグルがオンの場合、フィンガープリントは §6.3 / §10 の認証チェーンを介してあなたの @handle に解決され、ビューアーカウントダウンは公開前に「@{handle} が封印」を表示します。

これは、常時オンの Author タグが作り出す列挙リスクに対する意図的な防御です: 作成者のフィンガープリントを学んだ第三者は、タグで永久ストレージを検索し、その作成者の完全な歴史的出力を再構成できる可能性があります。オプトイン帰属はそのチャネルを閉じます — 作成者が明示的に帰属することを選択した qub のみが、永久ストレージ上のフィンガープリントの下に現れます。

/u/{handle} プロフィールページは検証済み ID カードです — ハンドル、オプションの表示名 + URL、「検証済みメール」ピル(アドレスなし)、および暗号フィンガープリント短形式。作成者の qub をリストしません。作成者の特定の qub を見たい訪問者は、その qub の配信 URL を直接フォローします。

3.7 外側の暗号ラッパー

タイムロック復号が数学的に可能になった後でも — つまり、結合されたラウンドの drand 署名が公開された後でも — 正規タイムロックレイヤー単独では、インデクサーが発見可能な qub を一括復号できてしまいます。非公開配布は、タイムロック暗号化バイト列を囲む追加の対称レイヤー(プロトコル §13)によってそのチャネルを閉じます。公開配布では、通知、埋め込み、発見用リンクを秘密フラグメントなしで機能させるため、意図的にラッパーを省略します。

ラッパーは AES-256-GCM を使用します。これは NIST 標準化された認証付き暗号で、新鮮な 256 ビット鍵 K がブラウザの CSPRNG により qub ごとに生成されます。K は認証付き追加データとして qub の qub_id にバインドされるため、ある qub の鍵を別の qub の復号に再利用できません。

既定の非公開ブラウザフローでは、K は当社サーバーに到達しません。 これは共有リンクの URL フラグメント(https://qub.social/c/<tx_id>#<base64url(K)>)にエンコードされます。ブラウザは URL フラグメントをサーバーに送信しません — RFC 3986 はフラグメントをリクエストの外に置きます — したがって、そのフローでは qub.social、ストレージゲートウェイ、CDN、リクエスト監視のいずれも K を認識しません。保存された OuterWrapper は認識可能な構造化 CBOR ですが、認証付き暗号文フィールドが内側の SealedQub 構造を隠しており、K なしでは開けません。

正味の帰結:

Worker のサーバーサイド /api/v1/seal エンドポイント(AI エージェントや他の API 呼び出し元が使用)は、呼び出し元に対し、CSPRNG で K を生成し、ローカルに保持し、wrapper_key_b64url として供給することを要求します。Worker はこの明示的に信頼されるパスにおいて、必然的に平文と K の両方をメモリ内で目にしますが、そのいずれも永続化しません。必須の Idempotency-Key は、失われたレスポンスが 2 つ目の課金対象 qub を作成することを防ぎ、その一方で呼び出し元が保持する K は、再送されたフラグメントなしの URL と組み合わせることができます。これはデフォルトのブラウザパスとは異なります。ブラウザパスでは、作成者が明示的に復旧を有効にしない限り、K が Worker に到達することはありません。


4. トランスポートとエッジ

4.1 TLS

qub へのブラウザトラフィックは、Cloudflare エッジで HTTPS により配信されます。レスポンスには HTTP Strict Transport Security(max-age=63072000; includeSubDomains; preload)を設定します。実際にネゴシエートされる TLS バージョンと暗号スイートは、アプリケーションコードで断言するのではなく、稼働中のエッジ構成により決まります。個別に到達可能なオリジンサーバーは公開していません。

4.2 コンテンツセキュリティ

コンパイルされたクライアントは厳格なコンテンツタイプおよびキャッシュヘッダーで提供されます。SPA シェルは単一オリジンです。アナリティクスや広告のためにサードパーティスクリプトを埋め込みません。プロダクトの 2 つのサードパーティタッチポイントは両方とも狭く範囲されています: 購入フローはフルページリダイレクトで SPA を完全に離れて Stripe ホストのチェックアウト(https://checkout.stripe.com/…)に進みます — Stripe の UI は当社オリジンで実行されることはなく、カードデータを見ることもありません — そして封印フローは Cloudflare の Turnstile ウィジェットをロードします。これは Cloudflare が独自のサンドボックス化された iframe 内で描画するプライバシー保護 CAPTCHA 代替です。どちらの当事者もページの残りを読めません。

qub 埋め込み iframe(qub.social/embed/{tx_id} から提供され、embed.js によりサードパーティサイトにロードされる)は、独自の Content-Security-Policy を持ちます。その connect-src 許可リストは 'self'、https://qub.social、https://arweave.net、https://ar-io.dev、https://permagate.io、https://api.drand.sh、https://drand.cloudflare.com です。iframe は sandbox="allow-scripts allow-top-navigation-by-user-activation"(allow-same-origin なし)で実行されます。ホストページはその DOM を読めず、iframe はユーザー操作後を除いてホストをナビゲートできません。

4.3 CORS およびフェッチスコープ

ブラウザクライアントは以下にのみフェッチリクエストを行います:

埋め込みの宛先は CSP により強制されます。メイン SPA の宛先はコードと構成に固定され、ブラウザおよび統合チェックで検証されます。Subresource Integrity はネットワーク宛先の制御ではありません。

埋め込みは、許可リストにある qub / ストレージオリジンを通じて保存済みバイト列を取得し、URL フラグメントの K を使って非公開ペイロードをブラウザ内でアンラップし、許可リストにある 2 つの drand オリジンから公開時のラウンド署名を取得します。メイン SPA は config/drand-endpoints.json の 4 エンドポイント(drand.cloudflare.com、api.drand.sh、api2.drand.sh、api3.drand.sh)をフォールバックとして使用するため、1 つの停止で公開が妨げられることはありません。埋め込みの CSP は明示されたリスト外への接続を拒否します。


5. サーバーサイドインフラ

5.1 サーバーレスエッジ

当社の API はエッジでマネージドサーバーレスランタイム上で完全に実行されます。VM、コンテナ、当社が管理する永続サーバープロセスはありません。これは、当社が責任を負う攻撃対象を劇的に削減します: 当社は OS、Web サーバー、または当社がパッチを当てなければならないアプリケーションランタイムを実行しません。

別のパブリックCORSミドルウェアが適用されます Access-Control-Allow-Origin: * 次の実装されたパスセットへ: /embed.js、 /embed/v1.js、その下のすべて /embed/; /api/v1/telemetry; /api/v1/openapi.json;すべての下 /api/v1/qub/ (バイト、メタデータ、証拠、関与、通知、およびプッシュサブルートを含む);その下のすべて /api/v1/log/; 公共のハンドル検索の下で /api/v1/handle/;そしてパブリックアバターは下に読みます /api/v1/identity/avatar/その事前飛行許可 GET、 POST、そして OPTIONS と一緒に Content-Type リクエストヘッダー。この接頭辞ベースのサーフェスは、現在埋め込みが行っている呼び出しだけに限定されるものではないため、これらの接頭辞の下にあるすべてのハンドラーは、自身の検証、認証、レート制限、および不正使用の制御を引き続き実施する必要があります。他のAPIパスは、qub.social-制限付きCORSポリシーを保持します。

5.2 ストレージ

既定のブラウザメッセージフローは、qub インフラに平文を永続化しません。Builder の /api/v1/seal は平文と K をメモリ内で扱いますが、どちらも永続化しません。約定のステージングは、共同署名、撤回、または期限切れまで、署名済みの構造化約定を必然的に保存します。オプトイン復旧では、後から復旧できるよう、配布能力(フラグメントを含む完全なリンク)を保存します。したがって、ストレージ層全体を「メタデータのみ」とは表現しません。

5.3 シークレット

シークレット(署名ウォレット、プロバイダートークン、HMAC 鍵)は、ソース管理ではなくプラットフォームのシークレット / 環境バインディングを通じて供給されます。実行時コンポーネントには、必要なバインディングだけが与えられます。ローテーションと重複期間の手順はコンポーネントごとに異なり、単一の普遍的な自動または監査済みローテーション機構があるとは主張しません。

5.4 ロギングとテレメトリ

構造化された JSON ログがすべての API リクエストに対して書き込まれ、X-Request-Id レスポンスヘッダーに相関 ID が表示されます。クライアントテレメトリは匿名です — 端末識別子なし、IP アドレスなし、コンテンツプレビューなし。イベントはメモリにバッファされ、ベストエフォートでフラッシュされます。失敗したフラッシュは破棄され、再試行されません。テレメトリは、プロダクトに影響を与えずにネットワーク層で無効化できるよう設計されています。


6. 認証

6.1 マジックリンクサインイン

サインインは、メール受信箱へ配信される単回使用の HMAC 署名トークンを使用します。リンクは 15 分間有効で、引き換えはアトミックに確保されるため、同時使用や再使用は fail closed になります。成功すると、ブラウザは Secure、HttpOnly、SameSite=Strict、Path=/ 属性を持つ不透明な __Host-qub_session Cookie を受け取ります。

セッションには 30 日のアイドル上限と 90 日の絶対上限があり、24 時間後にローテーションされます。レスポンス喪失に備える 120 秒の猶予期間では、直前の世代だけを受け入れます。機密性の高いアカウント変更には、直前 10 分以内の認証が必要です。HMAC 署名シークレットはプラットフォームバインディングであり、メタデータのみの読み取りから有効なトークンを発行することはできません。

6.2 API キー(開発者ティア)

開発者 API キーは、簡単な認識と grep 可能性のために接頭辞 qub_sk_ を使用します。各キーは:

管理者キー管理エンドポイントは、別の管理者資格情報の背後でゲートされています。

6.3 メール認証(作成者署名)

メールアドレスを署名鍵にバインドするには:

  1. 秘密署名鍵の保有(チャレンジに署名)
  2. メール受信箱の保有(メールで配信される 6 桁のコードを入力)

いずれか単独では不十分です。失効はあなた自身のアカウント上の署名された記録であり、即座に発効します。認証をフェッチする閲覧者は失効状態を見て、それに応じて表示します。


7. 決済

カード情報の入力と処理は Stripe がホストするチェックアウト内で行われます。当社がカード番号、有効期限、CVC を受け取ることはありません。アクセス、更新、従量課金、解約、返金を照合できるよう、Stripe の顧客・サブスクリプション識別子、サブスクリプション状態、期間データを権利 / API キー記録に保存します。Stripe のプライバシーおよびセキュリティ声明が、その決済データの取り扱いを規定します。

封印エンドポイントは、権利記録を端末識別子と、サインインしたユーザーの場合はリンクされた ID とクロスチェックします。マジックリンクサインインを介して明示的に復元しない限り、権利は端末をまたいで再利用できません。


8. 不正対策

8.1 ボット検出

封印フローは、トラッキングのためにクッキーを使用せず、広告のためにフィンガープリンティングを行わないプライバシー保護 CAPTCHA 代替によりゲートされています。失敗したチャレンジは、封印側の処理が行われる前にエッジ Worker により拒否されます。

8.2 レート制限

レート制限は複数のレイヤーで施行されます:

カウンターとアトミックな確保は、エンドポイントの整合性要件に応じて KV、Durable Objects、プラットフォームのレート制限バインディングに分散されます。制限された要求は 429 を返し、再試行可能時刻を計算できるエンドポイントでは Retry-After も含めます。

8.3 コンテンツモデレーション

デフォルトのブラウザアップロード経路はボディをスキャンできません:クライアントがシールしたアーティファクトのみを受け取ります。ビルダー /api/v1/seal ルートは平文を一時的に見ますが、パクトのステージングは最終決定まで構造化された条件を保持します。しかし、それらの信頼例外は、一般的なバイトブラインドのアップロード経路をコンテンツスキャナーに変えることはありません。運用上のモデレーションは 拒否リスト ビューアレイヤーでは、拒否リストに登録された qub は、保存されているペイロードがまだアクセス可能であるかどうかにかかわらず、ビューアによって拒否されます。拒否リストに登録することは、既に公開されている永続的なバイト、透明性ログのエントリ、または永久ネットワークデータを取り下げることはありません。

不正報告は、報告者の IP の一方向ハッシュを使用してレート制限されます。私たちはこの目的のために IP を平文で保存しません。


9. サプライチェーンとビルドの完全性

9.1 ツールチェーンの固定

コンパイラーとランタイムのバージョンはリポジトリ構成に固定され、依存関係はコミット済みのロックファイルで解決されます。CI は生成ファイルの鮮度と再現性に関わる不変条件を検査します。すべての対応マシンで、あらゆるクリーンビルドがビット単位で同一になるという、より強い主張はしません。

9.2 lint と静的解析

ワークスペースは最も厳格な lint グループを deny レベルで有効化します。CI はすべての警告 — ドキュメントリンク警告を含む — をビルド失敗として扱います。これは意図的です: 微妙なレグレッションのトリップワイヤーとして lint の厳格さを使用します。

9.3 CI ゲート

CI ワークフローは、フォーマットと厳格な lint、Rust、WASM / ブラウザ、Worker、埋め込み、API の各テスト、型チェック、コードカバレッジ、ミューテーション / 不変条件チェック、依存関係とワークフローの静的解析、i18n のキー・カバレッジ・ドリフト・敵対的コードポイント検査、生成ドキュメント / API / ナレッジベースの鮮度、ドキュメント目録と内部リンク、スタイルシートとバンドルの予算、OpenAPI 検証を対象とします。高コストなミューテーションジョブの一部は、プッシュごとではなくスケジュール実行されます。

単一の必須 ci 集約ジョブは、いずれかの必須ジョブが失敗している間は赤のままです。保護ブランチとデプロイワークフローは、より小さなセキュリティゲートを重複させず、その結果を利用します。

9.4 ミューテーションテスト

週次ジョブはセキュリティ重要な純粋モジュール(ハッシュ、正規 CBOR、封印、解除、ワイヤーフォーマットの newtype、プロトコルタイプ検証器、ハンドル名前空間)に対してミューテーションテストを実行します。ミューテーションテストは「テストスイートは微妙に間違ったコードをキャッチするか?」に答えます — 変異した実装が依然としてすべてのテストに合格する場合、テストカバレッジのギャップがあることがわかり、それに対処します。

9.5 Git フック

ローカルフック(pre-commit、pre-push)は CI ゲートをミラーリングし、レグレッションが開発者のマシンを離れる前にキャッチされます。フックはリポジトリスクリプトを介してインストールされます。当社のワークフローでバイパスされることはなく、スキップされた場合は CI が正式なゲートです。


10. テスト

セキュリティ重要なコードには 3 種類のテストが含まれます:


11. ブランチとリリースの衛生

機能ブランチは Gate 1 のプルリクエストを通じてのみ staging を進めます。必須 ci が緑で、未解決の変更要求やマージ競合がなく、レビュー済みツリーがクリーンであることが条件です。マージは squash し、ブランチを削除します。main は Gate 2 の staging → main プルリクエストを通じてのみ進み、マージコミットで祖先関係を保持します。ブランチへの直接 push はリリース手順ではありません。

ステージングと本番のデプロイは、CI 後の対応する保護済み staging / main ブランチ状態から起動されます。プルリクエストコードやフォークの資格情報にはデプロイ用シークレットが与えられません。

デプロイワークフローで使用されるシークレットは、当社の CI プラットフォームによりデプロイ環境にスコープされています。これらはフォークからのプルリクエストワークフローには利用できません。


12. 協調的開示

qub にセキュリティ脆弱性を発見したと思われる場合、できるだけ早くそれを聞きたく、報告をプロフェッショナルに処理することをコミットします。

3 営業日以内に受領を確認し、調査中も情報を提供します。同意があれば、リリースノートで報告者にクレジットします。

12.1 セーフハーバー

研究が上記のルール(誠実な調査、他のユーザーやサービスへの害なし、合理的な開示ウィンドウ)に従う場合、法的措置を取ることはなく、法執行機関に依頼することもありません。あなたの作業を承認されたテストとして扱い、他の誰かではなくあなたにバグを見つけてほしいと考えます。

このセーフハーバーは以下に適用されます:

qub チームメンバーへのソーシャルエンジニアリング、サービス拒否テスト、または問題の実証に必要な範囲を超えて他のユーザーのデータにアクセスすることには適用されません。何かがセーフハーバーの中に入るかどうか不明な場合は、同じ [SECURITY] 件名接頭辞を使用して最初にお尋ねください。


13. 誠実な限界

セキュリティは状態ではなく、実践です。直接名前を挙げる価値のある限界がいくつかあります:


14. このページの変更

重大な変更は、上部の発効日を更新することで記載されます。変更が具体的なセキュリティ改善を反映する場合、公開チェンジログで簡潔に説明します。変更がポリシーの明確化を反映する場合、何が変わったかとその理由を説明します。

このページに関する質問については、件名の接頭辞 [SECURITY] を付けて support@qub.social にメールしてください。


15. 変更履歴

バージョン 発効日 概要
1.1 2026 年 9 月 23 日 暗号学的主張、配布モード、ストレージ、CSP、セッション、API キー、決済、CI、リリースワークフローを実装済みシステムと照合しました。
1.0 2026 年 5 月 2 日 初版公開。