型付き辺: 出 8 / 入 0
ADR-0108: M365/Entra 顧客の自前 ID で GAS 会計を使わせる方式を検討する
- Status: Proposed
- Mode: Standard
- Kruchten Type: Executive
- Scope: platform
- Implementation Status: Not Started
- 起案者: [email protected] ([email protected])
- 起案日時 (JST): 2026-06-02
- 承認日時 (JST): -
- Deciders: [email protected] (単独 / 要 Decision Pipeline 検証)
Status は Proposed → Accepted (マージ時) / Rejected (Close 時) に遷移する。
本 ADR の位置づけ(監査用注記): 本 ADR は sub ワークスペース(ドキュメント担当)での 検討相談を記録したドラフトであり、Decision Pipeline (ADR-0052/0064) の Cross-Validation ゲートを 未通過である。§2 の MCDA スコアは暫定値で、確定(Accepted 化)前に main ワークスペースでの実装可否検証(特に案 A の自前 OIDC ゲートの PoC)と pipeline 検証を要する。Decision Pipeline の retroactive validation (ADR-0052) は任意。
TL;DR(要旨・専門語ゼロ): 当社の会計システムは Google の仕組み(Apps Script + スプレッドシート)の上で動いており、Google のアカウントが無いと「動かす」ことができない。一方、お客様が Microsoft(M365)だけを使っていて自社の ID のまま当社システムにログインしたい場合は、お客様には Google アカウントを発行せず、当社が用意した画面でお客様の Microsoft ID を確認し、裏側の処理は当社所有の Google アカウントが代行する、という作りにすればよい。これによりお客様側の Google ライセンスはゼロで済み、必要なのは当社側の数席だけになる。本 ADR はその方式の候補と論点を整理する。
1. コンテキスト
1.1 背景 (Background)
M365 基盤(Google Workspace なし)の法人で本 GAS 会計プロジェクトを稼働できるか、また顧客が自前の Entra ID / M365 を持つ場合にその ID のまま利用させられるかを検討するため、2026-06-02 に相談が発生した。
1.2 現状 (Current State / As-Is)
本プロジェクトは Google Apps Script V8 ランタイム上で動き、会計帳簿は Google Sheets(Drive 上)に存在する。appsscript.json の Web App access は DOMAIN、ユーザー識別は Session.getActiveUser()(Google OAuth 前提)、監査の一部は AdminReports.Activities(Workspace ドメイン管理者前提)に依存している。
1.3 課題 (Problem)
- Cloud Identity Free には Sheets/Drive が含まれないため、会計シートを操作する人間は Google Workspace 有償席が必須となる。
- 顧客が M365/Entra のみの場合、その外部 ID を Google Workspace 正規ユーザーへ直接マップする標準経路がなく、「自前 ID で Sheets を直接編集」は成立しない。
- 監査機能(
811_audit_checker.jsの Drive 外部共有検知)は Drive 監査ログ=Workspace エディション(Business Standard 以上想定)と super admin ロールを要し、最小構成と衝突する。
1.4 制約・要件 (Constraints & Requirements)
- GAS ランタイムは置換不可(M365 ネイティブ移植は全面リライト=本 ADR スコープ外)。
- Web App のオーナー(実行 identity)は実在の Workspace ユーザーである必要があり、最低 1 席は当社側に要る。
- 監査要件あり(CLAUDE.md 冒頭)。操作証跡を残せること。
- 顧客側に新規 ID 発行・ライセンス負担を強いない構成を優先する。
1.5 目標 (Goals / To-Be)
顧客が自前の Entra ID/M365 のまま当社 GAS 会計システムへアクセスでき、顧客側 Google ライセンス 0・当社側最小席数で、かつ操作証跡を残せる稼働方式を選定する。Non-Goals: GAS の M365 ネイティブ移植、全社員規模の Workspace 契約。
2. 判断基準 (Decision Drivers)
§2.2 のスコアは 暫定(Decision Pipeline 未通過・PoC 前)。確定前に再評価する。
2.1 評価軸
| # | 軸 | 重要度 (係数) | 案件特有の解釈 |
|---|---|---|---|
| 1 | #secure | [Must] (×2.0) | 会計データの露出面を増やさない。認証ゲートが堅牢で、顧客テナント分離が保てること。K.O. = 現状より露出が増えるなら不採用 |
| 2 | #efficient | [High] (×1.0) | 顧客側 Google ライセンス 0・当社側席数最小・追加運用コスト最小 |
| 3 | #usable | [High] (×1.0) | 顧客が M365/Entra のログイン体験のまま使える(ID 二重管理なし) |
| 4 | #operable | [Medium] (×0.5) | 「誰が操作したか」の監査証跡を残せる |
| 5 | #maintainable | [Medium] (×0.5) | 既存 GAS 資産を活かせる/実装と運用が無理なく続けられる |
K.O. criterion: Must 軸 (#secure) の score < 3 は不採用。
2.2 評価軸 × 案スコア表(暫定)
| 軸 | 係数 | 案 A (Web App + 自前 OIDC) | 案 B (顧客を Workspace 収容) | 案 C (GCP 外部フロント) |
|---|---|---|---|---|
#secure [Must] | ×2.0 | 3(自前ゲート実装品質に依存) | 4 | 5 |
#efficient [High] | ×1.0 | 5(顧客 0 席・当社 1 席〜) | 2(顧客人数ぶん有償席) | 3(新規開発コスト大) |
#usable [High] | ×1.0 | 4 | 3 | 5 |
#operable [Medium] | ×0.5 | 4(アプリ層で記録要) | 4 | 5 |
#maintainable [Medium] | ×0.5 | 4(既存 GAS 活用) | 3 | 2(別スタック新設) |
| K.O. 通過 (Must ≥3) | ✓ | ✓ | ✓ |
加重和は暫定のためタイブレーク参考にとどめ、確定値は pipeline 検証時に算出する。
3. 検討した代替案 (Considered Options)
案 A: GAS Web App「自分として実行+Anyone」+ 自前 Entra OIDC ゲート(顧客 Google 席 0)
- Good, because 顧客に Google ライセンス不要・当社オーナー 1 席〜で成立し、既存 SPA (
webapp_client/,302_spa_bridge.js) を活かせる。 - Good, because M365/Entra のログイン体験を維持できる。
- Bad, because アクセス制御が完全に自前 OIDC 実装(JWKS 署名検証・セッション管理)頼みで、実装ミスが会計データ露出に直結する。セキュリティレビューと PoC が必須。
- Bad, because
Session.getActiveUser()で顧客を識別できず、操作証跡はアプリ層で別途記録する必要がある。
- Good, because 顧客に Google ライセンス不要・当社オーナー 1 席〜で成立し、既存 SPA (
案 B: 顧客ドメインを当社 Workspace に収容(secondary domain + OU 別 SSO profile を顧客 Entra へ)→ 顧客が Sheets を直接操作
- Good, because 標準機能の範囲で済み、
Sessionベースの監査がそのまま効く。 - Bad, because 顧客の操作者人数ぶん有償席を消費し、コスト効率が悪い。
- Bad, because 顧客ドメイン収容・OU/SSO profile 運用が重く、テナント境界管理が複雑。
- Good, because 標準機能の範囲で済み、
案 C: GAS 外に正式 Web フロント(GCP Identity Platform で Entra OIDC 受け)+ Sheets API バックエンド
- Good, because 認証・監査・スケール・マルチテナント分離が最も堅牢。
- Bad, because ほぼ新規開発で、既存 GAS 資産を活かしにくくコスト最大。
却下: 個人 gmail を顧客に配布 / 全社員 Workspace 化 — 組織統制・監査要件・コストで不可(評価対象外)。
4. 決定 (Decision Outcome)
提案: 短中期は 案 A を本命候補とする。理由: 顧客側 Google ライセンス 0・当社最小席で成立し、既存 GAS 資産を最大活用できるため。ただし #secure が自前 OIDC ゲートの実装品質に依存するため、Accepted 化の前に OIDC ゲートの PoC(JWKS 署名検証・セッション・顧客テナント分離)とセキュリティレビューを必須条件とする。顧客数・データ分離要件が拡大した場合は 案 C への移行を再評価する。
本節は Proposed であり、PoC 結果と Decision Pipeline 検証を経て確定する。
5. 影響 (Consequences)
5.1 正の影響 (Good)
- Good, because 顧客は M365/Entra のまま利用でき、Google ライセンス負担が 0 になる。
- Good, because 当社側は会計オペレーター/オーナーの実人数ぶん(最小 1 席)の Workspace のみで済む。
- Good, because 監査をアプリ層で GCP(Cloud Logging / BigQuery、既存
cloud-platformスコープ)に記録する設計に寄せれば、AdminReports=Business Standard+super admin 依存を外せる。
5.2 負の影響 (Bad)
- Bad, because 案 A は自前 OIDC ゲートのセキュリティが要で、実装・レビュー・保守コストと事故リスクを新たに負う。
- Bad, because Drive 外部共有の「事後検知」(
811) は GCP では代替不可。検知→予防(組織ポリシーで外部共有禁止)への方針転換が別途必要で、これは監査方針の変更を伴う。
5.3 中立 / トレードオフ (Neutral / Trade-offs)
- Neutral, because GAS Web App のオーナーは実在 Workspace ユーザー必須で、真の「無人サービスアカウント所有」は不可(最小 1 席は残る)。
5.5 Spike Results
本 ADR は未検証項目を含み、Accepted 化前に PoC を要する。
| 確認項目 | 結果 | 確認日 | 備考 |
|---|---|---|---|
| GAS 内 Entra OIDC ID トークン JWKS 署名検証 | ⬜ 未検証 (要 PoC) | - | UrlFetchApp + external_request スコープで実装可否 |
| Web App「自分として実行+Anyone」での自前ゲート保護 | ⬜ 未検証 (要 PoC) | - | 匿名到達リスクの遮断確認 |
| アプリ層 Entra identity の GCP 監査記録 (BigQuery/Cloud Logging) | ⬜ 未検証 | - | cloud-platform スコープ既存 |
| 顧客テナント単位のデータ分離制御 | ⬜ 未検証 | - | tenant id / email domain ベース |
コスト試算
採択候補(案 A)を Accepted 化し実装に進む場合の概算。AI 支援あり工数を一次見積、手作業(AI 非対応)を参考併記。本 ADR 自体は検討記録のため、確定前の暫定値。
| 作業 | AI 支援 (人日) | 手作業 (人日) |
|---|---|---|
| Entra OIDC ゲート PoC(JWKS 署名検証・セッション) | 1.0 | 2.5 |
| Web App「自分として実行+Anyone」化と自前ゲート保護の検証 | 0.5 | 1.0 |
| アプリ層 Entra identity の GCP 監査記録(BigQuery/Cloud Logging)実装 | 1.0 | 2.0 |
| 顧客テナント分離(tenant id / domain ベースのアクセス制御) | 0.5 | 1.5 |
| セキュリティレビュー | 0.5 | 0.5 |
| ADR 文書化(本ドラフト起案 + curation) | 0.25 | 0.5 |
| 合計 | 約 3.75 人日 | 約 8.0 人日 |
ライセンス費(実運用時の継続コスト): 顧客側 Google 0 円、当社側 Workspace 最小 1 席ぶん(エディションは監査を予防ポリシー化すれば下位プランで可)。追加 GCP コストは監査ログ保管(BigQuery/Cloud Logging)の従量分のみで小規模想定。
6. 撤退条件 / 再評価トリガー (Rollback Plan / More Information)
- 再評価トリガー: 顧客数が増えてマルチテナント分離要件が厳しくなる / 自前 OIDC ゲートの PoC が 2 回失敗 / セキュリティレビューで案 A が不適と判定 → 案 C(GCP 外部フロント)へ分岐。
- 判定タイミング: PoC 完了時、および顧客追加の都度。
- 判定主体: 代表取締役。
Confirmation (準拠確認 / Fitness Function)
- 検証手段: Proposed 段階のため継続検証なし。Accepted 化の前提として (1) OIDC ゲート PoC の手動確認チェックリスト、(2) セキュリティレビュー、(3) Decision Pipeline 検証(任意)を実施する。
- 実行頻度: 起案時のみ(Accepted 化時に Confirmation を本実装に差し替える)。
- 違反時の対応: PoC 未達なら案 C へ分岐(§6)。
7. 参照 (References)
7.1 プロジェクト内参照
- 関連 ADR: ADR-0005 (GAS スプレッドシートをデータストアとする), ADR-0013 (Env モジュール抽象化), ADR-0021 (UC スライス開発・監査ログ機構), ADR-0049 (4-tier ADR scope), ADR-0104 (GAS/clasp デプロイ認証の組織 Internal 化)
- 関連ファイル:
appsscript.json,300_ui/302_spa_bridge.js,webapp_client/,800_ops/811_audit_checker.js
7.2 設計根拠 (Theoretical Foundation)
- Google Cloud — Workforce Identity Federation
- Google Cloud — Workload Identity Federation
- Google Workspace Admin — Set up SSO via a third-party IdP