⚖️

SOC 2 監査に耐えうる特権管理: 「代理操作」を支えるアイデンティティ分離と実装パターン

に公開

こんにちは。ログラス プロダクト基盤部の小林です。

私たちのチームでは、マルチテナント環境における「安全な代理操作」の仕組みについてアップデートを進めている最中です。今回は、その設計や検証の過程で整理した知見の一部をご紹介します。


「自分がこの操作をしたときだけエラーが出る。画面を見て調査してくれないか?」

B2B SaaSや業務システムを運用していると、こうした 「顧客の代わりにシステムを操作したい」 という要件に必ず直面します。突発的なトラブル対応はもちろん、特にエンタープライズ向けのSaaSでは、導入コンサルタントによる初期セットアップや、過年度データの移行支援など、顧客と並走して深くシステムに関わるシーンが頻繁に発生します。

こうした手厚い顧客支援のためには、エンジニアやCS担当者が顧客環境に「ログイン」できる機能が必要になることがあります。しかし、それは裏を返せば、ベンダー側の人間が顧客の機密データを自由に閲覧・操作できてしまう「スーパーユーザー(Super User)」としての特権を持つことを意味します。

「ユーザーからパスワードを聞き出す」「データベースを直接書き換える」といった運用は、論外のアンチパターンです。SOC 2 や ISMS といった現代のセキュリティ監査基準は、こうした属人的で追跡困難な操作を許容しません。

本記事では、この 「運用効率」と「データプライバシー」のトレードオフ を解消するために、代表的なSaaSプロダクトが採用している設計パターンを整理し、SOC 2 (Type II) を概観し、 RFC 8693 (Token Exchange) によるID分離や、RDBの整合性を保つ実装パターンについて解説します。

1. 代表的なSaaSに見る「同意」と「権限」の設計パターン

機能仕様の観点から主要なエンタープライズSaaSのアプローチは2つのパターンに分類できます。

1.1 Salesforce: ユーザー主導の厳格な同意モデル(Pull Model)

金融機関や医療機関など、極めて高いセキュリティ要件を持つ顧客に支持されているSalesforceは、「顧客が明示的に招待しない限り、ベンダーは一切アクセスできない」 という厳格なモデルを採用しています。

  • アカウントログインアクセスの許可
    • デフォルト状態では、Salesforceのサポートエンジニアであっても顧客データにはアクセスできません。
    • ユーザーは設定画面から、「Salesforceサポート」や「特定のアプリケーションベンダー」を指定して、アクセス権を付与(Grant)します。
    • 参考: Grant Salesforce Support login access to your organization
  • Time-Bound Access(期間限定)
    • この許可には必ず期限があります。「1日」「3日」「1週間」など、ユーザーが期間を選択します。
    • 期間が過ぎるとアクセス権は自動的に失効するため、「許可しっぱなし」によるリスクを防げます。
    • 参考: Grant Login Access - Salesforce Help

この「Pull Model(必要な時だけベンダーを引き入れる)」は、データ主権を顧客側に残すという意味で、非常に信頼性の高いアプローチと言えます。

1.2 HubSpot / Slack / Zendesk: 管理者制御と透明性(Push Model)

一方、コラボレーションツールやマーケティングオートメーションの分野では、「管理者が制御し、操作は全て監視する」 というアプローチが一般的です。

  • 管理者によるON/OFF制御
    • HubSpotやZendeskでは、組織の管理者が「サポートアクセス」の有効/無効を切り替えるトグルスイッチを提供しています。
    • 個々のユーザーではなく、組織全体(テナント)のポリシーとして管理させることが特徴です。
  • 透明性の確保
    • Slack(Enterprise Grid)などは Audit Logs API を通じて、ベンダーによるアクセス履歴を詳細に顧客へ提供しています。
    • 「事前承認」のハードルを少し下げる代わりに、「いつ、誰が、何をしたか」を事後的に完全に追跡可能(Traceable)にすることで、統制を担保する設計です。
    • 参考: Collect Slack Audit logs | Google Security Operations

2つのアプローチの比較:

アプローチ 代表的なSaaS 権限のトリガー アクセス期間 主なメリット
Pull Model Salesforce 顧客側の明示的な許可 一時的
(数日〜数週間等)
データ主権が完全に顧客側にあり、コントロール権を喪失しない
Push Model Slack, Zendesk, HubSpot テナント管理者によるON/OFF 原則として
常時ONなど要件次第
都度の許可フローがなく、スピード感のあるサポート対応が可能

私たちのようなマルチテナントSaaSベンダーにとって、代理操作機能の実装は利便性とセキュリティのバランスが難しく考慮事項が多岐に渡ります。そこでヒントになりそうなのが SOC 2 (Type II) です。実装すべき要件が網羅的に整理されていそうです。

2. SOC 2 に見る「特権アクセス」のあるべき姿

SOC 2 (Type II) などのセキュリティ監査基準は、「これを実装しなさい」という具体的な機能要件のリストではありません。セキュリティや機密保持といった「原則(Trust Services Criteria)」を定義しているものです。
しかし、現実の監査においては、例えば私たちが実装するSaaSの「特権アクセス」機能が、これらの原則を満たすための「内部統制(コンプライアンス)」として適切に機能するかが厳しく問われます。エンタープライズ向けSaaSが監査をクリアするために実質的に求められるベストプラクティスは、主に以下の4点です。

2.1 最小特権と承認プロセス (Least Privilege & Approval)

  • チケット連携: サポート担当者が顧客環境に入る際は、必ず「カスタマーチケット(問い合わせID)」と紐付いている必要があります。アクセス理由の正当性が求められます。
  • 承認ベース: 自動的な権限付与ではなく、上位者や顧客による明示的な承認(またはシステム上の申請フロー)を経て、初めて一時的な権限が発行される仕組みが必要です。

2.2 アクセス権のライフサイクル管理 (Lifecycle Management)

  • 自動的な剥奪 (Revocation): 退職者や異動者のアカウントがIdP(OktaやEntra IDなど)側で停止された場合、即座(理想的には24時間以内)にSaaS側の特権アクセスも無効化される仕組みが必要です。
  • 定期棚卸し: 「現在、誰が特権を持っているか」を四半期ごとにレビューできるレポート機能が求められます。

2.3 データ保護とセキュアなアクセス経路 (Data Isolation & Security)

  • 本番データの持ち出し禁止: 不具合調査のために本番データを開発環境へダンプすることは、個人情報保護の観点から厳格に禁止されます。だからこそ「本番環境の中で安全に調査できる」代理操作機能が必須になるのですが、そのアクセス経路自体も強固に守る必要があります。
  • MFAの強制: 代理操作を行うための社内管理画面やAPIへのアクセスには、VPNや多要素認証(MFA)を必須の前提とします。

2.4 操作の追跡可能性 (Traceability)

  • 監査ログ: 「誰が(Actor)」「誰のデータを(Subject)」「何のために(Ticket ID)」「どんな操作をしたか(Action)」が、改ざん不可能な形で記録され、長期間(一般的には90日〜1年以上)保持される必要があります。

ここからは、この「追跡可能性」をどう実装するか、技術的な側面にフォーカスします。

3. アイデンティティの分離と RFC 8693

たとえば Auth0 は、かつて提供していた単純な「User Impersonation」機能を、現在では Deprecated(非推奨・廃止) としています。(参考: Recommended alternatives to impersonation - Auth0 Community

管理者がユーザーのアクセストークンを単にコピーしてログインする方式は、監査ログにおける「真の実行者」の隠蔽につながるリスクが高すぎるためです。この課題を構造的に解決する標準仕様として、RFC 8693 (OAuth 2.0 Token Exchange) があります。

3.1 「トークン交換」の標準仕様としての位置づけ

RFC 8693 は「あるトークンを別のトークンに交換するためのプロトコル」です。このフレームワークの中で、Section 4.1 に規定されている act クレーム (Actorを表すクレーム) の概念を利用することが、代理操作における隠蔽問題を解決し「IDの分離」を適切に表現する標準的な手法となっています。

RFC 8693(および関連するOAuthの委譲パターン)の文脈では、実は「Impersonation(完全ななりすまし)」と「Delegation(権限委譲)」は明確に区別されています。単なるImpersonationでは元のユーザーと見分けがつきませんが、act クレームを含めるアプローチは仕様上 Delegation(委譲) と呼ばれ、「誰が誰の代理で動いているか」という監査証跡をトークン自体に埋め込むことができます。

  • sub (Subject): リソースの所有者(顧客ユーザー)
  • act (Actor): 実際に操作を行っている主体(サポート担当者)

この仕様に準拠した Delegation トークンを発行することで、責任の所在を明確に分離できます。

3.2 JWTペイロードの実装例と構造図

「サポート担当者が顧客のフリをする」という状態について、まずは代理トークンを取得する「認証(Token Exchange)」の流れを含めたシーケンスのイメージです。

代理操作中に実際に発行されるアクセストークンの例(ペイロード部分)は以下のようになります。

{
  "iss": "https://auth.saas-provider.com",
  // Subject: 振る舞う対象(顧客ユーザー)
  // 既存のバックエンドロジックはこの値を参照して動く
  "sub": "user_customer_123",
  
  "aud": "api-service",
  "exp": 1618037588,

  // Actor: 実際の操作者(サポート担当者)
  // 監査ログ基盤はこの値を参照して、操作の実行者を特定・記録する
  "act": {
    "sub": "agent_suzuki_999",
    "email": "suzuki@vendor.com",
    "role": "support_engineer"
  },

  // Scope: 権限の縮退(オプション)
  "scope": "read:only"
}

この設計の強みは、「互換性」と「追跡可能性」の両立です。

  1. 互換性: 既存のビジネスロジックは sub クレームを見るだけでそのまま動作します(例: order.user_id == token.sub)。代理操作のためにアプリケーション側の実装を大きく分岐させる必要がありません。
  2. 追跡可能性: 監査ログを出力するミドルウェア層などで act クレームをパースすれば、「実行者:鈴木(代理)」という正確なログを残すことができます。

4. データベースアクセスと外部キー制約の課題

RFC 8693 により、APIやマイクロサービス間では「誰が代理しているか」をきれいに伝播できるようになりました。しかし、Webサーバーを通過し、最終的に データベース(RDB) に到達した時点で、外部キー制約の問題に直面します。

4.1 外部キー(FK)制約の壁

多くのアプリケーションでは、データを誰が作成したか記録するために created_byusers テーブルへの外部キーを張っています。

ALTER TABLE reports 
ADD CONSTRAINT fk_reports_users 
FOREIGN KEY (created_by) REFERENCES users (id);

サポート担当の鈴木が代理でデータを登録する際、created_by には何を保存すべきでしょうか。

  1. 鈴木のIDを入れる: 上図の通り、テナントの users テーブルに「鈴木」は存在しないため、FK制約違反(Integrity Error)で保存できません。
  2. 顧客のIDを入れる: DB上は「顧客自身が作った」ことになってしまい、後からサポート担当者が操作した記録をDB上で区別できなくなります。

4.2 解法A: 影のユーザーパターン (Shadow User)

この問題を解決する一つ目のアプローチが「Shadow User(影のユーザー)」です(SAP などのエンタープライズ基盤でも見られる手法のようです)。

実装フロー:

  1. プロビジョニング: サポートがテナントへアクセスを開始した際、テナントの users テーブルに一時的なレコードを挿入します。
    • id: 新規生成
    • name: "Loglass Support (鈴木)"
    • is_shadow: true
    • real_agent_id: "agent_suzuki_999"
  2. 操作: アプリケーションは、この「Shadow User ID」を使ってデータを保存します。これでFK制約エラーを回避できます。
  3. クリーンアップ: サポートセッション終了後、このユーザーは論理削除(Soft Delete)または無効化されます。

メリットとデメリット:
よくある INNER JOIN users クエリが壊れず、「IDは記録するがUserレコードは存在しない」透明人間バグを回避できるのがメリットです。

一方で、このアプローチには課題もあります。一時的とはいえShadow Userのレコードが無闇やたらに増えてしまうこと。また、サポートチケット番号などの「代理ユーザーならではの関心事」を、本来顧客の情報を管理すべきプロダクトのテーブル側に含めざるを得なくなり、関心事が過剰に混ざってしまう点です。

4.3 解法B: 個別サポートアカウントパターン

解法Aの課題を嫌う場合、より自然に思いつくのがこのパターンです。

実装フロー:

  1. 事前準備: サポート担当の鈴木、田中それぞれの専用アカウント(support-suzuki@vendor.com, support-tanaka@vendor.com)をあらかじめテナントやシステムに作成しておく。
  2. 操作: 各自が自分のサポート用IDで代理操作を行う。
  3. 管理: 人の出入りに合わせてアカウントを追加・削除する。

トレードオフ:
この方法はデータベース上の制約を満たしつつ、「誰が操作したか」がDB上で直接わかるのが利点です。

しかし、B2Bの運用においてはスケールしません。サポートのローテーションやシフト変更のたびにアカウント管理の手間が発生し、サポート担当者の異動・退職に伴う権限の剥奪(オフボーディング)漏れのリスクが格段に高まります。これは第2章で触れた SOC 2が求める「アクセス権の自動的な剥奪(ライフサイクル管理)」の要件を満たす上で、致命的な弱点(非準拠リスク) となります。さらに、顧客から見た時に「〇〇株式会社のサポートチーム」としてではなく「鈴木という個人」が見えすぎてしまうことの是非もありそうです。

4.4 解法C: 共有サービスアカウントパターン

これまでの解法A・Bが持つ課題を踏まえ、折衷案となるアプローチも考えられます。

実装フロー:

  1. 事前準備: システムにサポート専用の共有アカウントを作成しておく。
  2. 操作: 鈴木も田中も、代理操作時のDB書き込みは、すべてこの共有アカウントのIDで行う。
  3. 監査ログ: データベースの作成者は共有IDになりますが、アプリケーションの監査ログ(Audit Log)には必ず act クレームから「鈴木」「田中」を記録する。

設計の分岐点(テナント単位か、グローバル単位か):
この解法Cを採用する場合、共有アカウントのスコープをどう設計をするかで一般的なSaaSアーキテクチャでは2つのアプローチに分かれます。

  • グローバル共有(Global Support Access):
    全テナント共通で1つの support@vendor.com を使う方式。運用・設計コストは最小ですが、万が一アカウント権限が奪取された場合の「ブラスト・ラジアス(影響範囲)」が全顧客に及んでしまうリスクがあります。そのため、サポート管理画面への強固なMFAやVPN経由のアクセス制限といった厳格な統制とセットで運用することが大前提となります。
  • テナント毎の共有(Per-Tenant Support Access):
    テナントA用には support-A@vendor.com、テナントB用には support-B@vendor.com と、テナントごとに1つのサービスアカウントを発行する方式。管理の手間は増えますが、影響範囲を確実に1テナント内に局所化できるため、金融や医療向けなど、より高いデータアイソレーション要件が求められる場合に適しています。

トレードオフ:
このアプローチは、データベースのFK制約やユーザー管理を極めてシンプルに保てる一方で、「データベースのレコード単体を見ただけでは、『サポートの誰が』操作したのかまでは特定できない(アプリケーションの監査ログと突き合わせる必要がある)」 というトレードオフを生じさせます。

データ分析(BI)などで直接DBを参照する場合、作成者がすべて「サポート窓口」に丸められてしまう点は、アーキテクチャ選定においてビジネスサイドと事前に合意しておくべき重要なポイントです。アカウント管理コストの削減を優先してこの解法を採用するのか、突き合わせ作業を嫌って解法A(Shadow User)を採用するのか、正解は分かれそうです。

DBアーキテクチャ3つの解法比較:

パターン DB層での個人の特定 監査ログでの個人の特定 アカウント管理コスト 退職者(SOC2)対応 概要
A: Shadow User やや高 (*1) DBに一時的な個人の分身を作る
B: 個別アカウント 非常に高 ✖️ サポート担当者全員のIDを全テナント層で管理
C: 共有アカウント ✖️ (突き合わせ必須) 低 (*2) DB上は「システム」、詳細なログは「アプリケーション層」で担保

(*1) 各テナントごとに一時ユーザーを作成・削除するプロビジョニングの仕組み化が必要

(*2) テナント単位(Per-Tenant)で共有する場合は管理の手間が追加される

まとめ

マルチテナント環境における「代理操作」は、後付けの便利機能では不十分です。セキュリティやデータ整合性を確保しつつ、顧客との信頼関係を損なわずに手厚いサポートを行うための、極めて高度なアーキテクチャ設計だと感じています。

ログラスは「良い景気を作ろう」というミッションのもと、中長期視点でのシステム設計・運用を重視しています。弊社公式X(旧Twitter)アカウントおよびConnpassもご覧ください。

https://x.com/LoglassPrdTeam

https://loglass-tech.connpass.com/

株式会社ログラス テックブログ

Discussion