dbt

dbt env_var() の安全な利用: シークレット管理の注意点と実務パターン

2026-04-19
NicheeLab編集部

env_var() は便利だが、使い方を誤るとパスワードがコンパイル済みSQLやログに残る。試験でも実務でも、どこで評価され何に残るかを理解しておくことが重要。

本稿では、dbt-core の公式挙動に沿って安全な利用法とアンチパターン、CI/CD・Vault等の組み合わせ、監査の観点を整理する。

env_var() の基礎と評価タイミング

env_var(name, default=None) は、Jinja が評価されるタイミングで OS の環境変数を参照する。dbt における Jinja の主な評価点は、モデルやマクロのコンパイル時、dbt_project.yml・profiles.yml の読み込み時である。

重要なのは、SQL ファイル内で env_var() を使うと、その値がコンパイル済みSQL(target/compiled 配下)に埋め込まれうる点だ。シークレットは SQL へ埋め込まず、接続情報(profiles.yml)でのみ参照するのが原則。

profiles.yml は実行成果物(manifest.json, run_results.json, catalog.json)に含まれない。一方、dbt_project.yml の vars やモデルの config で与えた値は成果物へ含まれる可能性があるため、そこにシークレットを置くのは避ける。

  • env_var() は文字列を返す。数値にしたい場合は Jinja フィルタ(| int など)で明示変換。
  • default を安易に指定すると気づかぬうちに“既定の資格情報”で接続する危険がある。シークレットは既定値なしで、未設定なら明示的に失敗させる。
  • ローカル開発でも export 等で一時的に環境変数を注入し、ファイル(.env 等)に平文で残さない。

profiles.yml での安全な参照例(Snowflake)

snowflake:
  target: prod
  outputs:
    prod:
      type: snowflake
      account: "{{ env_var('SNOWFLAKE_ACCOUNT') }}"
      user: "{{ env_var('SNOWFLAKE_USER') }}"
      password: "{{ env_var('SNOWFLAKE_PASSWORD') }}"
      role: "{{ env_var('SNOWFLAKE_ROLE') }}"  # シークレットではない任意値でも default は慎重に
      warehouse: "{{ env_var('SNOWFLAKE_WAREHOUSE') }}"
      database: ANALYTICS
      schema: CORE

どこに漏れるか:流通経路と脅威モデル

シークレットが漏れやすい箇所は、コンパイル済みSQL、実行ログ、dbt の成果物(manifest.json 等)、CI/CD のジョブログ・環境ダンプだ。env_var() 自体は単に値を返すだけなので、どこで参照するかが決定的に重要になる。

dbt は一部の機微情報をマスクする実装を持つことがあるが、全てを保証できるわけではない。運用側で“出さない・残さない”設計を徹底する。

  • コンパイル済みSQL: モデル内で env_var() を使うと、その値が平文で残る可能性。
  • 成果物: dbt_project.yml の vars に入れた値やモデル config の一部は manifest.json に入ることがある。秘密は vars に載せない。
  • ログ: デバッグ出力(--debug)やカスタム log() で誤って値を印字しない。CI の環境ダンプも禁止。
  • リポジトリ: .env, profiles.yml の平文化・誤コミットは厳禁。

危険な例(モデル内での出力や SQL 埋め込み)

-- model.sql(やってはいけない)
{{ log(env_var('SNOWFLAKE_PASSWORD'), info=True) }}  -- ログに出る
select '{{ env_var('SNOWFLAKE_PASSWORD') }}' as leaked; -- コンパイル物に残る

原則は、秘密は外部シークレットマネージャで保管し、CI/CD 実行時に環境変数として一時注入、dbt は profiles.yml の env_var() でのみ参照する。これにより秘密は SQL・成果物に入らず、ローテーションも容易になる。

dbt Cloud を使う場合は、プロバイダ連携やマネージドな接続設定を優先し、任意の env_var で秘密を扱わない。OSS 実行では CI プラットフォームのマスク機能(GitHub Actions secrets、GitLab CI variables 等)と組み合わせる。

  • 外部保管: HashiCorp Vault、クラウドの Secret Manager 等で保管・ローテーション。
  • 短命トークン: OAuth/短命トークンを優先。長期パスワードは避ける。
  • 注入は実行時: CI/CD ジョブでのみ環境に注入。ローカルは一時シェルセッションで export。
  • 参照は profiles.yml のみ: dbt_project.yml の vars・モデル SQL・マクロ出力には流さない。

GitHub Actions での一時注入例(OSS 実行)

jobs:
  run-dbt:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.11'
      - run: pip install dbt-snowflake
      - name: Run dbt
        env:
          SNOWFLAKE_ACCOUNT: ${{ secrets.SNOWFLAKE_ACCOUNT }}
          SNOWFLAKE_USER: ${{ secrets.SNOWFLAKE_USER }}
          SNOWFLAKE_PASSWORD: ${{ secrets.SNOWFLAKE_PASSWORD }}
          SNOWFLAKE_WAREHOUSE: ${{ secrets.SNOWFLAKE_WAREHOUSE }}
        run: |
          dbt deps
          dbt build --target prod

アンチパターンと対策

秘密を vars に入れる、モデルやマクロで log() 出力する、Jinja で SQL へ文字列埋め込みする、といったパターンはすべて長期的に漏えいリスクを高める。特に vars は成果物に残るため、禁止する。

未設定時の default で“通ってしまう”のも事故の温床。env_var() の存在チェック用にヘルパーマクロを用意し、欠落時は明示的に失敗させるとよい。

  • vars へシークレット格納 → manifest.json に載る可能性。
  • Jinja で SQL へ埋め込み → target/compiled に平文残存。
  • ログ出力や環境ダンプ → CI のログ永続化・外部共有で拡散。
  • default 指定の乱用 → 想定外資格情報で接続・検知遅延。

必須環境変数の検証マクロ(欠落なら失敗)

{% macro required_env_var(name) -%}
  {% set val = env_var(name) %}
  {% if not val %}
    {{ exceptions.raise_compiler_error('Missing required env var: ' ~ name) }}
  {% endif %}
  {{ return(val) }}
{%- endmacro %}

# profiles.yml 側での利用例(Jinja 可)
password: "{{ required_env_var('SNOWFLAKE_PASSWORD') }}"

比較表:dbt におけるシークレットの扱い方

実務と試験の両面で正解となるのは、外部で保管し実行時に環境変数として注入、profiles.yml の env_var() でのみ参照する構成である。以下に代表的手段を比較する。

  • “成果物に残らないか”“ローテーション容易性”“試験での推奨度”に注目する。
  • dbt Cloud を利用可能なら、まずはプラットフォームの管理機能を検討する。
手段可視化リスク(SQL/ログ/成果物)ローテーション容易性試験での推奨度
dbt_project.yml の vars に格納高い(成果物に載りやすい)低い(コード変更が必要)不可
profiles.yml に平文ハードコード中(成果物には載らないが漏えい時の影響大)低い(配布・差替えが手作業)不可
外部 Secret → 環境変数 → profiles.yml の env_var()低い(SQL・成果物に残さない設計が可能)高い(外部で一括ローテーション)推奨(標準解)
dbt Cloud のマネージド接続低い(プラットフォームが管理)高い(UI/API で更新)推奨(Cloud 利用時)
Vault 等の動的認証 + CI 注入 + env_var()低い(短命・最小権限で設計可能)高い(自動ローテーション)推奨(成熟運用)

Databricks(トークン)例:profiles.yml

databricks:
  target: prod
  outputs:
    prod:
      type: databricks
      host: "{{ env_var('DATABRICKS_HOST') }}"
      http_path: "{{ env_var('DATABRICKS_HTTP_PATH') }}"
      token: "{{ required_env_var('DATABRICKS_TOKEN') }}"
      catalog: main
      schema: core

運用・監査ポイントと試験対策チェック

監査観点では、成果物・コンパイル物・ログに秘密が出ていないかの機械検査、CI のマスク設定と権限分離、トークンの有効期限・ローテーションの定期点検が肝要。dbt 側は“profiles.yml の env_var() でのみ秘密参照”“vars・SQL へは出さない”の2点を守る。

試験対策としては、env_var() の評価タイミング、vars へ秘密を置くと manifest.json に残るという点、未設定時 default で通ってしまう危険、dbt Cloud ではプラットフォーム管理を優先、を押さえる。

  • CI で env をダンプしない(set -x や printenv 禁止)。
  • dbt 実行ユーザの権限は最小化。ロール/ワークスペースも分離。
  • 成果物・target 配下・ログをスキャンし、秘密パターン(例: acct_ や token= 等)ヒットがないか自動検査。

安全なシークレットフロー(概念図)

 [Secret Manager]
         |
         v   (masked, short-lived)
     [CI/CD Runner] --(env export)--> [Process Env]
                                      |
                                      v
                               [dbt env_var()]
                                      |
                                      v
                               [Adapter/Driver]
                                      |
                                      v
                               [Warehouse/BI]

モデルやマクロで“使わない”ためのガイドコメント例

{#
注意:
- env_var() をモデルSQLや log() に渡さないこと。
- シークレットは profiles.yml でのみ参照。
- 未設定は required_env_var() で即時失敗させる。
#}

問題で確認

Analytics Engineer

問題 1

OSS の dbt を GitHub Actions で実行する。Snowflake のパスワードを安全に扱う最も適切な方法はどれか?

  1. GitHub Secrets に保管し、ジョブ実行時に環境変数として注入し、profiles.yml で env_var() 参照する
  2. dbt_project.yml の vars にパスワードを設定し、マクロから参照する
  3. モデル SQL 内で env_var('SNOWFLAKE_PASSWORD') を文字列として埋め込む
  4. デバッグのために log(env_var('SNOWFLAKE_PASSWORD')) で一度ログに出す

正解: A

秘密は外部で保管し、実行時に環境変数として注入、profiles.yml の env_var() でのみ参照するのが安全かつ標準的。vars やモデル SQL、ログ出力は漏えいリスクが高く不適切。

よくある質問

dbt は .env ファイルを自動で読み込みますか?

いいえ。dbt-core 自身は .env を自動読込しない。シェルで export するか、CI/CD のシークレット機能で環境変数として注入する。外部の dotenv ツールを使う場合も、平文ファイルの取り扱いに注意すること。

env_var() の値は dbt の成果物に残りますか?

profiles.yml で接続情報として参照する分には成果物(manifest.json 等)に含まれない。一方、dbt_project.yml の vars やモデル/マクロで env_var() を使って値を構成すると、内容がコンパイル済みSQLや成果物へ入る可能性がある。

env_var() に default を指定しても良いですか?

シークレットには原則として指定しない。未設定時に既定値で“通る”と誤接続や検知遅延を招く。欠落時は required_env_var() 等で明示的に失敗させる。default はロール名など非機微・挙動が明確な項目に限定する。

この記事で学んだ内容を問題で確認しましょう

16,000問以上の問題で実力チェック

無料で問題を解いてみる
この記事の著者

NicheeLab編集部

データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。


関連記事
dbt

dbt Model の基礎: SQL で定義する変換の最小単位

Analytics Engineer 向けに、dbt Model の定義、マテリアライゼーション、依存関係、インクリメン...

dbt

dbt Analytics Engineer 試験ガイド: 出題範囲・配点・申込の実務視点

dbt Analytics Engineer 認定の出題範囲、配点の考え方、申込から受験までの流れを、公式ドキュメントの...

dbt

dbt Cloud と dbt Core の違いと選び方:Analytics Engineer 試験に効く要点

dbt Cloud と dbt Core の機能差を、実務と資格対策の両面から整理。スケジューリング、IDE、RBAC、...

dbt

dbt プロジェクト構造ガイド: models / seeds / macros の実務レイアウト

Analytics Engineer 向けに、dbt プロジェクトのディレクトリ構造と命名規約、dbt_project....

dbt

dbt_project.yml の読み方:主要設定と命名を最短で掴む

dbt_project.yml の必須キー、命名解決(database.schema.identifier)、設定優先度...

dbtの記事一覧 (101件)
© 2026 NicheeLab All rights reserved.