2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

他の投稿はこちら

TL;DR

  • 非保持型権限委譲 = アプリやデバイス側にトークン等の認証情報を一切持たせない権限アーキテクチャ(特許第7870515号)
  • 認証済みセッションと暗号通信路をサーバー内部でペアリングし、この対応関係が成立している間だけ権限が存在する
  • トークンがないので、盗まれる・漏れる・失効管理する、という問題が発生源ごと消える

はじめに

.envにAPIキーを書いたことのある人なら、一度は冷や汗をかいたことがあると思います。うっかりGitHubにpushしたキーは数分でクローラーに拾われますし、pushしなくても、アプリに保存したトークンは端末ごと盗まれれば使われます。退職した人が持っていたキー、全部ローテーションしましたか?

私たちはこれを「気をつける」で守っています。.gitignoreに入れる、Secret Managerという金庫に仕舞う、有効期限を短くする、端末に縛る、漏れたらすぐ止められるようにする。対策はどんどん堅牢になっていますが、全部トークンを守る方法です。どれだけ金庫を頑丈にしても、中に価値ある物が入っている限り、盗まれる可能性があります。

そこで考えたのが、アプリにトークンを渡さずに、ログイン済みのユーザーの権限で動かす方法です。

0. Webとネイティブアプリの連携

Webアプリからローカルのネイティブアプリを呼び出して、サイレント印刷やUSB機器の操作をさせる——そんな構成を以前の記事で紹介しました。

では、そのネイティブアプリに「ログインしたユーザーにだけ使わせたい」というアクセス制限をかけたい場合、どうすればよいでしょうか。

1. 従来方式の課題 — 「再利用可能な資格情報」という構造問題

Webアプリ側でユーザーがログイン済みでも、ネイティブアプリは別プロセス(あるいは別端末)です。ログイン状態をそのまま共有できないため、ID・パスワードやアクセストークンを別途持たせることになります。

これは、ネイティブアプリ側に後から再利用できる資格情報を置く方式です。

サーバー側のパスワードはハッシュ化して元の値を持たずに済みます。一方、再ログインに使うアプリ側では、暗号化して保存しても実行時には復号して使います。保存場所を守れても、盗む価値のあるものが端末に存在するという構造は変わりません。

2. 発想の転換 — セッション・通信路ペアリング

本モデルは、権限の置き場所を端末からサーバー内部へ移します。

システムを、ユーザーをサーバーが認証する認証層と、ネイティブアプリとサーバーが暗号通信を行う権限委譲層に分け、両層を論理的に独立させます。ネイティブアプリは、ID・パスワードもアクセストークンも保持しません。代わりに、サーバーが次の対応関係を動的に管理します。

fig1_pairing.png

権限は、この対応関係が成立している間だけ、サーバー内部に存在します。

3. システム構成と処理シーケンス

本システムは、サーバー、ブラウザ(中継)、ネイティブアプリの3つで構成されます。処理の流れは以下の通りです。

fig2_sequence.png

流れは大きく3段階です。

  1. ブラウザでログインし、ネイティブアプリが作った暗号通信路を、そのセッションとサーバー内で結び付ける。
  2. ブラウザから「印刷して」と要求すると、サーバーが命令を暗号化してアプリへ送る。
  3. アプリが復号して実行し、結果を暗号化して返す。ブラウザはサーバーから画面表示用の結果を受け取る。

従来ネイティブアプリが自ら行っていた認証を、ブラウザの認証済み経路に「相乗り」する形で担保している、と見ることができます。

ここでブラウザは、サーバーとネイティブアプリ間の暗号化データを中継しますが、復号する機能を持ちません。中身の読めない「土管」です。

この構成が作り出す性質 — 相互不可知

土管化の帰結として、次の状態が成立します。

  • ブラウザは、自分が何と何を繋いだのかを知らない。 セッションと暗号化された鍵を運ぶだけで、権限の中身に触れられない。
  • ネイティブアプリは、自分が誰として繋がったのかを知らない。 鍵は持つが、セッションIDも認証資格情報も一切受け取らない。
  • 両方を知っているのは、サーバーの対応管理だけ。

認証と認可の「分離」は昔から提唱されてきましたが、既存方式の分離は責務の分離にとどまり、認証の成果物(トークン等)は結局、実行側へ渡っていました。本モデルは、認証の成果物が実行側に一切流れない、情報の流れのレベルでの分離を実現します。

4. 何が嬉しいのか

① 盗む対象が端末から消える

ネイティブアプリが保持するのは、自ら生成した鍵情報だけです。鍵単体では権限は成立せず、サーバー側の対応関係と揃って初めて有効になります。「盗まれると困るもの」を守るのではなく、盗む対象そのものを端末から無くす防御です。しかもユーザーから見れば、ブラウザでログインするだけでアプリが使える——安全性の向上と導入の簡素化が同時に成立します。

② 中継経路を信頼しなくてよい

権限委譲層の機密性は、中継するブラウザや途中経路の安全性に依存しません。仮に中継経路が平文であっても、委譲される権限データと鍵は暗号化されたまま通過します(なお認証層のセッション保護は、従来どおりTLSで行います)。ブラウザ拡張や開発者ツールが通信を覗ける環境でも、権限の中身は読めません。

③ トークン運用そのものが消える

OAuthやAPIキー方式では、配布したトークンについて有効期限、リフレッシュ、失効伝播、保存場所の保護、端末ごとの棚卸しを考え続ける必要があります。本モデルではトークンを配布しないため、これらの運用が発生しません。権限を止めたいときは、端末に散ったトークンを回収するのではなく、サーバー側の対応関係を一行消すだけです。失効が分散問題ではなく局所操作になります。

④ 片側奪取では権限を再構成できない

認証する端末と実行する装置が物理的に離れている場合——ドローン、車載装置、工場設備、IoT機器——この設計の効果が最も鮮明に現れます。

操作端末が持つのは認証済みセッション、実行装置が持つのは暗号鍵。どちらか一方を奪っても、権限の素材は揃いません。 実行装置が奪取され、メモリから鍵を抜かれたとしても、その装置単体ではセッション側の素材を欠くため、権限主体として機能できないのです。

一部の素材をコピーしても、サーバー内の対応関係を別環境で再現することはできません。漏洩を起点にした横展開も成立しにくくなります。

⑤ 監査が「誰の認証で、どの装置が、何をしたか」で語れる

権限の成立点がサーバー内部にあるため、誰の認証済みセッションが、どの実行端点に紐付き、その結果として何が実行されたかを、一貫した記録として残せます。

5. OAuth・ゼロトラストとの本質的な違い

OAuthとの違い — スナップショットか、生きた関係か

OAuthのアクセストークンは、発行時点の権限を切り出したスナップショットです。トークンを持つ主体は、その有効期間中、発行時の権限を提示によって行使できます。だからこそ失効の伝播やリフレッシュという管理問題がついて回ります。

本モデルの権限は、行使のたびにサーバー内の対応関係を参照して成立する生きた関係です。実行主体も認証主体も単独では権限を持たず、各主体の素材がサーバーで組み合わさった瞬間にだけ権限が発現します。トークンを強化するのではなく、「権限の引換券を配る」という設計そのものを無くしている——ここが各種のトークン改良方式との決定的な違いです。

ゼロトラストとの違い

ゼロトラストは「ネットワーク境界を信頼せず、アクセスごとに検証する」思想です。本モデルはこの思想と高い親和性を持ちますが、分割する対象が異なります。ネットワークの内外ではなく、権限の成立条件そのものを認証層と権限委譲層に分割し、両層をサーバー内部で組み合わせる。ゼロトラストの検証原則を、資格情報の配布なしに実装する一つの解、と位置付けられます。

6. トレードオフ — 何を手放しているか

権限行使のたびにサーバー側の対応関係を参照するため、トークン方式が持つ検証のオフライン性・自己完結性はありません。 リソース側がトークン署名だけで検証を完結できる方式に比べ、サーバーの可用性と参照性能への依存が生まれます。

したがって本モデルが最も効くのは、即時失効・資格情報レス・奪取耐性が性能コストに見合う領域——特権操作、遠隔制御、物理的に奪取されうる装置、監査要件の厳しい環境——です。

7. Webの枠を超える — 「分散セキュアIPC」への一般化

ここまで「ブラウザ」と「ローカルPCのネイティブアプリ」というWeb連携の形で説明してきましたが、このアーキテクチャの本質はWebスタックに閉じていません。

「サーバー」「中継クライアント」「ネイティブアプリ」という名称は機能的役割を指す呼称であり、装置形態・通信プロトコル・物理配置に縛られません。一歩引いて見れば、これは中継経路の安全性を前提にしない、汎用的な分散セキュアIPC(プロセス間通信)フレームワークとして抽象化できます。

応用① スマートフォンによる共有設備の一時操作

利用者はスマートフォンアプリで認証されます。設備側のQRコード、NFCタグ、BLEビーコンを読み取ると、サーバーが「この認証済み利用者」と「この設備の通信路」を一時的に対応付けます。宅配ロッカーの指定扉を一度だけ開ける、会議室機器を一定時間だけ有効化する、といった操作がこれで成立します。

利用者の認証情報は設備へ渡らず、設備の鍵はスマートフォンへ渡りません。権限はどちらの端末にも保存されず、サーバー上の一時的な対応関係としてのみ存在します。

応用② 管理対象端点への一時的な操作委譲

企業内PCや工場設備にエージェントを置き、管理者の認証と承認に基づいて、診断ログ取得や設定変更を一時的に許可します。入口はWeb管理画面でもCLIでも構いません。実行端点に管理者のトークンや保守用パスワードを保存せず、「誰の承認で、何をしたか」をサーバーに残せます。

応用③ バックエンド処理からの一時的な実行委譲

認証主体は人間である必要もありません。CI/CDパイプラインや監視システムと、デプロイ対象サーバーやロボットの通信路を対応付ければ、長期トークンを実行端点へ配らずに操作を委譲できます。自律エージェントへ一時的・条件付きの権限を与える場合も、同じ構造が使えます。

まとめ

非保持型権限委譲は、「認証資格情報の永続化リスク」と「中継環境の脆弱性リスク」を、運用ではなく構成の力で無効化するアーキテクチャです。

権限を端末に持たせるのではなく、セッションと通信路のペアリングによって、サーバー内部の対応関係として成立させる。認証する側と実行する側は互いを知らず、両者を結ぶ知識はサーバーにしか存在しない。

この「認証の成立条件」と「実行の成立条件」の分離は、物理配置やスタックに依存しない設計思想として、特権操作・遠隔制御・自律エージェントといった、これからの分散システムが直面する権限管理にそのまま適用できます。

Q&A

Q. ただのセッション管理と何が違うの?

Cookieセッションは「認証した主体=実行する主体」が前提です。

本モデルは、認証する主体(ブラウザ)と実行する主体(ネイティブアプリ)がで、互いの秘密を知らないまま、サーバー内部でだけ結び付きます。セッションと暗号通信路を「ペアリング」し、違う主体にまで権限を延長する技術と言えます。

Q. ネイティブアプリのメモリから鍵を抜かれたら終わりじゃないの?

鍵単体では権限が成立しません。権限の行使にはサーバー側の対応関係、つまりセッション側の素材も必要だからです。操作する端末と実行する装置が分かれていれば、鍵を抜かれた装置だけでは素材が揃いません。

Q. ブラウザのセッションを乗っ取られたら意味なくない?

セッション乗っ取りへの防御は、従来どおりTLSやCookieの保護で行います。そこはこのモデルの守備範囲ではありません。

このモデルが保証するのは、中継やアプリ側から認証情報・鍵・権限データが漏れないこと、そして漏れた断片を別環境に持ち出しても権限を組み立て直せないことです。

Q. localhostのWebSocketって、他のサイトからも繋げるよね?

はい。なのでOriginチェック等の対策は必要です(初回記事のQ&A参照)。

仮に悪意あるページが中継に相乗りしても、流れているのは復号できない暗号データです。悪意あるページはサーバーの認証済みセッションとの対応関係を持たないため、盗聴できず、権限も成立しません。

Q. 一番最初の鍵のやり取りで、中継が偽物の鍵にすり替えたら?

「最初の一回をどう信じるか」という問題です。ネイティブアプリが鍵を暗号化するのに使う「サーバーの鍵」は、アプリにあらかじめ埋め込むなどして固定します。中継が別の鍵に差し替えても、アプリはそれを受け付けません。

さらに、アプリに署名用の秘密鍵を持たせ、最初の鍵登録と以降の通信に署名を添える構成も取れます。サーバーは公開鍵で署名を確かめます。鍵の組を初回接続時にアプリ自身が生成すれば、秘密鍵は端末の外に出ず、インストールごとに固有の鍵になります。ただし初回だけは「このログインセッションで最初に登録してきたアプリ」を本物とみなし、二回目以降は署名によって同一性を確認します。

Q. 標準化されてるの? 他社サービスとは繋げる?

標準化はされていません。本稿は考案したアーキテクチャの解説であり、「非保持型権限委譲」という呼び方も本稿で導入したものです。

標準がないことは相互運用性の面でデメリットですが、組織を跨ぐ連携も、相手のサーバーとの間に暗号通信の関係を一本張れば成立します。連携解消のときはその一本を切るだけ。トークンを交換し合う方式との違いは、繋ぎ目に配布物が残るかどうかです。

Q. 実装が大変そう。特殊な暗号ライブラリとかが要るのでは?

使う部品はすべて枯れた既製品です。公開鍵暗号で鍵を運ぶ、共通鍵で暗号化する、ログイン状態をセッションで管理する、対応表を1つ持つ——どれも各言語の標準ライブラリや、普通のWebフレームワークに入っている機能で組めます。

新しいのは部品ではなく組み合わせ方です。

Q. オフラインでは何もできなくなるのでは?

いいえ。切れている間にできなくなるのは、サーバーとの新しいやり取り——新しい指示の受信や、データの送信——だけです。すでに受け取って復号済みの権限や指示に基づく動作は、切断中も継続できます。

鍵もセッションの有効期間中は保持して再利用できるので、通信が戻れば、再ログインなしで元の権限状態のまま送受信を再開できます。

切断中にどこまでの動作を許すかは、サーバーが権限を発行する時点で範囲や期限として制御できます。切断中に溜めたデータを、再接続時にまとめて暗号化して送る、という使い方も可能です。

という内容の

特許を取得しました。(特許第7870515号、国際出願中)

業務で当技術の利用を検討されている方は、お気軽にご相談ください。

関連記事

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?