本文へ移動

2026-08-01 時点の資料です。読みやすさのために、一部の文字の色を濃くしています。

設計の背景/ Why This Design

この仕組みが引き受けた課題と、そこから決まった構成

共有リンクは「アカウントを持たない相手に、こちらのファイルを渡す」という、アプリの中で最も外に開いた機能です。開いた分だけ設計の制約も強くなります。ここでは、何を解決するために作ったのか、なぜ受取ページを本体と別のホストに置いたのか、そしてログインという手がかりが無いまま何を積み上げたのかをご説明します。

01

解決する業務課題The Problem

取引先とのやりとりには、継続的なものと単発のものがあります。継続的なものは Box に招待して共同で扱えばよいのですが、「この 1 件を渡すだけ」に同じ手間はかけられません。かといってメールに添付すると、渡したあとの制御が一切効かなくなります。

単発の受け渡しに使える手段の比較
観点メール添付Box へ招待共有リンク
相手の準備不要アカウント作成と招待の受諾が必要不要(URL を開くだけ)
扱えるサイズ数 MB 程度で弾かれるアップロードの上限までアップロードの上限まで(フォルダは ZIP のしきい値あり)
渡したあとの取り消しできないメンバーから外せるいつでも無効化できる
期限なし(相手の受信箱に残り続ける)なし最長 14 日で自動的に開かなくなる
受け取りの確認できない操作履歴で分かる開封とダウンロードが記録される
ウイルス検査相手のメール環境まかせ取り込み時に検査済み検査済みのファイルしか渡せない

共有リンクは、この表のいちばん右の列を実現するための機能です。相手には手間をかけず、こちら側は「いつまで・何回・誰に・どこまで」を握ったまま渡す。渡したあとに気が変わったら止められる。これが引き受けた課題です。

02

公開ホストの分離The Public Host

受取ページは、本体アプリ portal.example.com ではなく inbox.portal.example.com という別のホスト名で公開しています。同じアプリの一部でありながらホストを分けたのは、次の 3 つを同時に成立させるためです。

分けて得られること内容
Cookie の分離ブラウザの Cookie はホスト名で区切られます。ホストを分ければ、社員のログインセッションの Cookie が公開面へ構造的に出ていきません。受取ページが使う Cookie も、その受取ページ専用の短命なものだけになります。
防御設定の独立公開面は本体より攻撃を受けやすいため、上限を厳しくしたい一方で、社員の通常業務を巻き込みたくありません。ホストが分かれていれば、Cloud Armor のルールもレート制限も公開面だけに強くかけられます(公開面は本体より厳しい IP ごとのレート制限にしています)。
公開する経路の限定共有リンクのために公開ホストへ通しているのは /s/{token}(受取ページ)と /api/share-links/*(状態確認・照合・URL 発行)の2 経路だけです。本体 API 全体は、このホストからは到達できません。

分けた分だけ構成が増えるかというと、そうではありません。DNS は同じゾーンで管理し、負荷分散は 1 台のロードバランサがホスト名を見て振り分けます。証明書も 2 ホスト分を 1 枚にまとめた Google マネージド SSL です。増えるのは「ルール」だけで、運用する部品は増やしていません。

受取ページから本体へのリンクについて: 受取ページの下部にある利用規約・プライバシーポリシーなどのリンクは、公開ホストの相対リンクではなく本体ホストへの絶対 URLにしています。相対リンクにすると、その瞬間に公開ホスト側へ 2 経路以外のページが生えてしまうためです。
03

アカウント不要の受け渡しAccess Without Accounts

受け取る側はログインしていません。つまり「誰が来ているか」をアカウントで判断できないまま、正しい相手には確実に渡し、それ以外には渡さない必要があります。この矛盾は、1 つの強い仕掛けではなく、性質の違う手がかりを重ねることで解いています。

手がかり何を確かめているか単独では足りない理由
推測できない URLその URL を知っていること転送されれば誰でも知りうる
パスワードURL とは別の経路で伝えた合図を知っていることURL と一緒に伝えてしまえば意味がない(だからシステムからは送らない)
受取人の本人確認指定したメールアドレスを受信できることそのメールボックスを見られる人には通る
有効期限渡してからの経過時間期限内であれば止まらない
ダウンロード回数受け取られた回数回数内であれば止まらない
レート制限とロック試行の速さと失敗の多さ正しい合図を知っている相手は止められない

どれも単独では破れます。しかし破り方が互いに違うため、重ねると全部を同時に満たす必要が生まれます。URL を手に入れただけでは開けず、パスワードを推測しようにも速さで止められ、時間をかけようにも期限が来る。この「手口の異なるものを重ねる」考え方が、この機能全体の背骨です。実装の詳細は防御の設計で扱います。

パスワードをシステムから送らない理由: 案内メールに URL とパスワードを両方書けば、そのメール 1 通が漏れた時点で両方が漏れます。パスワードを別の手がかりとして機能させるには、URL とは違う経路で伝わる必要があります。そのため案内メールの本文には「パスワードは発行者から別の連絡手段でお受け取りください」という固定の案内だけを入れ、値そのものは載せません。
04

設計の四原則Design Principles

個々の判断で迷ったときに立ち返っている 4 つの原則です。この先の各ページで出てくる「一見まわりくどい作り」は、たいていこのどれかに由来しています。

1. 検査済みのものだけを渡す

共有リンクで渡せるのは、ウイルス検査を通過(検査済み)したファイルだけです。検査中・検査に失敗・隔離されたファイルは、発行時に対象として選べないだけでなく、データベースの読み取り範囲そのものから外れています。発行後にファイルが差し替えられた場合も、受取人に見えるのは検査済みの最新版だけです。

2. 失効は不可逆、編集はさせない

発行したリンクはあとから編集できません。期限を延ばす、回数を増やす、受取人のメールアドレスを変える、いずれも用意していません。条件を変えたいときは、無効化して発行し直します。無効化も取り消せません。

これは画面でボタンを出していないだけではありません。ログインした利用者がデータベースに対して書き換えられるのは「無効化した日時」と「無効化した人」の2 つの列だけで、期限や回数の列は権限そのものが与えられていません。仮にアプリ側に穴があっても、条件の書き換えはデータベースが拒みます。

3. 記録は必ず残す

受取ページで起きたことは、成功も失敗もすべて記録します。開封(受取画面に着いた)・ダウンロード・パスワードの誤り・確認コードの誤り・期限切れ後のアクセス・無効化後のアクセス・回数上限・アクセス集中による制限、そして存在しないリンクへのアクセス。記録しているからこそ異常を自動で見つけられます(記録と異常検知)。

4. 止める手段を常に用意する

止められる人を 3 層に用意しています。発行者本人と Box の Owner はいつでも無効化でき、全社の管理者は発行者の意向に関わらず強制的に失効させられます。加えて、元のファイルやフォルダを削除したとき、Box を無効化したときには、それを指す共有リンクが自動的に無効になります(管理機能)。

4 つの原則が同じ方向を向いていること: いずれも「渡したあとに困らないこと」を守っています。渡すのは検査済みのものだけ、条件は後から緩まない、何が起きたかは残る、いつでも止められる。この 4 つが揃っているので、発行する側は細かく悩まずに渡せます。