次の方法で共有


セキュリティのベスト プラクティス: Microsoft Entra SDK for AgentID のセキュリティ強化

このガイドでは、運用環境で Microsoft Entra SDK for AgentID を安全に展開および運用するための包括的なセキュリティ構成とセキュリティ強化のベスト プラクティスについて説明します。 ネットワーク分離、資格情報管理、トークン検証、ランタイム セキュリティ、監視などの重要なセキュリティ制御が含まれており、SDK のデプロイがセキュリティのベスト プラクティスに従っていることを確認します。

注意事項

Microsoft Entra SDK for AgentID API に パブリックにアクセス することはできません。 アクセスできるのは、同じ信頼境界内のアプリケーション (同じポッド、同じ仮想ネットワークなど) だけです。 既定では、許可されるホストは localhost です。 この API を公開すると、 承認されていないトークンの取得が有効になります。これは重大なセキュリティ リスクです。 また、同じ信頼境界内のすべてのアプリケーションがこの API にアクセスできる点にも注意してください。 その境界内のすべてのアプリケーションが信頼され、プロパティがセキュリティで保護されていることを確認します。

SDK を実行しても安全ですか?

Microsoft Entra SDK for AgentID はセキュリティを念頭に置いて設計されていますが、その安全性は適切な構成と展開のプラクティスによって異なります。 セキュリティで保護されたデプロイを確保するには、次のベスト プラクティスに従います。

  • コンテナー化された環境でのみ実行する
  • localhost/pod-internal のみにアクセスを制限する
  • Kubernetes ネットワーク ポリシーを使用する
  • 資格情報を安全に格納する (Key Vault、シークレット)
  • 非ルート ユーザーとして実行する
  • 監査ログを有効にする

ネットワークのセキュリティ

ネットワークの分離は、認証操作を保護するために重要です。 Microsoft Entra SDK for AgentID は、厳密なアクセス制御と包括的なトラフィック フィルタリングを使用して、信頼された境界内で実行する必要があります。 これには、localhost 専用のバインド、ポッド内部通信、認証エンドポイントへの不正アクセスを防止するネットワーク ポリシーが含まれます。

SDK アクセスの制限

認証エンドポイントへの外部ネットワーク アクセスを防ぐために、localhost でのみリッスンするように Kestrel を構成します。

containers:
- name: sidecar
  image: mcr.microsoft.com/entra-sdk/auth-sidecar:1.0.0
  env:
  - name: Kestrel__Endpoints__Http__Url
    value: "http://127.0.0.1:5000"

または、アクセスを制限するために、AllowedHosts で Kestrel のホスト フィルター処理を使用します。

containers:
- name: sidecar
  image: mcr.microsoft.com/entra-sdk/auth-sidecar:1.0.0
  env:
  - name: AllowedHosts
    value: "localhost;127.0.0.1"

Pod-Local 通信を使用する

localhost 経由で Microsoft Entra SDK for AgentID と通信するようにアプリケーションを構成して、トラフィックが同じポッド内に残り、ネットワークを通過しないようにします。

containers:
- name: app
  env:
  - name: SIDECAR_URL
    value: "http://localhost:5000" # Pod-local communication only

LoadBalancer またはイングレスを介して公開しないでください (これにより、信頼された境界外からの未承認のトークン取得が許可されます)。

# WRONG - exposes Microsoft Entra SDK for AgentID publicly
apiVersion: v1
kind: Service
metadata:
  name: sidecar-service
spec:
  type: LoadBalancer # Exposes SDK publicly - INSECURE
  selector:
    app: myapp
  ports:
  - port: 5000

資格情報の管理

セキュリティで保護された資格情報管理は、SDK セキュリティの基礎となります。 可能な限りマネージド ID を使用してシークレットを排除し、認証資格情報を構成するときに最小限の特権の原則に従います。

コンテナーのワークロード ID を優先する

コンテナー化されたデプロイ (AKS) に Azure AD ワークロード ID を使用して、シークレットを完全に排除し、ファイルベースのトークン プロジェクションを使用してセキュリティで保護された資格情報管理を確保します。

apiVersion: v1
kind: ServiceAccount
metadata:
  name: myapp-sa
  annotations:
    azure.workload.identity/client-id: "<managed-identity-client-id>"

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  template:
    metadata:
      labels:
        azure.workload.identity/use: "true"
    spec:
      serviceAccountName: myapp-sa
      containers:
      - name: sidecar
        image: mcr.microsoft.com/entra-sdk/auth-sidecar:1.0.0
        env:
        - name: AzureAd__ClientId
          value: "<web-api-client-id>"
        
        # Workload Identity credentials - uses file-based token projection
        - name: AzureAd__ClientCredentials__0__SourceType
          value: "SignedAssertionFilePath"

利点: ワークロード ID を使用すると、資格情報の自動管理、Azure RBAC 統合、完全な監査証跡を提供しながら、シークレットを格納またはローテーションする必要がなくなります。 トークンはワークロード ID webhook によってポッドに自動的に投影され、SDK は SignedAssertionFilePath 資格情報の種類を使用してそれを読み取ります。 このアプローチにより、従来のシークレットベースの認証と比較して、セキュリティ リスクと運用オーバーヘッドが大幅に削減されます。

: Azure VM と App Services (コンテナー化されていない環境) の場合は、代わりに、 SignedAssertionFromManagedIdentity 資格情報の種類でシステムまたはユーザー割り当てマネージド ID を使用します。 詳細については、「 マネージド ID の使用」を参照してください。

シークレットの代わりに証明書を使用する

クライアント シークレットを回避できない場合は、認証に証明書を優先します。 証明書は公開キー暗号化を使用し、抽出や誤用が困難なため、クライアント シークレットよりも強力なセキュリティを提供します。 一元管理と自動更新のために Azure Key Vault に証明書を格納します。

- name: AzureAd__ClientCredentials__0__SourceType
  value: "KeyVault"
- name: AzureAd__ClientCredentials__0__KeyVaultUrl
  value: "https://your-keyvault.vault.azure.net"
- name: AzureAd__ClientCredentials__0__KeyVaultCertificateName
  value: "your-cert-name"

利点: Azure Key Vault は、自動ローテーション、アクセス ポリシー、包括的な監査を使用して一元化された証明書管理を提供し、証明書がコンテナー イメージに埋め込まれることはありません。 詳細については、「 認証に証明書を使用する」を参照してください。

シークレットを安全に保存する

Kubernetes シークレットは、マネージド ID または証明書がオプションでない場合にクライアント シークレットを格納するのに適したオプションですが、シークレットが保存時に暗号化され、アクセスが厳密に制御されていることを確認します。

apiVersion: v1
kind: Secret
metadata:
  name: app-cert
type: Opaque
data:
  certificate.pfx: <base64-encoded-pfx>
  certificate.password: <base64-encoded-password>

---
containers:
- name: sidecar
  volumeMounts:
  - name: cert-volume
    mountPath: /certs
    readOnly: true
  env:
  - name: AzureAd__ClientCredentials__0__SourceType
    value: "Path"
  - name: AzureAd__ClientCredentials__0__CertificateDiskPath
    value: "/certs/certificate.pfx"
  - name: AzureAd__ClientCredentials__0__CertificatePassword
    valueFrom:
      secretKeyRef:
        name: app-cert
        key: certificate.password

volumes:
- name: cert-volume
  secret:
    secretName: app-cert
    items:
    - key: certificate.pfx
      path: certificate.pfx
    defaultMode: 0400  # Read-only for owner

クライアント シークレット (可能な場合は回避)

クライアント シークレットを使用する必要がある場合は、リスクを最小限に抑えるために追加のセキュリティ対策を実装します。 クライアント シークレットはマネージド ID や証明書よりも安全性が低いので、短い有効期限、保存時の暗号化によるストレージのセキュリティ保護、RBAC によるアクセスの制限、頻繁なローテーション スケジュールなど、追加の保護が必要です。 デプロイ マニフェストに表示されるコンテナー イメージまたは環境変数にシークレットを格納しないでください。

apiVersion: v1
kind: Secret
metadata:
  name: app-secrets
type: Opaque
stringData:
  client-secret: "<your-client-secret>"

---
containers:
- name: sidecar
  env:
  - name: AzureAd__ClientCredentials__0__SourceType
    value: "ClientSecret"
  - name: AzureAd__ClientCredentials__0__ClientSecret
    valueFrom:
      secretKeyRef:
        name: app-secrets
        key: client-secret

注意事項

シークレットをソース管理にコミットしないでください。 外部シークレット管理 (Azure Key Vault、Sealed Secrets など) を使用します。

トークンのセキュリティ

トークン セキュリティにより、有効な適切なスコープのトークンのみが SDK によって受け入れられ、処理されるようになります。 トークンの検証、スコープの要件、および対象ユーザーチェックを実装して、未承認のアクセスを防ぎ、トークンの誤用を制限します。

スコープの検証を有効にする

受信トークンに特定のスコープを要求する (スペース区切り):

- name: AzureAd__Scopes
  value: "access_as_user"

適切な対象ユーザーを設定する

トークンの検証に必要な対象ユーザーを構成します。

- name: AzureAd__Audience
  value: "api://your-api-id"

予想される対象ユーザーの値は、アプリの登録の 要求されたAccessTokenVersion によって異なります。

  • バージョン 2: {ClientId} 値を直接使用する
  • バージョン 1 または null: アプリ ID URI を使用する (通常はカスタマイズしていない限り api://{ClientId} )

使用前にトークンを検証する

ユーザー トークンを受け入れる前に、常に /Validate を呼び出します。

GET /Validate
Authorization: Bearer <user-token>

ランタイム セキュリティ

ランタイム セキュリティ コントロールは、変更、特権エスカレーション、および承認されていない機能アクセスから SDK コンテナーを保護します。 攻撃対象領域を減らすために、最小限の特権と読み取り専用ファイルシステムで実行するようにコンテナーを構成します。

読み取り専用のルートファイルシステム

コンテナー ファイルシステムの変更を防止する:

securityContext:
  readOnlyRootFilesystem: true

ポッドのセキュリティ ポリシー

セキュリティ標準を適用する:

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: sidecar-psp
spec:
  privileged: false
  allowPrivilegeEscalation: false
  requiredDropCapabilities:
  - ALL
  runAsUser:
    rule: 'MustRunAsNonRoot'
  seLinux:
    rule: 'MustRunAs'
  fsGroup:
    rule: 'MustRunAs'
  readOnlyRootFilesystem: true

ログ記録と監視

効果的なログ記録と監視により、異常を検出し、問題のトラブルシューティングを行い、コンプライアンスのために監査証跡を維持することができます。 環境に適したログ レベルを構成し、正常性プローブを実装して、SDK が期待どおりに動作することを確認します。

適切なログ記録の構成

運用環境:

- name: Logging__LogLevel__Default
  value: "Warning"
- name: Logging__LogLevel__Microsoft.Identity.Web
  value: "Information"

開発環境 (詳細):

- name: Logging__LogLevel__Default
  value: "Debug"
- name: ASPNETCORE_ENVIRONMENT
  value: "Development"

ヘルスモニタリングを有効にする

liveness と readiness のプローブを構成します。

livenessProbe:
  httpGet:
    path: /health
    port: 5000
  initialDelaySeconds: 10
  periodSeconds: 10
  failureThreshold: 3

readinessProbe:
  httpGet:
    path: /health
    port: 5000
  initialDelaySeconds: 5
  periodSeconds: 5
  failureThreshold: 3

ベスト プラクティスチェックリスト

この包括的なチェックリストを使用して、SDK のデプロイが、ネットワーク、資格情報、トークン、ランタイム、監視の各ディメンションにわたって推奨されるすべてのセキュリティ プラクティスに従っていることを確認します。

ネットワーク:

  • [ ] SDK は localhost/127.0.0.1 でのみリッスンします
  • [ ] LoadBalancer またはイングレスを介して公開されない
  • [ ] ネットワーク ポリシーによって外部アクセスが制限される
  • [ ] 外部通信用の HTTPS/TLS

資格 情報:

  • [ ] コンテナーにワークロード ID を使用する (AKS、Kubernetes、Docker) SignedAssertionFilePath
  • [ ] VM/App Services でマネージド ID を使用する SignedAssertionFromManagedIdentity
  • [ ] シークレットよりも証明書を優先する
  • [ ] セキュリティで保護された管理システムに格納されているシークレット
  • [ ] 定期的な資格情報の更新

トークン:

  • [ ] スコープの検証が有効になっている
  • [ ] 対象ユーザーの検証が構成されている
  • [ ] 使用前に検証されたトークン

ランタイム:

  • [ ] コンテナーは非ルートとして実行されます
  • [ ] 読み取り専用ルート ファイルシステム
  • [ ] 適用されるセキュリティ コンテキスト
  • [ ] リソース制限の設定

モニタリング:

  • [ ] 適切に構成されているログ設定
  • [ ] ヘルスチェック有効
  • [ ] 監査ログが有効になっている
  • [ ] 構成されたアラート

一般的なセキュリティ パターン

参照実装では、複数のセキュリティ制御をまとまりのあるデプロイ パターンに組み合わせる方法を示します。 これらのパターンは、さまざまな脅威モデルでの運用デプロイのテンプレートとして機能します。

高度セキュリティ デプロイメント

apiVersion: v1
kind: ServiceAccount
metadata:
  name: secure-app-sa
  annotations:
    azure.workload.identity/client-id: "<managed-identity-id>"

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: secure-app
spec:
  template:
    metadata:
      labels:
        azure.workload.identity/use: "true"
    spec:
      serviceAccountName: secure-app-sa
      securityContext:
        fsGroup: 2000
      containers:
      - name: sidecar
        image: mcr.microsoft.com/entra-sdk/auth-sidecar:1.0.0
        ports:
        - containerPort: 5000
        env:
        - name: Kestrel__Endpoints__Http__Url
          value: "http://127.0.0.1:5000"
        - name: AzureAd__TenantId
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: tenant-id
        - name: AzureAd__ClientId
          value: "<managed-identity-client-id>"
        securityContext:
          runAsNonRoot: true
          runAsUser: 1000
          readOnlyRootFilesystem: true
          allowPrivilegeEscalation: false
          capabilities:
            drop:
            - ALL
        resources:
          requests:
            memory: "128Mi"
            cpu: "100m"
          limits:
            memory: "256Mi"
            cpu: "250m"
        livenessProbe:
          httpGet:
            path: /health
            port: 5000
          initialDelaySeconds: 10
          periodSeconds: 10

資格情報を定期的にローテーションする

資格情報をローテーションすると、資格情報が漏洩または侵害された場合に攻撃者の機会を減らすことができます。 ローテーションの頻度は、資格情報の種類と組織のセキュリティ ポリシーによって異なります。

  • クライアント シークレット: 90 日ごと (推奨)
  • 証明書: 有効期限が切れる前(通常は 1 ~ 2 年ごと)
  • 署名済み HTTP 要求 (SHR) のキー: 組織のセキュリティ ポリシーに従います

実装ガイダンス: 自動ローテーション機能を備えた Azure Key Vault を使用するか、外部シークレット マネージャー (Sealed Secrets など) をデプロイ パイプラインに統合します。 これにより、手動による介入が最小限に抑え、一貫したローテーション スケジュールが保証されます。

侵害された資格情報に対応する

資格情報が侵害されたと思われる場合は、すぐに次の手順に従ってインシデントを封じ込め、未承認のアクセスを防ぎます。

  1. Microsoft Entra ID で侵害された資格情報を取り消す - アプリケーション登録から資格情報を削除して、すぐに使用をブロックします。
  2. 新しい資格情報を生成する - Microsoft Entra ID で新しいクライアント シークレットまたは証明書を作成し、侵害された資格情報を置き換えます。
  3. シークレット管理システムを更新 する - 適切なアクセス制御を使用して、Kubernetes シークレットまたは Azure Key Vault に新しい資格情報を格納します。
  4. SDK コンテナーを再デプロイ する - 新しい資格情報を使用するようにデプロイを更新し、実行中のすべてのインスタンスが変更を確実に取得できるようにします。
  5. アクセス ログを確認 する - Azure Monitor と Kubernetes の監査ログで、侵害期間中の未承認のトークン要求または疑わしいアクティビティの兆候を確認します。
  6. インシデントを文書化する - インシデントの詳細 (検出されたとき、発生した方法、アクセスされた内容) を記録し、組織のインシデント対応手順に従って繰り返しを防ぎます。

こちらもご覧ください