🤝

dbt docsを Cloud Run + GCS + IAPでセキュアに社内限定公開する方法

に公開

はじめに

この記事の対象者はこちら

  1. dbt coreを利用しているユーザー
  2. 1かつ、社内ユーザーに限定してdbt docsをセキュアに公開したい

上記ユーザーに向けてかなり簡単にかつセキュアにCloud Runで公開したdbt docsをIAPを用いて特定のユーザーのみにアクセスを制御する方法について説明していますのでぜひ読んでいただけると嬉しく思います。

TL;DR(要約)

  1. dbt docs を dbt docs generate --static で HTML 化し、GCSに保存。
  2. Cloud Run のシンプルな Flaskアプリで GCS の index.html をホスティング。
  3. 外部公開はせず、IAP で社内の許可ユーザー/グループだけに閲覧を限定。
  4. “ドキュメント自動更新”は GitHub Actions のスケジュール実行にて行う。

今回使用するツールのおすすめ説明記事

  • dbt docsについての説明

https://zenn.dev/foursue/books/31456a86de5bb4/viewer/82447e

  • Cloud Runとは?について

https://zenn.dev/cloud_ace/articles/2d6b2a4740b1ec

  • Cloud Run × IAPの説明

https://zenn.dev/iret/articles/cloud-run-iap-auth

  • GitHub ActionsでGCSを公開

https://zenn.dev/yuichi_dev/articles/ddddd1be215ac5

全体の仕組み、フロー

こう設計する理由

今回はCloud Run + IAP を選んだ基準として、

  • 社内限定・人/グループ単位で管理したい(最低限のガバナンス要件)
  • URL流出を前提にしても、未許可なら見えない防波堤が必要
  • 誰が閲覧したかの痕跡(メールアドレス)をログに残したい
  • 将来、独自ドメイン/CloudCDN/監査統合などへ拡張する余地を確保したい
    などの要件があったため、他にも候補となる構成はありましたが本ドキュメント通りの構成としております。

今回使用するツールのそれぞれの役割

  • GitHub Actions:dbt docs をビルドして GCS へ配置。
  • GCS(非公開):GitHub Actionsの実行で作成されたindex.htmlの保管。公開はしない。
  • Cloud Run:GCS から index.html を取り出してレスポンス。
  • IAP:Googleアカウント(ユーザーorグループ)での認証・認可。

必要なもの(前提)

  • GCP プロジェクト & Cloud Run が使える権限
  • 非公開 GCS バケット
  • Cloud Run サービス
  • 実行用サービスアカウント

Cloud Run の環境変数(例)

  • BUCKET_NAME=your-bucket-name
  • OBJECT_NAME=index.html

実装に必要なコード

最小の Flask アプリで GCS から index.html を読んで返すだけにします。ETagCache-Control を付け、ヘッダでのセキュリティも最低限セットします。

https://github.com/yutoaoki412/dbt-docs-internal/blob/main/app.py

依存パッケージ

https://github.com/yutoaoki412/dbt-docs-internal/blob/main/requirements.txt

参考 Dockerfile(例)

既存のベースに合わせて適宜調整してください。

https://github.com/yutoaoki412/dbt-docs-internal/blob/main/Dockerfile

セキュリティ設定

  1. GCS を“非公開”に固定

    • UBLA(Uniform Bucket-Level Access)有効化
    • Public Access Prevention(公開ブロック)有効化
    • allUsers バインディングが付いていないことを確認
  2. サービスアカウントに最小権限

    • 対象バケットにだけ roles/storage.objectViewer
  3. Cloud Run は未認証拒否--no-allow-unauthenticated

  4. IAP 有効化

    • 初回は OAuth 同意画面と OAuth クライアント作成
    • アクセス制御でユーザー/グループに IAP-secured Web App User を付与

デプロイ手順(初回)

# 0) 対象プロジェクトに切替
gcloud config set project <PROJECT_ID>

# 1) GCS を“非公開運用”に固定
gsutil uniformbucketlevelaccess set on gs://<BUCKET>
gsutil pap set enforced gs://<BUCKET>
gsutil iam get gs://<BUCKET> | grep -i allUsers || echo "OK: no allUsers"

# 2) サービスアカウントに最小権限
gcloud storage buckets add-iam-policy-binding gs://<BUCKET> \
  --member=serviceAccount:<SERVICE_ACCOUNT> \
  --role=roles/storage.objectViewer

# 3) Cloud Run デプロイ
gcloud run deploy dbt-docs-viewer \
  --region asia-northeast1 \
  --source . \
  --service-account <SERVICE_ACCOUNT> \
  --no-allow-unauthenticated \
  --set-env-vars BUCKET_NAME=<BUCKET>,OBJECT_NAME=index.html

IAPの設定

  1. デプロイしたCloud RunのサービスURLにアクセスし、セキュリティタブを開く。
    そしてIAPのチェックボックスをクリックして、ポリシーを編集ボタンをクリック。
  2. principal 1にて、アクセスを許可したい個人のアドレスや、グループメールアドレスを入力して保存を押す。

IAP設定後のサイトの挙動

  1. このようにGoogleアカウントのログインが求められます。
  2. 権限を持ったアカウントで入るとこのようにdbt docsの内容が表示されます。


3. 権限を持っていないアカウントでログインを行うとこのようにアクセスが制限されるようになります。

更新の自動化(GitHub Actions)

  • スケジュール(例:JST 08:00)で dbt docs generate --static を実行。
  • 生成された static_index.htmlgs://<BUCKET>/index.html に上書きアップロード。
  • 公開設定変更は不要。配信は常に Cloud Run + IAP 経由。

手動反映したいときは、workflow_dispatch でワークフローを起動すれば即反映できます。

https://github.com/yutoaoki412/dbt-docs-internal/blob/main/.github/workflows/dbt-docs-to-gcs.yml

監視用のログの見方

  • URL 共有:Cloud Run のサービス URL(IAP 保護済み)を配布。

  • ログ

    gcloud logs tail --project=$PROJECT_ID --region=$REGION \
      "resource.type=cloud_run_revision AND resource.labels.service_name=$SERVICE"
    
  • キャッシュ:ブラウザのキャッシュが強い場合は Cache-Controlmax-age=0, no-cache に変更。

  • 権限管理:閲覧者追加は IAP のアクセス制御にユーザー/グループを登録。

まとめ

  • dbt docs の社内公開は GCS 非公開 + Cloud Run + IAP がシンプルかつセキュア。
  • 最小権限と IAP の組み合わせで、URL 流出時も被害を最小化。
  • 運用は「毎朝生成 + リクエスト時取得」の二段で十分スケールします。

Discussion