Skip to content

fix: プロジェクトの env による共通機密の打ち消しが効かないことがある #152

Description

@takemi-ohama

何を見つけたか

プロジェクトの env で共通機密のキーを空上書きしても、コンテナへは共通機密の値が入ることがあります。稼働中の with-ai-dev コンテナで確認しました。

$ docker exec with-ai-dev-dev-1 bash -lc 'echo "$GOOGLE_CLOUD_PROJECT / $GCP_ACTIVE_PROFILE / $DEVBASE_ACCOUNT_GROUP"'
nyle-carmo-analysis / default / with

projects/with-ai-dev/env は次のとおりで、期待値は GOOGLE_CLOUD_PROJECT が空、GCP_ACTIVE_PROFILE が with です。

DEVBASE_ACCOUNT_GROUP=with
GCP_ACTIVE_PROFILE=with
GOOGLE_CLOUD_PROJECT=

3 つのうち DEVBASE_ACCOUNT_GROUP だけが期待どおりです。 この非対称が手がかりになります。生成された .docker-compose.scale.yml を見ると、扱いが 2 通りに分かれています。

environment:
  - GCP_ACTIVE_PROFILE          # 名前だけ。値は docker compose 実行時の環境から取る
  - GOOGLE_CLOUD_PROJECT        # 同上
  - DEVBASE_ACCOUNT_GROUP=with  # 値がリテラルで書かれている

名前だけの受け渡しは env_file: より優先されるため、env_file に書いた空上書きは負けます。値は _inject_secrets が docker compose の実行前に環境へ載せたものになります。

タイミング

古いコンテナが残っているだけ、という筋は成り立ちません。

出来事 時刻
env へ空上書きを入れたコミット(devbase-ext bddbe18) 2026-09-01 11:49 UTC
.docker-compose.scale.yml の生成 2026-09-02 00:54:28 UTC
コンテナの起動 2026-09-02 00:54:29 UTC

生成の時点で env は 13 時間前から現在の内容でした。実際、生成器は DEVBASE_ACCOUNT_GROUP=with を読み取って compose へ書き込んでいます。

どこで見つけたか

lib/devbase/env/runtime.py の _project_env_overrides()(114-135 行)。

    keys = EnvFile.parse_bytes(raw).keys()
    return {key: os.environ[key] for key in keys if key in os.environ}

値をファイルから読まず os.environ から取ります。 コメントのとおり、env 内の変数参照(APP_ROOT=$APP_HOME/app)を展開済みの値で拾うための設計です。裏を返すと、起動ラッパーが対象プロジェクトの env を os.environ へ載せていない経路では、この上書きが 1 件も効きません。

手元で対象ディレクトリの env を source してから runtime.resolve() を呼ぶと、期待どおりに解決されます。

[with-ai-dev]
  GOOGLE_CLOUD_PROJECT = []
  GCP_ACTIVE_PROFILE   = [with]

つまり実装は「env が os.environ に載っていれば正しい」状態で、載せる側の経路のどれかが抜けていると読めます。EnvFile.parse_bytes はキーを正しく拾えており(10 キーすべて取得を確認)、パース側の問題ではありません。

当時どのディレクトリからどう devbase up を実行したかは記録に残っておらず、再現手順を確立できていません。 そのため「どの経路が抜けているか」は未特定です。

なぜこの変更の範囲外なのか

PLAN50(gemini の Vertex AI 強制をやめる)の受け入れ条件は起動定義の振る舞いで、機密の解決経路は対象外です。issues/PLAN50_gemini-vertex-alias.md の「対象範囲(含まない)」に明記しています。

直さないと何が起きるか

プロジェクトの env による共通機密の打ち消しが、経路によって効いたり効かなかったりします。失敗しても何も表示されません。

with-ai-dev の例では、withjp のアカウントで認証したコンテナに nyle の GCP プロジェクト ID が入り、gemini が Vertex AI を叩いて失敗していました。企業をまたいで設定が混ざる形なので、気づきにくいわりに影響が大きいところです。

同じ形の打ち消しは project-trygroup-prd でも使っており、v3.2.0 で追加した GOOGLE_GENAI_USE_VERTEXAI= の打ち消しも同じ仕組みに乗っています。

切り分けの候補:

  • devbase up <name> / devbase up(プロジェクト内) / devbase project up <name> のそれぞれで、os.environ に対象プロジェクトの env が載っているかを確かめる
  • 載っていない経路があれば、_project_env_overrides がファイル側の値へ落ちる(ただし変数展開の扱いを決める必要がある)か、ラッパー側で必ず載せる
  • 稼働中の with-ai-dev-dev-1 コンテナに現象が残っているので、作り直す前に採取する

由来

issue #139 の作業から派生(PLAN50 / PR #149)

進行

モード: operation / 計画: issues/PLAN53_openbao-switchover.md

  • 要求と受け入れ条件 — 2026-09-14 15:20
  • 作業場所の用意
  • 設計 — 2026-09-14 15:25
  • 素材の収集と出典の確定
  • ドキュメント再構成
  • ドキュメントレビュー
  • 計画 — 2026-09-14 15:26
  • 実装
  • 構造改善
  • 実装レビュー
  • 完了判定
  • Pull Request
  • 確定仕様化
  • 後片付け
  • 配布
  • 体裁レビュー
  • リリース後テスト — 2026-09-15 16:41
  • 振り返り

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions