Azure documentation update「Improve token handling and cleanup in docker.md」は、Azure Pipelines の Docker ベースのセルフホステッドエージェントを使っている人が確認すべき変更です。結論から言うと、主なポイントは Linux/Bash 版 start.sh のトークン取得・クリーンアップ処理を見直し、長時間待機後のエージェント削除時に認証エラーが出る問題を避ける ことです。
特に、サービスプリンシパルで Azure DevOps に接続している Docker エージェント、長時間待機するセルフホステッドエージェント、コンテナー停止時に VS30063 エラーが出たことがある環境では、影響を確認する価値があります。一方で、2026年5月11日時点で該当PRはまだ Open 状態で、do-not-merge ラベルも付いているため、公式ドキュメントへ完全反映済みと断定せず、採用時は検証環境で確認するのが安全です。(GitHub)
Azure documentation update「Improve token handling and cleanup in docker.md」の概要
今回の更新対象は、MicrosoftDocs の azure-devops-docs リポジトリにある docs/pipelines/agents/docker.md です。これは Azure Pipelines のセルフホステッドエージェントを Docker コンテナーで実行する手順を説明するドキュメントで、Windows と Linux の両方のコンテナーホストを扱います。Microsoft Learn の現行ドキュメントでも、Docker でエージェントを動かすには AZP_URL や認証用の環境変数を渡して Azure Pipelines または Azure DevOps Server に接続する構成が説明されています。(Microsoft Learn)
今回のPRでは、Linux/Bash 版の Docker エージェント起動スクリプトについて、トークンの読み込み処理とクリーンアップ処理をリファクタリングしています。PR本文では、クリーンアップ時に WRITE ERROR: VS30063: You are not authorized to access https://dev.azure.com. が発生する問題への対応として説明されています。原因として、エージェント起動時にサービスプリンシパルのクライアントID・シークレットで取得したトークンが、数時間または数日待機した後のクリーンアップ時には有効でなくなる可能性が挙げられています。(GitHub)
何が変わったのか
今回の変更は、単なる表記修正ではありません。Docker エージェントの起動・登録・終了処理に関わる Bash スクリプトの実装改善です。PRの差分では、1ファイルに対して 100 additions / 26 deletions の変更が示されており、対象は docs/pipelines/agents/docker.md 内の Linux 用スクリプト例です。(GitHub)
| 変更点 | 内容 | 実務上の意味 |
|---|---|---|
| トークン取得処理の関数化 | load_azp_token() を追加し、トークン取得とトークンファイル書き込みを集約 | 起動時とクリーンアップ時で同じ考え方のトークン処理を使いやすくなる |
| クリーンアップ時のトークン再取得 | サービスプリンシパル利用時、cleanup() 内で新しいトークン取得を試行 | 長時間待機後に古いトークンでエージェント削除を試みるリスクを下げる |
AZP_TOKEN_FILE の既定パス変更 | 固定パス /azp/.token ではなく、スクリプト配置場所基準の .token を使う方向に変更 | /azp が存在しない、または書き込めない環境での失敗を減らす |
| シークレット露出の抑制 | AZP_CLIENTSECRET を子プロセスへ継承させない設計を追加 | パイプラインジョブ側に秘密情報が渡るリスクを下げる |
| Azure CLI の一時領域を分離 | AZURE_CONFIG_DIR を一時ディレクトリにし、ログアウト・削除処理を追加 | Azure CLI のキャッシュや認証情報が後続処理へ残りにくくなる |
| トークンファイルの権限確認 | ディレクトリ・ファイルの書き込み可否、空ファイル、権限設定を確認 | 権限不足や空トークンによる原因不明の失敗を早期に検出しやすくなる |
PR差分では、load_azp_token() の追加、AZP_CLIENTSECRET の unexport、Azure CLI の一時設定ディレクトリ作成、az logout・az account clear・一時ディレクトリ削除、トークンファイルの書き込み権限チェック、umask 177 と chmod 600 による権限調整が確認できます。(GitHub)
対応すべき人・影響を受けにくい人
今回の Azure documentation update は、Azure 全体の設定変更というより、Azure DevOps / Azure Pipelines の Docker エージェント運用に関する更新です。したがって、すべての Azure 利用者が急いで対応する必要はありません。
| 環境・運用 | 対応優先度 | 理由 |
|---|---|---|
| Linux コンテナーで Azure Pipelines セルフホステッドエージェントを運用している | 高 | 変更対象が Linux/Bash 版の Docker スクリプトであるため |
AZP_CLIENTID、AZP_CLIENTSECRET、AZP_TENANTID を使ってサービスプリンシパル認証している | 高 | トークン再取得とシークレットの扱いが主な改善点のため |
| エージェントがジョブ実行まで長時間待機する | 高 | 起動時に取得したトークンがクリーンアップ時に有効でない可能性があるため |
コンテナー停止・再起動時に VS30063 が出る | 高 | 今回のPRが扱っている典型的な症状と一致するため |
| PAT のみで短時間実行し、ジョブごとに破棄している | 中 | 直接の影響は限定的だが、トークンファイル権限や環境変数管理は確認したい |
| Windows PowerShell 版の Docker エージェントだけを使っている | 低 | 今回のPRの主対象は Linux/Bash スクリプトのため |
| Microsoft-hosted agent だけを使っている | 低 | 自前の Docker エージェントスクリプトを管理していないため |
Microsoft Learn の環境変数一覧では、PAT 利用時は AZP_TOKEN、サービスプリンシパル利用時は AZP_CLIENTID、AZP_CLIENTSECRET、AZP_TENANTID が必要とされています。今回の変更は、まさにこの認証情報を Linux コンテナー内のスクリプトでどう扱うかに関係します。(Microsoft Learn)
なぜ VS30063 が問題になるのか
VS30063: You are not authorized to access https://dev.azure.com. は、Azure DevOps へのアクセス権限や認証トークンに問題があるときに出るエラーです。今回のPRでは、エージェント起動時に取得したトークンが、クリーンアップ時点では古くなっているケースが問題として説明されています。(GitHub)
Docker エージェントの運用では、次のような流れがよくあります。
| タイミング | 従来起きやすい問題 |
|---|---|
| コンテナー起動時 | サービスプリンシパルで Azure DevOps 用のトークンを取得する |
| エージェント待機中 | ジョブが来るまで数時間から数日待機することがある |
| ジョブ実行後または停止時 | 古いトークンでエージェント登録削除を試みる |
| クリーンアップ時 | 認証エラーになり、エージェント削除や後処理が失敗する |
この問題が厄介なのは、起動時には正常に見える点です。コンテナーは起動し、エージェントも登録されているため、認証設定は一見正しく見えます。しかし、時間が経ってから停止や削除の処理で失敗するため、原因をネットワークや権限設定の問題と誤解しやすくなります。
移行前に確認すべき設定
今回の変更を取り込む前に、まず現在の Docker エージェントがどの認証方式で動いているかを確認します。特に、サービスプリンシパルを使っている場合は、起動スクリプト内でトークン取得処理がどこに書かれているか、クリーンアップ時に再取得しているかを見てください。
確認するコマンド例は次のとおりです。
grep -n "AZP_CLIENTID\|AZP_CLIENTSECRET\|AZP_TENANTID\|AZP_TOKEN_FILE\|VSO_AGENT_IGNORE\|cleanup\|load_azp_token" start.sh
チェック観点は次の4つです。
| 確認項目 | 見るべきポイント |
|---|---|
| 認証方式 | AZP_TOKEN のPAT運用か、サービスプリンシパル運用か |
| トークンファイル | AZP_TOKEN_FILE が固定パスに依存していないか |
| クリーンアップ処理 | cleanup() が古いトークンだけに依存していないか |
| 秘密情報の扱い | AZP_CLIENTSECRET がジョブプロセスへ渡らないようになっているか |
現行の Microsoft Learn ドキュメントでは、Linux 版スクリプトに cleanup() があり、config.sh remove にトークンファイルの内容を渡してエージェント削除を行う流れが示されています。また、VSO_AGENT_IGNORE で AZP_TOKEN と AZP_TOKEN_FILE を無視する設定も含まれています。今回のPRは、この周辺をさらに整理し、サービスプリンシパル利用時の再取得や AZP_CLIENTSECRET の扱いを改善するものです。(Microsoft Learn)
実務での対応手順
このPRを見てすぐ本番の start.sh を書き換えるのではなく、次の順序で進めるのがおすすめです。
| 手順 | 作業内容 | 判断基準 |
|---|---|---|
| 現状把握 | 本番で使っている docker.md ベースの start.sh を確認する | 公式サンプルをそのまま使っているか、独自改修があるか |
| 認証方式の確認 | PAT かサービスプリンシパルかを確認する | サービスプリンシパルなら優先度高 |
| エラーログ確認 | VS30063、config.sh remove、cleanup 失敗のログを探す | 停止・再起動時に出ていれば要対応 |
| 検証環境で反映 | PR差分の考え方を検証用エージェントに適用する | 起動、ジョブ実行、停止、再起動が通るか |
| セキュリティ確認 | トークンファイル権限、環境変数、Azure CLI キャッシュを確認する | シークレットがジョブログや子プロセスに残らないか |
| 本番反映 | 影響の少ないエージェントプールから段階的に反映する | 失敗時に旧スクリプトへ戻せる状態にする |
特に重要なのは、停止時のテストです。起動テストだけでは今回の問題を検出できません。検証では、エージェントを起動してすぐ止めるだけでなく、一定時間待機させた後にジョブ実行と停止を行い、クリーンアップが成功するか確認してください。
変更を取り込むときの注意点
PRがまだ確定版ではない可能性がある
2026年5月11日時点で、対象PRは Open 状態です。GitHub上では do-not-merge や Change sent to author などのラベルも確認できます。つまり、記事執筆時点では「公式サンプルの改善案として確認すべき内容」ではあるものの、最終的なマージ済み仕様として扱うのは避けるべきです。(GitHub)
本番に反映する場合は、次のどちらかを確認してください。
- Microsoft Learn の
docker.mdに同等の変更が反映されているか - PRがマージ済みになり、該当ドキュメントの正式な内容として公開されているか
/azp/.token 前提の独自処理がないか確認する
今回の変更では、AZP_TOKEN_FILE の既定パスを固定の /azp/.token から、スクリプトの場所を基準にした .token へ変える意図が示されています。PR本文でも、/azp/.token が存在しない可能性のあるハードコードされたパスである点が修正理由として説明されています。(GitHub)
そのため、社内で次のような独自処理を入れている場合は注意が必要です。
cat /azp/.token
rm -f /azp/.token
chmod 600 /azp/.token
スクリプト側の既定パスが変わると、これらの処理は期待どおりに動かない可能性があります。AZP_TOKEN_FILE を明示的に指定している場合は、そのパスが存在し、書き込み可能で、ディレクトリではなくファイルとして扱われているか確認してください。
Azure CLI のキャッシュを残さない
サービスプリンシパルでトークンを取得する場合、Azure CLI のログイン状態やキャッシュがコンテナー内に残ると、後続ジョブへ影響する可能性があります。今回の差分では、AZURE_CONFIG_DIR を一時ディレクトリに分離し、az logout、az account clear、一時ディレクトリ削除を行う処理が追加されています。(GitHub)
これは地味ですが重要です。CI/CD のエージェントは、ビルドスクリプトやテストコードなど、複数の処理が同じコンテナー上で動くことがあります。認証情報をジョブ側に残さない設計は、障害対応だけでなくセキュリティ対策としても有効です。
よくある失敗と対処法
起動は成功するのに停止時だけ失敗する
この場合、起動時の認証ではなく、クリーンアップ時のトークン状態を疑います。サービスプリンシパルで起動時にトークンを取得しているだけの場合、停止時に再取得できる構成になっているか確認してください。
AZP_TOKEN_FILE が空、または読めない
トークンファイルが存在していても、中身が空なら認証には使えません。今回の差分では、トークンファイルが読み取り可能か、空でないか、既存ファイルが書き込み可能かを確認する処理が追加されています。(GitHub)
確認例は次のとおりです。
test -r "$AZP_TOKEN_FILE" && echo "readable"
test -s "$AZP_TOKEN_FILE" && echo "not empty"
ls -l "$AZP_TOKEN_FILE"
AZP_CLIENTSECRET がジョブ側に見えてしまう
今回の変更では、AZP_CLIENTSECRET を子プロセスへ継承させないための処理や、VSO_AGENT_IGNORE に AZP_CLIENTSECRET を含める変更が入っています。(GitHub)
本番環境では、ジョブログに環境変数を出力するデバッグ処理がないかも確認してください。たとえば、障害調査用に env や printenv をそのまま出す処理が残っていると、シークレット管理の改善をしてもログ側から漏れる可能性があります。
今回の更新をどう判断すべきか
この Azure documentation update は、Azure Pipelines の Docker エージェントを安定して運用するための実務的な改善です。特に、サービスプリンシパル認証を使う Linux コンテナーエージェントでは、クリーンアップ時に新しいトークンを取得する考え方を取り入れることで、長時間待機後の認証エラーを減らせる可能性があります。
ただし、現時点でPRが未マージの場合は、正式なドキュメント更新としてそのまま扱うのではなく、次の順で確認してください。
- Microsoft Learn の
docker.mdに反映されたか確認する - 自社の
start.shが Linux/Bash 版サンプル由来か確認する - サービスプリンシパル利用環境を優先して検証する
- 起動だけでなく、ジョブ実行後の停止・削除までテストする
AZP_TOKEN_FILE、AZP_CLIENTSECRET、Azure CLI キャッシュの扱いを確認する
今回の変更は、派手な新機能ではありません。しかし、CI/CD 基盤では「終了時に正しく片付けられるか」が運用品質を左右します。Docker で Azure Pipelines セルフホステッドエージェントを使っているなら、トークンの取得タイミング、保存場所、クリーンアップ時の再取得、秘密情報の継承範囲をこの機会に見直しておくと安全です。

コメント