[Yandex Cloud documentation](../../index.md) > [Yandex Managed Service for Kubernetes](../index.md) > [Tutorials](index.md) > Accessing the Yandex Cloud API from a Managed Service for Kubernetes cluster using a workload identity federation

# Accessing the Yandex Cloud API from a Managed Service for Kubernetes cluster using a workload identity federation in Identity and Access Management

Managed Service for Kubernetes supports integration with Identity and Access Management _workload identity federations_.

[Workload identity federations](../../iam/concepts/workload-identity.md) allow you to configure a link between external systems and Yandex Cloud via the [OpenID Connect](https://openid.net/developers/how-connect-works/) (OIDC) protocol. This allows external systems to perform actions with Yandex Cloud resources under IAM [service accounts](../../iam/concepts/users/service-accounts.md) without using [authorized keys](../../iam/concepts/authorization/key.md). This is a more secure method that minimizes the risk of credential leakage and the possibility of unauthorized access.

When this option is enabled, Managed Service for Kubernetes automatically creates an OIDC provider for the specific cluster and provides the following parameters for integration with workload identity federations:
* `Issuer URL`.
* `JWKS key set URL`.

![image](../../_assets/managed-kubernetes/mk8s-wlif.svg)

This tutorial exemplifies getting the value of a Yandex Lockbox [secret](../../lockbox/concepts/secret.md) from a Managed Service for Kubernetes using an Identity and Access Management [service account](../../iam/concepts/users/service-accounts.md). 

Similarly, you can perform any action via the [Yandex Cloud CLI](../../cli/quickstart.md), [Terraform](../../terraform/quickstart.md), an [SDK](../../overview/sdk/overview.md), or the [API](../../api-design-guide/index.md).

{% note info %}

This tutorial demonstrates an example of integrating a Managed Service for Kubernetes cluster with a workload identity federation. For a tutorial on integrating a custom Kubernetes installation, see [Getting the Yandex Lockbox secret value on the custom Kubernetes installation side](../../tutorials/security/wlif-k8s-integration.md).

{% endnote %}

To configure access to a Yandex Lockbox secret from a Managed Service for Kubernetes cluster via the Yandex Cloud API using a workload identity federation:

1. [Get your cloud ready](#prepare-cloud).
1. [Configure the Managed Service for Kubernetes cluster](#prepare-cluster).
1. [Create a workload identity federation](#create-wlif).
1. [Set up an IAM service account](#prepare-sa).
1. [Set up an Kubernetes service account](#prepare-sa-k8s).
1. [Link the IAM service account to the federation](#connect-sa).
1. [Create a Yandex Lockbox secret](#create-secret).
1. [Test the integration](#check-integration).

If you no longer need the resources you created, [delete them](#clear-out).

## Get your cloud ready {#prepare-cloud}

Sign up for Yandex Cloud and create a [billing account](../../billing/concepts/billing-account.md):
1. Navigate to the [management console](https://console.yandex.cloud) and log in to Yandex Cloud or create a new account.
1. On the **[Yandex Cloud Billing](https://center.yandex.cloud/billing/accounts)** page, make sure you have a billing account linked and it has the `ACTIVE` or `TRIAL_ACTIVE` [status](../../billing/concepts/billing-account-statuses.md). If you do not have a billing account, [create one](../../billing/quickstart/index.md) and [link](../../billing/operations/pin-cloud.md) a cloud to it.

If you have an active billing account, you can create or select a [folder](../../resource-manager/concepts/resources-hierarchy.md#folder) for your infrastructure on the [cloud page](https://console.yandex.cloud/cloud).

[Learn more about clouds and folders here](../../resource-manager/concepts/resources-hierarchy.md).

### Required paid resources {#paid-resources}

The infrastructure support cost includes:
* Fee for computing resources and disks for Managed Service for Kubernetes cluster [nodes](../concepts/index.md#node-group) (see [Yandex Compute Cloud pricing](../../compute/pricing.md)).
* Fee for using the Managed Service for Kubernetes [master](../concepts/index.md#master) and outgoing traffic (see [Managed Service for Kubernetes pricing](../pricing.md)).
* Fee for the Managed Service for Kubernetes cluster's [public IP addresses](../../vpc/concepts/address.md#public-addresses) (see [Yandex Virtual Private Cloud pricing](../../vpc/pricing.md)).
* Fee for storing the [secret](../../lockbox/concepts/secret.md) and requests to it (see [Yandex Lockbox pricing](../../lockbox/pricing.md)).

## Set up a Managed Service for Kubernetes cluster {#prepare-cluster}

1. If you do not have a Managed Service for Kubernetes cluster yet:
    1. [Create a cluster](../operations/kubernetes-cluster/kubernetes-cluster-create.md).

    1. [Create](../operations/node-group/node-group-create.md) a node group.
    1. [Set up](../operations/connect/security-groups.md) security groups for the cluster and node group.
1. To use the Yandex Cloud API, your cluster nodes must have internet access. Make sure your cluster nodes have public IP addresses assigned to them or the subnet they reside in has a configured [NAT gateway](../../vpc/concepts/gateways.md#nat-gateway) or [NAT instance](../../tutorials/routing/nat-instance/index.md). Also make sure the security group rules allow unrestricted outgoing traffic for your cluster nodes.
1. Set up integration with a workload identity federation for the cluster and node group:

    {% list tabs group=instructions %}

    - Management console {#console}

      1. In the [management console](https://console.yandex.cloud), select the folder with your cluster.
      1. Navigate to **Managed Service for&nbsp;Kubernetes**.
      1. Click ![image](../../_assets/console-icons/ellipsis.svg) next to the cluster and select **Edit**.
      1. Enable the workload identity federation in the **Identity and access management** field.
      1. Click **Save**.
      1. Under **Identity and access management** on the cluster overview page, copy the **Issuer URL** and **JWKS key set URL** values. You will need them to complete the integration.
      1. Navigate to the **Node group** tab.
      1. Click ![image](../../_assets/console-icons/ellipsis.svg) next to the node group and select **Edit**.
      1. Enable the workload identity federation in the **Identity and access management** field.
      1. Click **Save**.

    - CLI {#cli}

      If you do not have the Yandex Cloud CLI yet, [install and initialize it](../../cli/quickstart.md#install).

      The folder used by default is the one specified when [creating](../../cli/operations/profile/profile-create.md) the CLI profile. To change the default folder, use the `yc config set folder-id <folder_ID>` command. You can also specify a different folder for any command using `--folder-name` or `--folder-id`. If you access a resource by its name, the search will be limited to the default folder. If you access a resource by its ID, the search will be global, i.e., through all folders based on access permissions.

      1. Enable support for integration with workload identity federation in the cluster:

          ```bash
          yc managed-kubernetes cluster update \
            --id <cluster_ID> \
            --enable-workload-identity-federation
          ```

          Result:

          ```text
          done (3s)
          ...
          workload_identity_federation:
            enabled: true
            issuer: https://storage.yandexcloud.net/mk8s-oidc/v1/clusters/catc7433801j********
            jwks_uri: https://storage.yandexcloud.net/mk8s-oidc/v1/clusters/catc7433801j********/jwks.json
          ```

          Copy the `workload_identity_federation.issuer` and `workload_identity_federation.jwks_uri` values. You will need them to complete the integration.

      1. Enable support for integration with workload identity federation in the node group:

          ```bash
          yc managed-kubernetes node-group update \
            --id <node_group_ID> \
            --enable-workload-identity-federation
          ```

          Result:

          ```text
          done (12s)
          ...
          workload_identity_federation:
            enabled: true
          ```

    - Terraform {#tf}

      With [Terraform](https://www.terraform.io/), you can quickly create a cloud infrastructure in Yandex Cloud and manage it using configuration files. These files store the infrastructure description written in HashiCorp Configuration Language (HCL). If you change the configuration files, Terraform automatically detects which part of your configuration is already deployed, and what should be added or removed.
      
      Terraform is distributed under the [Business Source License](https://github.com/hashicorp/terraform/blob/main/LICENSE). The [Yandex Cloud provider for Terraform](https://github.com/yandex-cloud/terraform-provider-yandex) is distributed under the [MPL-2.0](https://www.mozilla.org/en-US/MPL/2.0/) license.
      
      For more information about the provider resources, see the guides on the [Terraform](https://www.terraform.io/docs/providers/yandex/index.html) website or [its mirror](../../terraform/index.md).

      If you do not have Terraform yet, [install it and configure the Yandex Cloud provider](../../tutorials/infrastructure-management/terraform-quickstart.md#install-terraform).
      
      
      To manage infrastructure using Terraform under a service account or user accounts (a Yandex account, a federated account, or a local user), [authenticate](../../terraform/authentication.md) using the appropriate method.

      1. Add the `workload_identity_federation` section to the cluster manifest in the Terraform configuration file:

          ```hcl
          resource "yandex_kubernetes_cluster" "my_cluster" {
          ...
            workload_identity_federation {
              enabled = true
            }
          }
          ```

      1. Add the `workload_identity_federation` section to the node group manifest in the Terraform configuration file:

          ```hcl
          resource "yandex_kubernetes_node_group" "my_node_group" {
          ...
            workload_identity_federation {
              enabled = true
            }
          }
          ```

      1. Make sure the configuration files are correct.

          1. In the command line, navigate to the directory that contains the current Terraform configuration files defining the infrastructure.
          1. Run this command:
          
             ```bash
             terraform validate
             ```
          
             Terraform will show any errors found in your configuration files.

      1. Confirm resource changes.

          1. Run this command to view the planned changes:
          
             ```bash
             terraform plan
             ```
          
             If you described the configuration correctly, the terminal will display a list of the resources to update and their parameters. This is a verification step that does not apply changes to your resources.
          
          1. If everything looks correct, apply the changes:
             1. Run this command:
          
                ```bash
                terraform apply
                ```
          
             1. Confirm updating the resources.
             1. Wait for the operation to complete.

      1. Get the issuer URL (`issuer`) and the JWKS keyset URL (`jwks_uri`) to configure the workload identity federation using the Terraform [yandex_kubernetes_cluster](../../terraform/data-sources/kubernetes_cluster.md) data source.

          You can aslo [find out](../operations/kubernetes-cluster/kubernetes-cluster-list.md#get) these parameters in the [management console](https://console.yandex.cloud), using the CLI or API.

    - API {#api}

      1. Use the [update](../managed-kubernetes/api-ref/Cluster/update.md) REST API method for the [Cluster](../managed-kubernetes/api-ref/Cluster/index.md) resource or the [ClusterService/Update](../managed-kubernetes/api-ref/grpc/Cluster/update.md) gRPC API call.

          {% note info %}
          
          Below, see parameters for the REST API request body. To specify a parameter in a gRPC API call, convert its name from [lower CamelCase](https://en.wikipedia.org/wiki/Camel_case) to [snake_case](https://en.wikipedia.org/wiki/Snake_case), e.g., `minResourcePresetId` becomes `min_resource_preset_id`.
          
          {% endnote %}

          Provide the following in the request:
          * Cluster ID in the `clusterId` parameter.
          * `updateMask` set to `workloadIdentityFederation.enabled`.

            {% note warning %}
            
            The API method will assign default values to all the parameters of the object you are modifying unless you explicitly provide them in your request. To avoid this, list the settings you want to change in the `updateMask` parameter as a single comma-separated string.
            
            {% endnote %}

          * `workloadIdentityFederation` set to `"enabled": "true"`.

          Copy the `workloadIdentityFederation.issuer` and `workloadIdentityFederation.jwksUri` values from the response. You will need them later.

      1. Use the [update](../managed-kubernetes/api-ref/NodeGroup/update.md) REST API method for the [NodeGroup](../managed-kubernetes/api-ref/NodeGroup/index.md) resource or the [NodeGroupService/Update](../managed-kubernetes/api-ref/grpc/NodeGroup/update.md) gRPC API call.

          Provide the following in the request:
          * Node group ID in the `nodeGroupId` parameter.
          * `updateMask` set to `workloadIdentityFederation.enabled`.
          * `workloadIdentityFederation` set to `"enabled": "true"`.

    {% endlist %}

## Create a workload identity federation {#create-wlif}

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), select the folder you want to access via the Yandex Cloud API.
  1. Navigate to **Identity and Access Management**.
  1. In the left-hand panel, select ![cpus](../../_assets/console-icons/cpus.svg) **Workload identity federations**.
  1. Click **Create federation**.
  1. In the **Issuer value (iss)** field, enter the **Issuer URL** value you got earlier, e.g., `https://storage.yandexcloud.net/mk8s-oidc/v1/clusters/c49i54tk66ob********`.
  1. In the **Acceptable Audience values (AUD)** field, also enter the **Issuer URL** value.
  1. In the **JWKS address** field, enter the **JWKS key set URL** value you got earlier, e.g., `https://storage.yandexcloud.net/mk8s-oidc/v1/clusters/c49i54tk66ob********/jwks.json`.
  1. In the **Name** field, enter a name for the federation, e.g., `test-iam-federation`.
  1. Click **Create**.

- CLI {#cli}

  Run this command:

  ```bash
  yc iam workload-identity oidc federation create \
    --name <federation_name> \
    --issuer "<issuer_URL>" \
    --audiences "<issuer_URL>" \
    --jwks-url "<JWKS_URL>"
  ```

  Where:
  * `--name`: Name of the new federation, e.g., `test-iam-federation`.
  * `--issuer` and `--audiences`: Issuer URL value you got earlier, e.g., `https://storage.yandexcloud.net/mk8s-oidc/v1/clusters/c49i54tk66ob********`.
  * `--jwks-url`: JWKS URL value you got earlier, e.g., `https://storage.yandexcloud.net/mk8s-oidc/v1/clusters/c49i54tk66ob********/jwks.json`.

  Result:

  ```text
  id: aje2c4qv19lf********
  name: test-iam-federation
  folder_id: b1gfq9pe6rd2********
  enabled: true
  audiences:
    - https://storage.yandexcloud.net/mk8s-oidc/v1/clusters/c49i54tk66ob********
  issuer: https://storage.yandexcloud.net/mk8s-oidc/v1/clusters/c49i54tk66ob********
  jwks_url: https://storage.yandexcloud.net/mk8s-oidc/v1/clusters/c49i54tk66ob********/jwks.json
  created_at: "2024-12-28T16:04:31.530652473Z"
  ```

  Save the federation ID for later use.

- Terraform {#tf}

  1. In the Terraform configuration file, define the parameters of the federation you want to create:

      ```hcl
      resource "yandex_iam_workload_identity_oidc_federation" "wlif" {
        name        = "<federation_name>"
        folder_id   = "<folder_ID>"
        issuer      = "<issuer_URL>"
        audiences   = ["<issuer_URL>"]
        jwks_url    = "<JWKS_URL>"
      }
      ```

      Where:
      * `name`: Name of the new federation, e.g., `test-iam-federation`.
      * `folder_id`: [ID of the folder](../../resource-manager/operations/folder/get-id.md) you are creating the workload identity federation in.
      * `issuer` and `audiences`: Issuer URL value you got earlier, e.g., `https://storage.yandexcloud.net/mk8s-oidc/v1/clusters/c49i54tk66ob********`.
      * `jwks_url`: JWKS URL value you got earlier, e.g., `https://storage.yandexcloud.net/mk8s-oidc/v1/clusters/c49i54tk66ob********/jwks.json`.

  1. Make sure the configuration files are correct.

      1. In the command line, navigate to the directory that contains the current Terraform configuration files defining the infrastructure.
      1. Run this command:
      
         ```bash
         terraform validate
         ```
      
         Terraform will show any errors found in your configuration files.

  1. Confirm creating the resources.

      1. Run this command to view the planned changes:
      
         ```bash
         terraform plan
         ```
      
         If you described the configuration correctly, the terminal will display a list of the resources to update and their parameters. This is a verification step that does not apply changes to your resources.
      
      1. If everything looks correct, apply the changes:
         1. Run this command:
      
            ```bash
            terraform apply
            ```
      
         1. Confirm updating the resources.
         1. Wait for the operation to complete.

      Save the federation ID for later use.

- API {#api}

  To create a workload identity federation, use the [create](../../iam/workload/oidc/workload-identity/api-ref/Federation/create.md) REST API method for the [Federation](../../iam/workload/oidc/workload-identity/api-ref/Federation/index.md) resource or the [FederationService/Create](../../iam/workload/oidc/workload-identity/api-ref/grpc/Federation/create.md) gRPC API call.

{% endlist %}

{% endlist %}

## Set up an IAM service account {#prepare-sa}

1. Create a service account named IAM:

    {% list tabs group=instructions %}

    - Management console {#console}

      1. In the [management console](https://console.yandex.cloud), select the folder with the Yandex Lockbox secret.
      1. Navigate to **Identity and Access Management**.
      1. Click **Create service account**.
      1. Enter a name for the service account, e.g., `sa-lockbox`.
      1. Click **Create**.
      1. Select the service account you created and save its ID, as you will need it later.

    - CLI {#cli}

      Run this command:

      ```bash
      yc iam service-account create --name sa-lockbox
      ```

      Result:

      ```text
      done (2s)
      id: aje7s96nvmdp********
      folder_id: b1gsm0k26v1l********
      created_at: "2026-03-12T12:16:01Z"
      name: sa-lockbox
      ```

      Save the IAM service account ID for later use.

    - Terraform {#tf}

      1. In the configuration file, specify the properties of the resources you want to create:
    
          ```hcl
          resource "yandex_iam_service_account" "sa" {
            name        = "<service_account_name>"
            folder_id   = "<folder_ID>"
          }
          ```

          Where:
          * `name`: Service account name, e.g., `sa-lockbox`.
          * `folder_id`: [Folder ID](../../resource-manager/operations/folder/get-id.md).
    
      1. Make sure the configuration files are correct.

          1. In the command line, navigate to the directory that contains the current Terraform configuration files defining the infrastructure.
          1. Run this command:
          
             ```bash
             terraform validate
             ```
          
             Terraform will show any errors found in your configuration files.

      1. Confirm creating the resources.

          1. Run this command to view the planned changes:
          
             ```bash
             terraform plan
             ```
          
             If you described the configuration correctly, the terminal will display a list of the resources to update and their parameters. This is a verification step that does not apply changes to your resources.
          
          1. If everything looks correct, apply the changes:
             1. Run this command:
          
                ```bash
                terraform apply
                ```
          
             1. Confirm updating the resources.
             1. Wait for the operation to complete.

          Save the IAM service account ID for later use.

    - API {#api}

      Use the [create](../../iam/api-ref/ServiceAccount/create.md) REST API method for the [ServiceAccount](../../iam/api-ref/ServiceAccount/index.md) resource or the [ServiceAccountService/Create](../../iam/api-ref/grpc/ServiceAccount/create.md) gRPC API call.

    {% endlist %}

1. Assign the `lockbox.payloadViewer` [role](../../iam/concepts/access-control/roles.md) for the folder to the service account: 

    {% list tabs group=instructions %}

    - Management console {#console}

      1. In the [management console](https://console.yandex.cloud), select the folder where you created the service account.
      1. Navigate to the **Access bindings** tab.
      1. Click **Configure access**.
      1. In the window that opens, select **Service accounts**.
      1. Select the service account you created earlier.
      1. Click ![image](../../_assets/console-icons/plus.svg) **Add role** and select the `lockbox.payloadViewer` [role](../../lockbox/security/index.md#lockbox-payloadViewer).
      1. Click **Save**.

    - CLI {#cli}

      Run this command by specifying the folder and service account IDs:

      ```bash
      yc resource-manager folder add-access-binding <folder_ID> \
        --role lockbox.payloadViewer \
        --subject serviceAccount:<service_account_ID>
      ```

    - Terraform {#tf}

      1. In the configuration file, describe the resources you want to create:

          ```hcl
          resource "yandex_resourcemanager_folder_iam_member" "lockbox" {
            folder_id   = "<folder_ID>"
            role        = "lockbox.payloadViewer"
            member      = "serviceAccount:<service_account_ID>"
          }
          ```

          Where:
          * `folder_id`: [Folder ID](../../resource-manager/operations/folder/get-id.md).
          * `role`: Role being assigned, e.g., `lockbox.payloadViewer`.
          * `member`: [ID of the service account](../../iam/operations/sa/get-id.md) you are assigning the role to. Use this format: `serviceAccount:<service_account_ID>`.

      1. Make sure the configuration files are correct.

          1. In the command line, navigate to the directory that contains the current Terraform configuration files defining the infrastructure.
          1. Run this command:
          
             ```bash
             terraform validate
             ```
          
             Terraform will show any errors found in your configuration files.

      1. Confirm creating the resources.

          1. Run this command to view the planned changes:
          
             ```bash
             terraform plan
             ```
          
             If you described the configuration correctly, the terminal will display a list of the resources to update and their parameters. This is a verification step that does not apply changes to your resources.
          
          1. If everything looks correct, apply the changes:
             1. Run this command:
          
                ```bash
                terraform apply
                ```
          
             1. Confirm updating the resources.
             1. Wait for the operation to complete.

    - API {#api}

      Use the [UpdateAccessBindings](../../resource-manager/api-ref/Folder/updateAccessBindings.md) REST API method for the [Folder](../../resource-manager/api-ref/Folder/index.md) resource or the [FolderService/UpdateAccessBindings](../../resource-manager/api-ref/grpc/Folder/updateAccessBindings.md) gRPC API call.

    {% endlist %}

## Set up an Kubernetes service account {#prepare-sa-k8s}

1. [Connect](../operations/connect/index.md#kubectl-connect) to the Managed Service for Kubernetes cluster using `kubectl`.
1. Create a manifest named `service-account.yaml` for the Kubernetes service account with the following contents:

    ```yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: wlif
      annotations:
        yandex.cloud/federated-yc-service-account-id: <IAM_service_account_ID>
    ```

1. Apply the manifest:

    ```bash
    kubectl apply -f service-account.yaml
    ```

1. To check the `ServiceAccount` resource you created, run this command:

    ```bash
    kubectl describe serviceaccount wlif
    ```

    Result:

    ```text
    Name:                wlif
    Namespace:           default
    ...
    ```

1. Save the values of the `Name` and `Namespace` fields, as you will need them later.

## Link the IAM service account to the federation {#connect-sa}

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), select the folder the service account was created in.
  1. Navigate to **Identity and Access Management**.
  1. In the list of service accounts, select `sa-lockbox`.
  1. In the top panel, click ![image](../../_assets/console-icons/cpus.svg) **Link to federation**.
  1. In the **Workload identity federation** field, select the federation you created earlier.
  1. In the **Subject value (sub)** field, specify the ID of the previously created Kubernetes service account in `system:serviceaccount:<namespace>:<Kubernetes_service_account_name>` format, where:
      * `namespace`: Kubernetes service account's `Namespace` field value, e.g., `default`.
      * `account_name`: Kubernetes service account's `Name` field value, e.g., `wlif`.

  1. Click **Link**.

- CLI {#cli}

  Run this command:

  ```bash
  yc iam workload-identity federated-credential create \
    --service-account-id <IAM_service_account_ID> \
    --federation-id <federation_ID> \
    --external-subject-id "system:serviceaccount:<namespace>:<Kubernetes_service_account_name>"
  ```

  Where:
  * `--service-account-id`: IAM service account ID you got earlier.
  * `--federation-id`: Workload identity federation ID you got earlier.
  * `--external-subject-id`: External subject ID, where:
    * `namespace`: Kubernetes service account's `Namespace` field value, e.g., `default`.
    * `Kubernetes_service_account_name`: Kubernetes service account's `Name` field value, e.g., `wlif`.

  Result:

  ```text
  id: aje401v1sup8********
  service_account_id: ajek7v5j65cg********
  federation_id: aje2c4qv19lf********
  external_subject_id: system:serviceaccount:default:wlif
  created_at: "2024-12-28T16:33:47.057632267Z"
  ```

- Terraform {#tf}

  1. In the Terraform configuration file, define the parameters of the federated credentials you want to create:

      ```hcl
      resource "yandex_iam_workload_identity_federated_credential" "fc" {
        service_account_id  = "<service_account_ID>"
        federation_id       = "<federation_ID>"
        external_subject_id = "system:serviceaccount:<namespace>:<Kubernetes_service_account_name>"
      }
      ```

      Where:
      * `service_account_id`: IAM service account ID you got earlier.
      * `federation_id`: Workload identity federation ID you got earlier.
      * `external-subject-id`: External subject ID, where:
        * `namespace`: Kubernetes service account's `Namespace` field value, e.g., `default`.
        * `external_subject_id_service_account_name`: Kubernetes service account's `Name` field value, e.g., `wlif`.

  1. Make sure the configuration files are correct.

      1. In the command line, navigate to the directory that contains the current Terraform configuration files defining the infrastructure.
      1. Run this command:
      
         ```bash
         terraform validate
         ```
      
         Terraform will show any errors found in your configuration files.

  1. Confirm creating the resources.

      1. Run this command to view the planned changes:
      
         ```bash
         terraform plan
         ```
      
         If you described the configuration correctly, the terminal will display a list of the resources to update and their parameters. This is a verification step that does not apply changes to your resources.
      
      1. If everything looks correct, apply the changes:
         1. Run this command:
      
            ```bash
            terraform apply
            ```
      
         1. Confirm updating the resources.
         1. Wait for the operation to complete.

- API {#api}

  To create federated credentials, use the [create](../../iam/workload/workload-identity/api-ref/FederatedCredential/create.md) REST API method for the [FederatedCredential](../../iam/workload/workload-identity/api-ref/FederatedCredential/index.md) resource or the [FederatedCredentialService/Create](../../iam/workload/workload-identity/api-ref/grpc/FederatedCredential/create.md) gRPC API call.

{% endlist %}

## Create a Yandex Lockbox secret {#create-secret}

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), select the folder where you want to create your secret.
  1. Navigate to **Lockbox**.
  1. Click **Create secret**.
  1. In the **Name** field, enter a name for the secret: `MY_SECRET`.
  1. Select **Secret type** `Custom`.
  1. In the **Key** field, enter a non-secret ID, e.g., `test-secret`.
  1. In the **Value** field, enter the confidential data you want to store, e.g., `hello-world`.
  1. Click **Create**.
  1. Save the ID of the secret. You will need it later.

- CLI {#cli}

  Run this command:

  ```bash
  yc lockbox secret create \
    --name <secret_name> \
    --payload "<array_with_secret_contents>" \
  ```

  Where:
  * `--name`: Secret name, e.g., `MY_SECRET`.
  * `--payload`: Secret contents as a YAML or JSON array, e.g., `"[{'key': 'test-secret', 'text_value': 'hello-world'}]"`.

  Result:
  
  ```text
  done (1s)
  id: e6qduvprvcon********
  folder_id: b1gsm0k26v1l********
  created_at: "2026-03-12T13:02:15.543Z"
  name: MY_SECRET
  status: ACTIVE
  current_version:
    id: e6qr13mvsl8t********
    secret_id: e6qduvprvcon********
    created_at: "2026-03-12T13:02:15.543Z"
    status: ACTIVE
    payload_entry_keys:
      - test-secret
  ```

- Terraform {#tf}

  1. In the configuration file, specify the secret properties:

     ```hcl
     resource "yandex_lockbox_secret" "my_secret" {
       name = "<secret_name>"
     }
     ```

     Where `name` is the secret's name, e.g., `MY_SECRET`.


  1. Check the secret's configuration for validity.

      1. In the command line, navigate to the directory that contains the current Terraform configuration files defining the infrastructure.
      1. Run this command:
      
         ```bash
         terraform validate
         ```
      
         Terraform will show any errors found in your configuration files.

  1. Confirm creating the secret.

      1. Run this command to view the planned changes:
      
         ```bash
         terraform plan
         ```
      
         If you described the configuration correctly, the terminal will display a list of the resources to update and their parameters. This is a verification step that does not apply changes to your resources.
      
      1. If everything looks correct, apply the changes:
         1. Run this command:
      
            ```bash
            terraform apply
            ```
      
         1. Confirm updating the resources.
         1. Wait for the operation to complete.

      Save the ID of the secret. You will need it later.

  1. Describe the secret's content properties in the configuration file:

      ```hcl
      resource "yandex_lockbox_secret_version_hashed" "my_version" {
        secret_id    = "<secret_ID>"
        key_1        = "<secret_1_key>"
        text_value_1 = "<secret_1_value>"

      }
      ```

      Where:

      * `secret_id`: ID of the secret you are creating a version for.
      * `key_1`: Secret key. A non-secret name for the value by which you will identify it, such as `test-secret`.
      * `text_value_1`: Secret data in plain text, e.g., `hello-world`.

  1. Check the secret's content configuration for validity.

      1. In the command line, navigate to the directory that contains the current Terraform configuration files defining the infrastructure.
      1. Run this command:
      
         ```bash
         terraform validate
         ```
      
         Terraform will show any errors found in your configuration files.

  1. Confirm creating the secret's content.

      1. Run this command to view the planned changes:
      
         ```bash
         terraform plan
         ```
      
         If you described the configuration correctly, the terminal will display a list of the resources to update and their parameters. This is a verification step that does not apply changes to your resources.
      
      1. If everything looks correct, apply the changes:
         1. Run this command:
      
            ```bash
            terraform apply
            ```
      
         1. Confirm updating the resources.
         1. Wait for the operation to complete.

- API {#api}

  To create a secret, use the [create](../../lockbox/api-ref/Secret/create.md) REST API method for the [Secret](../../lockbox/api-ref/Secret/index.md) resource or the [SecretService/Create](../../lockbox/api-ref/grpc/Secret/create.md) gRPC API call.

{% endlist %}

## Test the integration {#check-integration}

1. [Connect](../operations/connect/index.md#kubectl-connect) to the Managed Service for Kubernetes cluster using `kubectl`.
1. Create a test pod manifest named `pod.yaml` with the following contents:

    ```yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: test-wlif
    spec:
      containers:
        - image: nginx
          name: nginx
      serviceAccountName: wlif
    ```

    Where `spec:serviceAccountName` is the name of the Kubernetes service account you created earlier.

1. Apply the manifest:

    ```bash
    kubectl apply -f pod.yaml
    ```

1. Make sure the status of the new pod switched to `Running`:

    ```bash
    kubectl get pod test-wlif
    ```

    Result:

    ```
    NAME        READY   STATUS    RESTARTS   AGE
    test-wlif   1/1     Running   0          1m
    ```

1. Access the container:

    ```bash
    kubectl exec test-wlif -it -- bash
    ```

1. Install `jq`:

    ```bash
    apt-get update >/dev/null 2>&1 && apt-get install -y jq >/dev/null 2>&1
    ```

1. Get an [IAM token](../../iam/concepts/authorization/iam-token.md):

    ```bash
    IAMTOKEN=$(curl -s -H 'Metadata-Flavor: Google' \
      http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token \
      | jq -r '.access_token')
    ```

1. Get the Yandex Lockbox secret:

    ```bash
    curl -sH "Authorization: Bearer ${IAMTOKEN}" \
      "https://payload.lockbox.api.cloud.yandex.net/lockbox/v1/secrets/<secret_ID>/payload"
    ```

    Result:

    ```json
    {
     "entries": [
      {
       "key": "test-secret",
       "textValue": "hello-world"
      }
     ],
     "versionId": "e6qsqiadrsnh********"
    }
    ```

### Manual exchange of a Kubernetes service account token for an IAM token {#manual-token-exchange}

1. [Connect](../operations/connect/index.md#kubectl-connect) to the Managed Service for Kubernetes cluster using `kubectl`.
1. Create a test pod manifest named `pod.yaml` with the following contents:

    ```yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: test-wlif
    spec:
      containers:
        - image: nginx
          name: nginx
          volumeMounts:
            - mountPath: /var/run/secrets/tokens
              name: sa-token
      serviceAccountName: wlif
      volumes:
        - name: sa-token
          projected:
            sources:
              - serviceAccountToken:
                  path: sa-token
                  expirationSeconds: 7200
                  audience: https://storage.yandexcloud.net/mk8s-oidc/v1/clusters/c49i54tk66ob********
    ```

    Where:
    * `spec:serviceAccountName`: Name of the Kubernetes service account you created earlier.
    * `spec:volumes:projected:sources:serviceAccountToken:audience`: **Acceptable Audience values (AUD)** value set when creating the federation.

1. Apply the manifest:

    ```bash
    kubectl apply -f pod.yaml
    ```

1. Make sure the status of the new pod switched to `Running`:

    ```bash
    kubectl get pod test-wlif
    ```

    Result:

    ```
    NAME        READY   STATUS    RESTARTS   AGE
    test-wlif   1/1     Running   0          1m
    ```

1. Access the container:

    ```bash
    kubectl exec test-wlif -it -- bash
    ```

1. Set the required variables:

    ```bash
    SA_ID="<IAM_service_account_ID>" && \
    SECRET_ID="<Lockbox_secret_ID>" && \
    SA_TOKEN="$(cat /var/run/secrets/tokens/sa-token)"
    ```

    Where:
    * `SA_ID`: IAM service account ID you got earlier.
    * `SECRET_ID`: Yandex Lockbox secret ID you got earlier.
    * `SA_TOKEN`: Kubernetes service account token.

1. Install `jq`:

    ```bash
    apt-get update >/dev/null 2>&1 && apt-get install -y jq >/dev/null 2>&1
    ```

1. Get an [IAM token](../../iam/concepts/authorization/iam-token.md):

    ```bash
    IAMTOKEN=$(curl -sH "Content-Type: application/x-www-form-urlencoded" \
      -d "grant_type=urn:ietf:params:oauth:grant-type:token-exchange&requested_token_type=urn:ietf:params:oauth:token-type:access_token&audience=${SA_ID}&subject_token=${SA_TOKEN}&subject_token_type=urn:ietf:params:oauth:token-type:id_token" \
      -X POST https://auth.yandex.cloud/oauth/token | jq -r '.access_token')
    ```

1. Get the Yandex Lockbox secret:

    ```bash
    curl -sH "Authorization: Bearer ${IAMTOKEN}" \
      "https://payload.lockbox.api.cloud.yandex.net/lockbox/v1/secrets/${SECRET_ID}/payload"
    ```

    Result:

    ```json
    {
     "entries": [
      {
       "key": "test-secret",
       "textValue": "hello-world"
      }
     ],
     "versionId": "e6qsqiadrsnh********"
    }
    ```

## How to delete the resources you created {#clear-out}

To stop paying for the resources you created:
* [Delete](../../lockbox/operations/secret-delete.md) the Yandex Lockbox secret.
* [Delete](../operations/node-group/node-group-delete.md) the Managed Service for Kubernetes node group.
* [Delete](../operations/kubernetes-cluster/kubernetes-cluster-delete.md) the Managed Service for Kubernetes cluster.

### Useful links {#see-also}

* [Workload identity federations](../../iam/concepts/workload-identity.md)
* [Getting the Yandex Lockbox secret value on the custom Kubernetes installation side](../../tutorials/security/wlif-k8s-integration.md)