わたしは、実測値を表示する小さなダッシュボードをGoogle Apps Scriptで作って運用しています。「特定の人だけ見られるようにする」という要件で、メールアドレスが空文字になり、許可リストで判定できませんでした。
2026年10月16日訂正: 以前は「同じWorkspaceドメインでなければ取得できない」と書きましたが、一般仕様としては不正確でした。当時の検証結果と公式の取得条件を分けて記録します。
- わたしの当時の構成では、
Session.getActiveUser().getEmail()が空文字になった - 別ドメインや個人Gmailでは必ず取得できない、という一般仕様ではない
- URLキー方式は当時動いたが、特定のGoogleアカウント本人であることの確認にはならない
やりたかったこと
- GASのWebアプリを、決まった数人のGoogleアカウントだけに見せたい
- 利用者にはGoogle Workspaceと個人Gmailのアカウントが混在している
最初にやったこと(うまくいかなかった)
アクセスした人のメールアドレスを取得し、許可リストと照合しました。次は説明用の最小例です。空文字は許可しない条件を明示しています。
function isAllowedViewer_() {
var email = Session.getActiveUser().getEmail();
return !!email && ALLOWED_LIST.indexOf(email) !== -1;
}
当時は「アクセスしているユーザーとして実行」、アクセス権は「全員」に設定しました。しかし、許可リストに入っているはずのアカウントでもアクセスが弾かれました。
空文字になった実測と、公式の取得条件を分ける
Google公式のSessionリファレンス)では、利用者の識別情報へのアクセスがセキュリティポリシーで許可されない場合、getEmail() は空文字を返すと説明されています。
利用者自身の承認なしに動く処理(開発者として実行するWebアプリなど)は取得できない例です。一方、開発者自身の実行や同一Workspaceドメインでは、一般にその制限が適用されません。別ドメインという理由だけで、一律に取得不能とは言えません。
わたしの当時の検証では、実行ユーザーの設定を変えても解決しませんでした。OAuthスコープに userinfo.email を追加すると、新規ユーザーの同意フローで別のエラーになりました。これらは当時の構成での観測です。空文字になった根因の切り分けや、現在の利用者別・デプロイ別の再検証はできていません。
当時使った代替案: URLに秘密のキーを付ける
当時はGoogleアカウントでの識別をやめ、URLに秘密のキーを付ける方式へ切り替えました。次も説明用の最小例です。キーや引数が未設定なら許可しません。
function isAllowedViewer_(params) {
return !!SECRET_KEY && !!params && params.key === SECRET_KEY;
}
ブックマークするURLに ?key=... を付けてもらいました。これは「誰がアクセスしているか」ではなく、「キーを持っているか」で許可する方式です。
URLを渡された第三者も同じキーを使えます。動作したことだけでは、「特定のGoogleアカウントだけに見せる」という最初の要件を満たしたとは言えません。本人確認が必要な用途を、この方式で満たしたとは扱いません。
もう1つハマったこと: ドメイン専用URL
画面内のリンクには ScriptApp.getService().getUrl() を使っていました。Workspaceアカウントで実行すると、ドメイン専用の形式(/a/ドメイン名/macros/...)が返ることがあり、わたしの検証では別ドメインのアカウントから正しく開けませんでした。
当時は次の関数でURLを正規化しました。URLの形を変えても、認証やアクセス権が変わるわけではありません。
function toGenericWebAppUrl_(url) {
return String(url || '')
.replace(/\/a\/macros\/[^\/]+\//, '/macros/')
.replace(/\/a\/[^\/]+\/macros\//, '/macros/');
}
次に確認すること
まず、問題が起きたデプロイの「次のユーザーとして実行」と、利用者自身の承認の有無を確認します。わたしの失敗例だけから、同じ制約がすべてのアカウントに当てはまるとは判断しません。メールアドレスが空文字のときは、許可しない扱いにします。
関連する検証記録
- GAS Webアプリの認証|getActiveUserが空になる時の判断表 — 当時の構成と最小コードを整理した記事です。同一ドメインの条件を強く断定した記述が残っているため、一般仕様は上の公式資料を優先してください
- GASのUSER_DEPLOYINGとUSER_ACCESSINGを分けた|管理画面に管理者が入れない — 画面とAPIで実行ユーザーを分けた、その後の検証記録
このWebアプリのその後
ここで作ったダッシュボードに関連する記録です。
- 自動タスクが1週間「成功」と報告しながら何もしていなかった|ダッシュボードから止められるようにした記録 — 同じダッシュボードに操作盤を足した話
- 公開前チェックで実際に使っている正規表現パターン集 — 公開前に機械で走査している中身
- Claude Codeをサブエージェントで役割分担する|公開前チェックを別AIに任せた構成と実測値 — こうした小さなツールを誰に書かせているか
noteの運用記録
公開前に気づいて直した実測は、noteのMISSION LOGシリーズにも記録しています。
注記
この記事は、わたしが運営しているサービスの技術検証を一般化した記録です。コード例は説明用で、実際のIDや設定値、特定の組織・業務に関する情報は含みません。


コメント