OpenID Connect (OIDC)検出を使用したOCI以外のリソースへのアクセスに対するポッドの認可

OpenID Connect (OIDC) Discoveryを使用して、Container Engine for Kubernetes (OKE)で作成したクラスタで実行されているアプリケーション・ポッドを認証し、ポッドが外部クラウド・プロバイダのサービスAPIを呼び出すことができるようにする方法をご覧ください。

Kubernetes Engineで作成したKubernetesクラスタで実行されているアプリケーション・ポッドは、外部クラウド・プロバイダ(GCP、AWS、Azureなど)でホストされているクラウド・サービスAPIと通信できます。外部クラウド・プロバイダによってホストされるリソースのセキュリティを確保するには、クラスタで実行されているアプリケーションがアイデンティティを認証および管理する必要があります。ただし、資格証明を直接管理することはアプリケーションにとって面倒なプロセスであり、キー・ローテーションはかなりのオーバーヘッドを伴う手動プロセスです。

OpenID Connect(OIDC)は、このような統合をより簡単にするための業界標準です。OpenID Connectは、OAuth 2.0上に構築されたアイデンティティ・レイヤーです。OpenID Connectでは、OpenIDプロバイダ構成ドキュメント(「検出ドキュメント」と呼ばれる)を使用してアプリケーションを認証する検出プロトコル(「OIDC検出」と呼ばれることが多い)がサポートされています。

Kubernetes EngineはOIDC Discoveryをサポートしているため、ハード・コードを必要とせずに他のクラウド・サービスと対話するアプリケーションを構築し、API認証キーを手動でローテーションできます。オプションで、Kubernetesエンジンで拡張クラスタを作成または更新するときにOIDC検出を有効にできます。

概要レベルでは、クラスタに対してOIDC検出を有効にすると、アプリケーションのサービス・アカウント・トークンが認証され、(有効な場合)アクセス・トークンと交換されます。その後、アクセス・トークンを使用して、外部クラウド・プロバイダのAPIでアプリケーションを認証します。

詳細は、Kubernetesドキュメントのサービス・アカウント発行者の検出を参照してください。

OIDC検出の詳細

Kubernetesは、クラスタで実行されているすべてのアプリケーション・ポッドにサービス・アカウントを提供し、サービス・アカウントごとにサービス・アカウント・トークンを作成します。Kubernetesは、サービス・アカウント・トークンのライフサイクルを管理します。サービス・アカウント・トークンは、アプリケーションがAPIリクエストにアタッチするベアラー・トークンであり、JSON Webトークン(JWT)として構造化されます。

クラスタのOIDC検出を有効にすると、KubernetesエンジンはOIDC発行者を公開し、OIDC発行者のURLをサービス・アカウント・トークンにissクレームの値として追加します。

OIDC検出ドキュメントの場所は、OIDC発行者のURLを基準としており、パブリックにアクセスでき、認証されていない既知のエンドポイントです。OIDC検出ドキュメントには、サービス・アカウント・トークンを検証するための公開キーを含むJSON Webキー・セット(JWKS)のパブリックにアクセス可能で未認証の場所が含まれます。外部クラウド・プロバイダのアイデンティティ・プロバイダは、OIDC検出ドキュメントを使用してJWKSを検索し、JWKSを使用してサービス・アカウント・トークンを検証します。

セキュリティを強化するために、アプリケーション・ポッドによってコールされるクラウド・サービスAPIでは、Kubernetesが作成するサービス・アカウント・トークンに特定のオーディエンスが存在することが必要な場合があります。クラウド・サービスAPIに特定のオーディエンスが必要な場合は、ポッド・マニフェストで予測ボリュームのaudienceプロパティを設定することで、そのオーディエンスを指定できます。指定したオーディエンスは、サービス・アカウント・トークンにaudクレームの値として含まれ、外部クラウド・プロバイダによって検証できます。また、ポッド・マニフェストで予測されるボリュームのexpirationSecondsプロパティの値を設定することで、サービス・アカウント・トークンの有効期間を指定することもできます。詳細は、KubernetesドキュメントのServiceAccountトークン・ボリューム・プロジェクションを参照してください。

外部クラウド・プロバイダのアイデンティティ・プロバイダがJWKSを使用してサービス・アカウント・トークンを正常に検証した場合、アイデンティティ・プロバイダはサービス・アカウント・トークンをアクセス・トークンと交換します。その後、アクセス・トークンを使用してアプリケーションを認証し、アプリケーションが外部クラウド・プロバイダでAPIを使用するように認可します。

OIDC検出トークン交換プロセス

アプリケーション・ポッドが外部APIにリクエストを実行できるように、クラスタのOIDC検出を有効にすると、Kubernetesエンジンによって次のものが公開されます:
  • OIDC発行者。OIDC発行者は、公開されている信頼できるTLS/SSL証明書でHTTPSを介して公開されます。
  • サービス・アカウント・トークンの検証に使用される公開キーを含むJSON Webキー・セット(JWKS)。JWKSは、オブジェクト・ストレージ・サービスのパブリックにアクセス可能で未認証のバケットに格納されます。「JWKSの例」を参照してください。
  • JWKSの場所を含むOIDC検出ドキュメント(JSON形式)。検出ドキュメントは、オブジェクト・ストレージ・サービスのパブリックにアクセス可能で未認証のバケットに格納されます。検出ドキュメントの例を参照してください。

外部APIにリクエストを送信するアプリケーション・ポッドを定義する際に、外部クラウド・プロバイダのアイデンティティ・プロバイダがサービス・アカウント・トークン内の特定のオーディエンスを想定している場合は、ポッド・マニフェストで予測されるserviceAccountTokenを指定し、それに応じてaudienceプロパティを設定します。ポッド・マニフェストの例を参照してください。

次に、トークン交換プロセスの概要を示します。

  1. クラスタでアプリケーション・ポッドを作成すると、Kubernetesによってポッドにサービス・アカウント・トークンが付与されます。サービス・アカウント・トークンには、KubernetesエンジンOIDC発行者のURLがJWTのissクレームの値として含まれます。ポッド・マニフェストでオーディエンスを指定した場合、オーディエンスはaudクレームの値としてJWTに含まれます。サービス・アカウント・トークンの例を参照してください。

  2. アプリケーション・ポッドは、外部クラウド・プロバイダのAPIにリクエストを作成し、エンコードされたサービス・アカウント・トークンをAPIリクエストのAuthorizationヘッダーの外部クラウド・プロバイダに表示します。
  3. 外部クラウド・プロバイダのアイデンティティ・プロバイダは、サービス・アカウント・トークンをデコードし、KubernetesエンジンOIDC発行者のURLをissクレームから抽出し、/.well-known/openid-configurationをOIDC検出ドキュメントの場所としてURLに追加し、そのURLにリクエストを送信して検出ドキュメントを取得します。
  4. KubernetesエンジンOIDC発行者はOIDC検出ドキュメントを返します。このドキュメントには、jwks_uriフィールドにJWKSの場所のURLが含まれます。検出ドキュメントの例を参照してください。
  5. 外部クラウド・プロバイダのアイデンティティ・プロバイダは、OIDC検出ドキュメントからURLを抽出し、そのURLにリクエストを送信してJWKSを取得します。「JWKSの例」を参照してください。
  6. 外部クラウド・プロバイダのアイデンティティ・プロバイダは、JWKSを使用して、アプリケーション・ポッドによって最初に提示されたサービス・アカウント・トークンを検証します。
  7. サービス・アカウント・トークンが有効であるとすると、外部クラウド・プロバイダのアイデンティティ・プロバイダはアプリケーション・ポッドにアクセス・トークンを返します。
  8. アプリケーション・ポッドは、アイデンティティを証明するために外部クラウド・プロバイダのAPIにアクセス・トークンを提示し、APIリクエストを正常に行います。

次の図に、トークン交換プロセスを示します:

この図は、前後のテキストで説明されているトークン交換プロセスを示しています。

OIDC検出に関するノート

OIDC検出の使用時には、次の点に注意してください。

  • OIDC検出は、Kubernetesバージョン1.21以上を実行しているクラスタでサポートされています。
  • OIDC検出は、VCNネイティブ・クラスタ(独自のVCNのサブネット内のKubernetes APIエンドポイントを持つクラスタ)でのみサポートされます。VCNネイティブ・クラスタへの移行を参照してください。
  • OIDC検出は、管理対象ノード、仮想ノードおよび自己管理ノードでサポートされています。
  • OIDC検出は、拡張クラスタでサポートされています(基本クラスタではサポートされません)。

OIDC検出のポッド・マニフェスト、サービス・アカウント・トークン、検出ドキュメントおよびJWKSの例

Podマニフェストの例

クラウドサービスAPIを呼び出すアプリケーションポッドのマニフェストの例。この例では、外部クラウド・プロバイダのアイデンティティ・プロバイダは、サービス・アカウント・トークンがvaultという名前のオーディエンスを指定することを想定しています。

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - image: nginx
    name: nginx
    volumeMounts:
    - mountPath: /var/run/secrets/tokens
      name: vault-token
  serviceAccountName: build-robot
  volumes:
  - name: vault-token
    projected:
      sources:
      - serviceAccountToken:
          path: vault-token
          expirationSeconds: 7200
          audience: vault

サービス・アカウント・トークンの例

ポッド・マニフェストの例で、Kubernetesがポッドに対して作成するサービス・アカウント・トークンの例:

{
  "aud": [
    "vault"
  ],
  "exp": 1731613413,
  "iat": 1700077413,
  "iss": "https://objectstorage.us-ashburn-1.oci.customer-oci.com/n/okecustprod/b/oidc/o/{discoveryUUID}",
  "kubernetes.io": {
    "namespace": "kube-system",
    "node": {
      "name": "127.0.0.1",
      "uid": "58456cb0-dd00-45ed-b797-5578fdceaced"
    },
    "pod": {
      "name": "build-robot-69cbfb9798-jv9gn",
      "uid": "778a530c-b3f4-47c0-9cd5-ab018fb64f33"
    },
    "serviceaccount": {
      "name": "build-robot",
      "uid": "a087d5a0-e1dd-43ec-93ac-f13d89cd13af"
    },
    "warnafter": 1700081020
  },
  "nbf": 1700077413,
  "sub": "system:serviceaccount:kube-system:build-robot"
}

検出ドキュメントの例

jwks_uriフィールドで指定されたJWKSの場所など、Kubernetesエンジンが発行する可能性のある検出ドキュメントの例:

{
    "issuer": "https://objectstorage.us-ashburn-1.oci.customer-oci.com/n/okecustprod/b/oidc/o/{discoveryUUID}",
    "jwks_uri": "https://objectstorage.us-ashburn-1.oci.customer-oci.com/n/okecustprod/b/oidc/o/{discoveryUUID}/jwks",
    "response_types_supported": [
        "id_token"
    ],
    "subject_types_supported": [
        "public"
    ],
    "id_token_signing_alg_values_supported": [
        "RS256"
    ]
}

JWKSの例

サービス・アカウント・トークンを認証するJWKSの例:

{
"keys": [
    {
        "kty": "RSA",
        "kid": "42148Kf",
        "use": "sig",
        "alg": "RS256",
        "n": "iGaLqP6y-SJCCBq5Hv6pGDbG_SQ______asdf3sC",
        "e": "AQAB"
    },
    {
        "kty": "RSA",
        "kid": "bEaunmA",
        "use": "sig",
        "alg": "RS256",
        "n": "BISvILNyn-lUu4goZSXBD9ackM9______RpUlq2w",
        "e": "AQAB"
    }
]
}

OIDC検出のためのクラスタの有効化

Kubernetesエンジンで作成したクラスタで実行されているアプリケーション・ポッドが、外部クラウド・プロバイダでホストされているAPIにアクセスするときにOIDC Discoveryを使用して認証できるようにするには、クラスタの「OIDC検出の有効化」プロパティを設定する必要があります。

コンソールを使用したOIDC検出のためのクラスタの有効化

OIDC検出に対応した新規クラスタの作成

クラスタを作成し、クラスタで実行されているアプリケーション・ポッドが、外部クラウド・プロバイダでホストされているAPIにアクセスするときにOIDC Discoveryを使用して認証されるようにするには:

  1. 「カスタム作成」ワークフローを使用してクラスタを作成する手順に従います。コンソールを使用した、カスタム作成ワークフローでの明示的に定義された設定によるクラスタの作成を参照してください。
  2. 「クラスタの作成」ページで、新しいクラスタのデフォルトの構成の詳細のみを受け入れるか、次のように他の方法を指定します:

    • 名前: 新しいクラスタの名前。デフォルトの名前をそのまま使用するか、名前を入力します。機密情報の入力は避けてください。
    • コンパートメント: 新規クラスタを作成するコンパートメント。
    • Kubernetesバージョン: クラスタのコントロール・プレーン・ノードで実行するKubernetesのバージョン。デフォルトのバージョンをそのまま使用するか、バージョンを選択します。特に、選択したKubernetesバージョンによって、作成されたクラスタで有効になるアドミッション・コントローラのデフォルト・セットが決まります(サポートされているアドミッション・コントローラを参照)。
  3. 「拡張オプションの表示」をクリックし、「OpenID Connect (OIDC)検出」パネルで「OIDC検出の有効化」オプションを選択します。

  4. コンソールを使用したカスタム作成ワークフローでの明示的に定義した設定でのクラスタの作成の説明に従って、新しいクラスタの他の構成詳細を入力します。
  5. 「クラスタの作成」をクリックして、今すぐ新しいクラスタを作成します。

OIDC検出を有効にするための既存のクラスタの編集

既存のクラスタを更新して、クラスタで実行されているアプリケーション・ポッドが、外部クラウド・プロバイダでホストされているAPIにアクセスするときにOIDC Discoveryを使用して認証できるようにするには:

  1. コンソールを使用して既存のクラスタを更新する手順に従います。クラスタの更新を参照してください。
  2. 「クラスタ詳細」ページで、「編集」をクリックします。

  3. 「クラスタの編集」ウィンドウの「OpenID Connect (OIDC)検出」パネルで、「OIDC検出の有効化」オプションを選択します。

  4. 「保存」をクリックして、変更内容を保存します。

CLIを使用したOIDC検出のクラスタの有効化

CLIの使用の詳細は、コマンド・ライン・インタフェース(CLI)を参照してください。CLIコマンドで使用できるフラグおよびオプションの完全なリストは、コマンドライン・リファレンスを参照してください。

クラスタの作成およびOIDC検出の有効化

CLIを使用して、外部クラウド・プロバイダでホストされているAPIにアクセスするときにOIDC Discoveryを使用してアプリケーション・ポッドを認証する拡張クラスタを作成するには、oci ce cluster createコマンドに--open-id-connect-discovery-enabledパラメータを含めます。

例:

oci ce cluster create \
--compartment-id ocid1.compartment.oc1..aaaaaaaa______n5q \
--name sales \
--vcn-id ocid1.vcn.oc1.phx.aaaaaaaa______lhq \
--type ENHANCED_CLUSTER \
--kubernetes-version v1.25.4 \
--service-lb-subnet-ids "[\"ocid1.subnet.oc1.phx.aaaaaaaa______g7q"]" \
--endpoint-subnet-id ocid1.subnet.oc1.phx.aaaaaaaa______sna \
--endpoint-public-ip-enabled true \
--endpoint-nsg-ids "[\"ocid1.networksecuritygroup.oc1.phx.aaaaaaaa______5qq\"]" \
--cluster-pod-network-options '[{"cniType":"OCI_VCN_IP_NATIVE"}]' \
--open-id-connect-discovery-enabled true

クラスタの編集によるOIDC検出の有効化

CLIを使用して、外部クラウド・プロバイダでホストされているAPIにアクセスするときにOIDC Discoveryを使用してアプリケーション・ポッドを認証するように拡張クラスタを更新するには、isOpenIdConnectDiscoveryEnabled属性をtrueに設定します:

  1. 適切なエディタで、選択した名前でJSONファイルを作成します(これらの手順は、ファイルがcluster-enable-oidc.jsonという名前であると想定しています)。これには、次のものが含まれます。
    {
      "options": {
        "openIdConnectDiscovery": {
          "isOpenIdConnectDiscoveryEnabled": true
        }
      }
    }
  2. cluster-enable-oidc.jsonファイルを保存して閉じます。
  3. 次のように入力して、クラスタを更新します。

    oci ce cluster update --cluster-id <cluster-ocid> --from-json file://<path-to-file>

    ここでは:

    • --cluster-id <cluster-ocid>は、OIDC検出を有効にするクラスタのOCIDです。
    • --from-json file://<path-to-file>は、クラスタの更新時に使用するファイルの場所を指定します。

    例:

    oci ce cluster update --cluster-id ocid1.cluster.oc1.iad.aaaaaaaaaf______jrd --from-json file://./cluster-enable-oidc.json

APIを使用したOIDC検出のためのクラスタの有効化

CreateCluster操作を実行してクラスタを作成するか、UpdateCluster操作を実行してクラスタを編集し、CreateClusterOptionsリソースまたはUpdateClusterOptionsDetailsリソースのisOpenIdConnectDiscoveryEnabled属性の値としてtrueをそれぞれ指定します。