記事公開日
【Microsoft Entra】昨日まで動いていたAPI連携が朝から動かない― クライアントシークレット失効を防ぐ棚卸し術

この記事のポイント
アプリ登録のクライアントシークレットや証明書は、期限が切れた瞬間にバッチ・API連携を認証エラーで止めます。Microsoft Entra recommendationsに通知機能はありますが、有償ライセンスが前提な上、通知先はApplication Administratorロールの保持者に限られます。本記事では、読み取り専用のスコープだけでテナント全体の資格情報の期限を棚卸しし、「失効事故」を予定された更新作業に変える設計を整理します。
- 失効は「事故」ではなく「予定された停止」:
シークレットの期限はendDateTimeとして最初から記録されています。把握していないだけで、止まる日は決まっています。 - 棚卸しは読み取り専用スコープだけでできる:
Application.Read.All(読み取り専用)でテナント内全アプリのシークレット・証明書の期限を一覧化できます。管理者ロールは不要です。 - 構造的な解決は「シークレットをやめる」こと:
期限監視の仕組み化に加えて、フェデレーション資格情報やマネージドIDへ寄せれば、失効事故そのものをなくせます。
こんにちは!DXソリューション営業本部の大和矢です。
「昨日まで動いていたAPI連携が、朝からinvalid_clientで全滅」
―― その原因、クライアントシークレットの期限切れかもしれません。
Microsoft Entra IDのアプリ登録に発行するクライアントシークレットや証明書には、必ず有効期限があります。
そして期限が切れた瞬間、そのアプリを使うバッチ・API連携・自動化は、認証エラー(AADSTS7000222)で一斉に止まります。
本記事では、テナント内の資格情報の期限を読み取り専用の権限だけで棚卸しし、失効を事故にしない設計を整理します(2026年7月時点の情報です)。
本記事は、Microsoft Graphの権限棚卸しシリーズの続編です。前回はアプリに付与された「危険な権限」を棚卸ししました。
失効は「事故」ではなく「予定された停止」
アプリ登録に発行するクライアントシークレットには、作成時に必ず有効期限を設定します。指定できるのは最長でも2年(24か月)までで、それより長い期限は設定できません。ポータルの選択肢は180日・365日・730日などで、Microsoftは12か月未満を推奨しています(アプリケーション資格情報の追加と管理)。
証明書(keyCredentials)にも有効期限があります。
つまり、そのアプリがいつ認証できなくなるかは、作成した瞬間から決まっています。
それでも失効「事故」が繰り返されるのは、次の3つが揃っているからです。
- 通知機能はあるが、宛先が絞られている:
Microsoft Entra recommendationsに「Renew expiring application credentials」という通知機能(プレビュー)があり、資格情報の残りが30日を切るとApplication Administratorロールの保持者にメールが届きます。ただし公式ドキュメントには、Microsoft Entra Workload IDライセンスが前提であること、そのロールの保持者がテナントにいなければメール自体が送信されないことが明記されています。 - 作った人と運用する人が違う:
開発ベンダーや退職済みの担当者が作ったアプリは、期限の存在自体が引き継がれていないことがあります。 - 止まって初めて存在に気づく:
シークレットは期限が切れても何も起きません。次にそのアプリがトークンを取りに行った瞬間、AADSTS7000222(The provided client secret keys are expired)で失敗し、そこで初めて「このアプリ、何だっけ」が始まります。
逆に言えば、期限を一覧で見える化してしまえば、失効は「事故」から「予定された更新作業」に変わります。
そしてこの見える化は、管理者ロールがなくてもできます。
読み取り専用スコープで期限を全件棚卸しする
テナント内のアプリ登録と、その資格情報(passwordCredentials=シークレット/keyCredentials=証明書)の期限は、Microsoft Graphの読み取り専用スコープ Application.Read.All だけで取得できます(List applications)。
グローバル管理者などの管理者ロールは不要です。公式のList applications APIでも、サポートされる役割の筆頭に「既定のユーザー権限を持つ非管理者メンバー(またはゲスト)」が明記されています。
ただし、Application.Read.Allは管理者の同意が必要なスコープです。テナントでこのスコープにまだ同意していない場合は、一度だけ管理者に同意してもらう必要があります(同意は一度きりで、以降は管理者ロールを持たない一般ユーザーでも実行できます)。
Graph PowerShellでの棚卸しの骨子は、次のとおりです。
# 読み取り専用スコープで接続
Connect-MgGraph -Scopes "Application.Read.All"
# 全アプリ登録の資格情報と期限を一覧化
Get-MgApplication -All -Property DisplayName, AppId, PasswordCredentials, KeyCredentials |
ForEach-Object {
$app = $_
# シークレット(passwordCredentials)と証明書(keyCredentials)を、種別を付けて展開する
$creds = @($app.PasswordCredentials | ForEach-Object { [PSCustomObject]@{ 種別 = "シークレット"; 期限 = $_.EndDateTime } })
$creds += @($app.KeyCredentials | ForEach-Object { [PSCustomObject]@{ 種別 = "証明書"; 期限 = $_.EndDateTime } })
$creds | ForEach-Object {
[PSCustomObject]@{
アプリ名 = $app.DisplayName
AppId = $app.AppId
種別 = $_.種別
期限 = $_.期限
残り日数 = if ($_.期限) { [int]([datetime]$_.期限 - (Get-Date)).TotalDays } else { $null }
}
}
} | Sort-Object 残り日数 | Export-Csv secret_expiry.csv -NoTypeInformation -Encoding UTF8
ポイントは、取得できるのは期限などのメタデータだけという点です。
シークレットの「値」そのものは作成時に一度表示されるだけで、後からGraphで読み出すことはできません。棚卸しで秘密情報に触れる心配はありません。
実際に手元で試すと、次の3つでつまずきやすいので先に共有しておきます:
- モジュールが読み込めない:
「Connect-MgGraphコマンドはモジュール〇〇で見つかりましたが、読み込むことができませんでした」というエラーが出た場合、多くは実行ポリシーが原因です。
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser(現在のユーザーのみに適用され、管理者権限は不要)を実行してから再度お試しください。 - CSVの保存に失敗する:
スタートメニューからPowerShellを起動すると、既定の作業フォルダがC:\Windows\System32になっていることがあり、書き込み権限がなくExport-Csvが失敗します。
出力先はデスクトップなど、フルパスで指定してください。 - 「Authentication needed. Please call Connect-MgGraph.」と表示される:
Connect-MgGraphの接続はPowerShellのウィンドウ(プロセス)単位で保持されます。
ウィンドウを閉じて開き直した場合や時間が空いた場合は、Connect-MgGraphから実行し直してください。
自分のアプリだけなら、もっと簡単:
自分が所有者になっているアプリ登録なら、Entra管理センター(またはAzureポータル)の「アプリの登録」→「所有しているアプリケーション」で、証明書とシークレットの期限をいつでも確認できます。
「全社の棚卸しは読み取りスコープで、自分のアプリはポータルで」と覚えておくと、日常の点検が回しやすくなります。
棚卸し結果の読み方 ― 直す順番のつけ方
CSVを開くと、想像より多くの行が出てくるはずです。
たとえば、次のような一覧が得られます(アプリ名・AppIdはサンプルのダミー値です。残り日数がマイナスの行は、すでに期限切れです)。
| アプリ名 | AppId | 種別 | 期限 | 残り日数 |
|---|---|---|---|---|
| 夜間売上バッチ連携 | aaaaaaaa-1111-2222-3333-444444444444 | シークレット | 2025/11/15 | -234 |
| 退職者作成_検証アプリ | bbbbbbbb-1111-2222-3333-444444444444 | シークレット | 2026/02/10 | -147 |
| Teams通知フロー | cccccccc-1111-2222-3333-444444444444 | シークレット | 2026/07/25 | 18 |
| 基幹システムAPI連携 | dddddddd-1111-2222-3333-444444444444 | 証明書 | 2026/09/30 | 85 |
| 基幹システムAPI連携 | dddddddd-1111-2222-3333-444444444444 | シークレット | 2027/06/10 | 338 |
| 社内検証用アプリ | eeeeeeee-1111-2222-3333-444444444444 | シークレット | 2028/06/25 | 718 |
このサンプルには、対応の優先度を分ける典型的なパターンが詰まっています。
すでに期限切れの行、まもなく切れる行、同じAppIdに複数ぶら下がった行、2年近い長期シークレット――こうした違いを、4つの軸で優先順位として整理します。
| 軸 | 見るポイント |
|---|---|
| ① 期限の近さ | 残り30日以内は即対応。90日以内は次の定例で更新計画を立てる。すでに期限切れの行は「止まっているのに誰も気づいていない」か「もう使われていない」かの切り分けが必要。 |
| ② 業務影響 | そのアプリが止まると何が止まるか。夜間バッチ・基幹連携・監視ツールなど、影響の大きいものから台帳化する。 |
| ③ 期限の長さ | 2年などの長すぎるシークレットは、それ自体が是正対象。漏洩したときに悪用できる期間がそのまま長くなるため、短い期限+定期ローテーションへ寄せる。 |
| ④ シークレットの本数 | 同じAppIdに対して有効なシークレットが何本もぶら下がっていないか確認する。作り直すたびに古いものを削除せず追加していくと、誰も使っていないのに有効なシークレットだけが積み上がる。CSVをAppIdでグルーピングし、本数が多いアプリは棚卸しのついでに不要な分を削除する。 |
ここで前回の危険権限の棚卸し結果と突き合わせると、精度が一段上がります。
「強い権限を持っている × シークレットの期限が長い」アプリは、漏洩したときの被害が最大化する組み合わせです。台帳の最上段に置いてください。
失効を事故にしない設計 ― 監視・台帳・脱シークレット
棚卸しは一度やって終わりでは意味がありません。「気づける仕組み」と「そもそも失効しない構成」の2段構えで設計します。
- 気づける仕組み(運用でカバー):
棚卸しスクリプトをPower AutomateやLogic Appsで定期実行し、残り90日/30日を切った資格情報をTeamsやメールに通知します。
通知先を「アプリの所有者」に紐づけると運用が回りやすくなりますが、そのためには先ほどのスクリプトに、各アプリのオブジェクトIDと所有者(Owners)の取得を追加する必要があります(AppIdだけでは所有者を辿れません)。所有者まで取得すると、所有者が空のアプリ=誰も管理していないアプリも同時に炙り出せます。 - そもそも失効しない構成(構造で解決):
シークレットの更新作業を続けるより、資格情報の形を変えるほうが根本的です。失効という事象そのものをなくせるのは、次の2つです。
・Azure上で動く処理 → マネージドID(資格情報の管理自体が不要)
・GitHub Actionsや他クラウドなどAzure外からのアクセス → フェデレーション資格情報(ワークロードIDフェデレーション)でシークレットレスに(ワークロードIDフェデレーション)
なお、どうしても資格情報が必要な場合は、証明書に置き換えてAzure Key Vaultで一元管理すると、漏洩リスクと管理の手間を下げられます。
ただし証明書にも有効期限はあるため、この場合は棚卸しと期限監視を続ける必要があります(=失効そのものがなくなるわけではありません)。
組織として「作らせない」統制も視野に:
Microsoft Entra IDのアプリケーション管理ポリシーを使うと、「シークレットの有効期間は最大○日」「パスワード資格情報の新規追加を禁止」といったルールをテナント全体に強制できます。
ただしこのポリシーが効くのは、以後に追加される資格情報(かつ指定した日付以降に作成されたアプリ)に対してで、すでに存在する長期シークレットが自動で短縮・削除されるわけではありません。「既存分は棚卸しで是正、新規分はポリシーで作らせない」という役割分担になります。
こちらの設定は管理者の作業になるため、棚卸し結果を材料に「長期シークレットがこれだけあるので、上限を設けませんか」と情シスへ提案する、という持ち込み方が現実的です。
よくある質問(FAQ)
Q. 管理者ロールがなくても本当に実行できますか?
はい。棚卸しに必要なのはMicrosoft Graphの読み取り専用スコープ(Application.Read.All)であり、グローバル管理者などの管理者ロールは不要です。公式のList applications APIでも、既定のユーザー権限を持つ非管理者メンバーがサポート対象として明記されています。
ただし、Application.Read.Allは管理者の同意が必要なスコープです。テナントでこのスコープにまだ同意していない場合は、一度だけ管理者に同意してもらう必要があります(依頼するのは「読み取り専用スコープへの一度きりの同意」であって、管理者ロールの付与ではありません)。
Q. 棚卸しでシークレットの「値」が見えてしまうことはありませんか?
ありません。Graphで取得できるのは表示名・作成日・有効期限などのメタデータのみです。
シークレットの値は作成した瞬間に一度表示されるだけで、その後はMicrosoft側にも平文では保存されず、読み出す手段がありません。
Q. 期限切れが近いことを通知する標準機能はありますか?
あります。Microsoft Entra recommendations(Entra管理センターの「概要」→「推奨事項」)の「Renew expiring application credentials」(プレビュー)が、資格情報の残りが30日を切ったアプリをApplication Administratorロールの保持者へメール通知します(2026年7月時点)。
ただし公式ドキュメントには、Microsoft Entra Workload IDライセンスが前提であること、PIM環境ではロールをアクティブ化していないと届かないこと、そのロールの保持者が誰もいなければメール自体が送信されないことが明記されています。読み取り専用スコープで自前に棚卸しする本記事のアプローチは、この機能の有無にかかわらず有効です。
Q. シークレットの有効期限は何日にすべきですか?
ポータルの既定の選択肢は180日で、Microsoftは短い有効期間とローテーションを推奨しています。
ただし「180日ごとに手で更新」を続けるのは運用負荷も事故リスクも高いため、可能なものからマネージドIDやフェデレーション資格情報へ移行し、シークレットの本数自体を減らしていくことをおすすめします。
まとめ:止まる日は最初から決まっている
今回は、クライアントシークレット・証明書の期限切れを事故にしないための棚卸しと設計を整理しました。
学びは3つです。
- 失効は予定された停止:
期限はendDateTimeとして最初から記録されています。公式の通知機能はライセンスと宛先ロールの条件付きのため、見える化しない限り「ある日突然」は繰り返されます。 - 棚卸しは読み取り専用でできる:
Application.Read.Allだけでテナント全体の期限一覧が作れます。管理者ロールがなくても、今日から始められます。 - 最終形は脱シークレット:
マネージドID・フェデレーション資格情報へ寄せれば、失効事故そのものがなくなります。更新作業の自動化より一段上の解決策です。
まずは手元で棚卸しスクリプトを実行して、「残り日数」列を眺めてみてください。
30日を切った行が1つでもあれば、この記事を読んだ今日が、事故を防げる最後のチャンスかもしれません。
ここまでお読みいただき、ありがとうございました。
なお、本記事は Microsoft Entra ID のガバナンス・権限管理に関する内容でした。関連するテーマは、QESブログの「Microsoft Entra ID Governance」カテゴリでもまとめて発信していますので、あわせてご覧いただけますと幸いです。
QUICK E-Solutionsでは、AIを活用した業務効率化や、Microsoft Entra IDをはじめとした高度なセキュリティシステムの導入・設計をお手伝いしております。
それ以外でも様々なアプリケーションの開発・導入を行っております。提供するサービス・ソリューションにつきましては こちら に掲載しております。
システム開発・構築でお困りの問題や弊社が提供するサービス・ソリューションにご興味を抱かれましたら、ぜひ一度 お問い合わせ ください。
※このブログで参照されている、Microsoft、Microsoft Entra ID、Microsoft Azure、Microsoft Graph、PowerShell、Azure Key Vault、Power Automate、Azure Logic Apps、Microsoft Teams、GitHubは、米国Microsoft Corporationおよび関連会社の米国およびその他の国における商標または登録商標です。

