Microsoft Entra ID アプリケーションのシークレットや証明書の有効期限チェック
はじめに
Microsoft Entra ID に登録したアプリケーションや SAML の証明書・シークレットは有効期限が設定されており、期限切れとなった場合に必要なアプリにアクセスできなくなるリスクがあります。SAML 証明書は以下のように通知する仕組みになっているのですが、アプリケーションのほうは自身でチェックする必要がありますので、方法をまとめていきます。
推奨事項を使う
Microsoft Entra ワークロード ID Premium ライセンスを持っている場合、以下の推奨事項でチェックが可能です。(ライセンスがなくても現時点では見えますが)
Beta ですが、Microsoft Graph PowerShell からも取得できるので、自動化も可能かと思います。
ライセンスを持っていない場合
Microsoft Entra ワークロード ID Premium ライセンスを持ってない場合、自身でチェックする仕組みを作る必要があります。アプリのシークレット/証明書と SAML 証明書ともに Microsoft Graph PowerShell で詳細情報を取得可能なので、そこから 30 日以内に有効期限が切れる項目を CSV で一覧化します。Get-ExpiringApplication.ps1
がアプリ登録のシークレットと証明書、Get-ExpiringServicePrincipal.ps1
がエンタープライズ アプリの SAML 証明書になります。
# テナント指定
$TenantID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
# CSV ファイルのヘッダーを作成
$header = "Type,ApplicationDisplayName,CredentialType,CredentialKeyId,CredentialEndDate,DaysToExpire"
# CSV ファイルにヘッダーを書き込み
$header | Out-File -FilePath "ApplicationExpireDate.csv"
# Graph PowerShell 接続
Connect-MgGraph -Scopes 'Application.Read.All' -TenantId $TenantID
# Get-MgApplication でアプリ登録の一覧を取得
$Applications = Get-MgApplication -All
# 30 日以内に期限が切れる証明書やシークレットを持つアプリ登録をリストアップ
$Applications | ForEach-Object {
$Application = $_
$ApplicationDisplayName = $Application.DisplayName
$ApplicationKeyCredential = $Application.KeyCredentials
$ApplicationPasswordCredential = $Application.PasswordCredentials
$ApplicationKeyCredential | ForEach-Object {
$KeyCredential = $_
$KeyCredentialEndDate = $KeyCredential.EndDateTime
$KeyCredentialKeyId = $KeyCredential.KeyId
if ($KeyCredentialEndDate -ne $null) {
$KeyCredentialEndDate = [DateTime]::Parse($KeyCredentialEndDate)
$DaysToExpire = ($KeyCredentialEndDate - (Get-Date)).Days
if ($DaysToExpire -lt 30) {
# CSV ファイルにカンマ区切りで書き込み
$tmp = "Application,$ApplicationDisplayName,Key,$KeyCredentialKeyId,$KeyCredentialEndDate,$DaysToExpire"
$tmp | Out-File -FilePath "ApplicationExpireDate.csv" -Append
}
}
}
$ApplicationPasswordCredential | ForEach-Object {
$PasswordCredential = $_
$PasswordCredentialEndDate = $PasswordCredential.EndDateTime
$PasswordCredentialKeyId = $PasswordCredential.KeyId
if ($PasswordCredentialEndDate -ne $null) {
$PasswordCredentialEndDate = [DateTime]::Parse($PasswordCredentialEndDate)
$DaysToExpire = ($PasswordCredentialEndDate - (Get-Date)).Days
if ($DaysToExpire -lt 30) {
# CSV ファイルにカンマ区切りで書き込み
$tmp = "Application,$ApplicationDisplayName,Password,$PasswordCredentialKeyId,$PasswordCredentialEndDate,$DaysToExpire"
$tmp | Out-File -FilePath "ApplicationExpireDate.csv" -Append
}
}
}
}
# テナント指定
$TenantID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
# CSV ファイルのヘッダーを作成
$header = "Type,ServicePrincipalDisplayName,CredentialType,CredentialKeyId,CredentialEndDate,DaysToExpire"
# CSV ファイルにヘッダーを書き込み
$header | Out-File -FilePath "ServicePrincipalExpireDate.csv"
# Graph PowerShell 接続
Connect-MgGraph -Scopes 'Application.Read.All' -TenantId $TenantID
# Get-MgServicePrincipal でサービス プリンシパルの一覧を取得
$ServicePrincipals = Get-MgServicePrincipal -All
# 30 日以内に期限が切れる証明書やシークレットを持つ Service Principal をリストアップ
$ServicePrincipals | ForEach-Object {
$ServicePrincipal = $_
$ServicePrincipalDisplayName = $ServicePrincipal.DisplayName
$ServicePrincilalType = $ServicePrincipal.ServicePrincipalType
$ServicePrincipalKeyCredential = $ServicePrincipal.KeyCredentials
$ServicePrincipalPasswordCredential = $ServicePrincipal.PasswordCredentials
# マネージド ID 以外を対象
if ($ServicePrincilalType -ne "ManagedIdentity") {
$ServicePrincipalKeyCredential | ForEach-Object {
$KeyCredential = $_
$KeyCredentialEndDate = $KeyCredential.EndDateTime
$KeyCredentialKeyId = $KeyCredential.KeyId
if ($KeyCredentialEndDate -ne $null) {
$KeyCredentialEndDate = [DateTime]::Parse($KeyCredentialEndDate)
$DaysToExpire = ($KeyCredentialEndDate - (Get-Date)).Days
if ($DaysToExpire -lt 30) {
# CSV ファイルにカンマ区切りで書き込み
$tmp = "Service Principal,$ServicePrincipalDisplayName,Key,$KeyCredentialKeyId,$KeyCredentialEndDate,$DaysToExpire"
$tmp | Out-File -FilePath "ServicePrincipalExpireDate.csv" -Append
}
}
}
$ServicePrincipalPasswordCredential | ForEach-Object {
$PasswordCredential = $_
$PasswordCredentialEndDate = $PasswordCredential.EndDateTime
$PasswordCredentialKeyId = $PasswordCredential.KeyId
if ($PasswordCredentialEndDate -ne $null) {
$PasswordCredentialEndDate = [DateTime]::Parse($PasswordCredentialEndDate)
$DaysToExpire = ($PasswordCredentialEndDate - (Get-Date)).Days
if ($DaysToExpire -lt 30) {
# CSV ファイルにカンマ区切りで書き込み
$tmp = "Service Principal,$ServicePrincipalDisplayName,Password,$PasswordCredentialKeyId,$PasswordCredentialEndDate,$DaysToExpire"
$tmp | Out-File -FilePath "ServicePrincipalExpireDate.csv" -Append
}
}
}
}
}
結果はこのように出力されます。
ちなみに
スクリプト書いた後 (GitHub Copilot にほぼ書いてもらいましたが)に分かったのですが、公式ドキュメントでスクリプトが提供されていました。ので、こちらを使っていただいたほうがよさそうです。
次のステップ
次はこれを Azure Functions で実行できるようにして、Logic Apps と組み合わせて定期的なチェックとメール通知を実装します。
Discussion