A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://developer.hashicorp.com/vault/docs/auth/kubernetes below:

Kubernetes - Auth Methods | Vault

Note

This engine can use external X.509 certificates as part of TLS or signature validation. Verifying signatures against X.509 certificates that use SHA-1 is deprecated and is no longer usable without a workaround starting in Vault 1.12. Refer to the deprecation notices for more information.

The kubernetes auth method can be used to authenticate with Vault using a Kubernetes Service Account Token. This method of authentication makes it easy to introduce a Vault token into a Kubernetes Pod.

You can also use a Kubernetes Service Account Token to log in via JWT auth. See the section on How to work with short-lived Kubernetes tokens for a summary of why you might want to use JWT auth instead and how it compares to Kubernetes auth.

Note: If you are upgrading to Kubernetes v1.21+, ensure the config option disable_iss_validation is set to true. Assuming the default mount path, you can check with vault read -field disable_iss_validation auth/kubernetes/config. See Kubernetes 1.21 below for more details.

Via the CLI

The default path is /kubernetes. If this auth method was enabled at a different path, specify -path=/my-path in the CLI.

$ vault write auth/kubernetes/login role=demo jwt=...
Via the API

The default endpoint is auth/kubernetes/login. If this auth method was enabled at a different path, use that value instead of kubernetes.

$ curl \
    --request POST \
    --data '{"jwt": "<your service account jwt>", "role": "demo"}' \
    http://127.0.0.1:8200/v1/auth/kubernetes/login

The response will contain a token at auth.client_token:

{
  "auth": {
    "client_token": "38fe9691-e623-7238-f618-c94d4e7bc674",
    "accessor": "78e87a38-84ed-2692-538f-ca8b9f400ab3",
    "policies": ["default"],
    "metadata": {
      "role": "demo",
      "service_account_name": "myapp",
      "service_account_namespace": "default",
      "service_account_secret_name": "myapp-token-pd21c",
      "service_account_uid": "aa9aa8ff-98d0-11e7-9bb7-0800276d99bf"
    },
    "lease_duration": 2764800,
    "renewable": true
  }
}

Auth methods must be configured in advance before users or machines can authenticate. These steps are usually completed by an operator or configuration management tool.

  1. Enable the Kubernetes auth method:

    $ vault auth enable kubernetes
    
  2. Use the /config endpoint to configure Vault to talk to Kubernetes. Use kubectl cluster-info to validate the Kubernetes host address and TCP port. For the list of available configuration options, please see the API documentation.

    $ vault write auth/kubernetes/config \
        token_reviewer_jwt="<your reviewer service account JWT>" \
        kubernetes_host=https://192.168.99.100:<your TCP port or blank for 443> \
        kubernetes_ca_cert=@ca.crt
    

    Note: The pattern Vault uses to authenticate Pods depends on sharing the JWT token over the network. Given the security model of Vault, this is allowable because Vault is part of the trusted compute base. In general, Kubernetes applications should not share this JWT with other applications, as it allows API calls to be made on behalf of the Pod and can result in unintended access being granted to 3rd parties.

  3. Create a named role:

    $ vault write auth/kubernetes/role/demo \
        bound_service_account_names=myapp \
        bound_service_account_namespaces=default \
        policies=default \
        audience=myapp \
        ttl=1h
    

    Note: audience will be a required field in Vault 1.21+. This field is used to verify the JWT token's audience claim.

    This role authorizes the "myapp" service account in the default namespace and it gives it the default policy.

    For the complete list of configuration options, please see the API documentation.

Starting in version 1.21, the Kubernetes BoundServiceAccountTokenVolume feature defaults to enabled. This changes the JWT token mounted into containers by default in two ways that are important for Kubernetes auth:

The changes to token lifetime are important when configuring the token_reviewer_jwt option. If a short-lived token is used, Kubernetes will revoke it as soon as the pod or service account are deleted, or if the expiry time passes, and Vault will no longer be able to use the TokenReview API. See How to work with short-lived Kubernetes tokens below for details on handling this change.

In response to the issuer changes, Kubernetes auth has been updated in Vault 1.9.0 to not validate the issuer by default. The Kubernetes API does the same validation when reviewing tokens, so enabling issuer validation on the Vault side is duplicated work. Without disabling Vault's issuer validation, it is not possible for a single Kubernetes auth configuration to work for default mounted pod tokens with both Kubernetes 1.20 and 1.21. Note that auth mounts created before Vault 1.9 will maintain the old default, and you will need to explicitly set disable_iss_validation=true before upgrading Kubernetes to 1.21. See Discovering the service account issuer below for guidance if you wish to enable issuer validation in Vault.

How to work with short-lived kubernetes tokens

There are a few different ways to configure auth for Kubernetes pods when default mounted pod tokens are short-lived, each with their own tradeoffs. This table summarizes the options, each of which is explained in more detail below.

Option All tokens are short-lived Can revoke tokens early Other considerations Use local token as reviewer JWT Yes Yes Requires Vault (1.9.3+) to be deployed on the Kubernetes cluster Use client JWT as reviewer JWT Yes Yes Operational overhead Use long-lived token as reviewer JWT No Yes Use JWT auth instead Yes No

Note: By default, Kubernetes currently extends the lifetime of admission injected service account tokens to a year to help smooth the transition to short-lived tokens. If you would like to disable this, set --service-account-extend-token-expiration=false for kube-apiserver or specify your own serviceAccountToken volume mount. See here for an example.

Use local service account token as the reviewer JWT

When running Vault in a Kubernetes pod the recommended option is to use the pod's local service account token. Vault will periodically re-read the file to support short-lived tokens. To use the local token and CA certificate, omit token_reviewer_jwt and kubernetes_ca_cert when configuring the auth method. Vault will attempt to load them from token and ca.crt respectively inside the default mount folder /var/run/secrets/kubernetes.io/serviceaccount/.

$ vault write auth/kubernetes/config \
    kubernetes_host=https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT

Note: Requires Vault 1.9.3+. In earlier versions the service account token and CA certificate is read once and stored in Vault storage. When the service account token expires or is revoked, Vault will no longer be able to use the TokenReview API and client authentication will fail.

You can use the trust store for CA certificates

If you leave `kubernetes_ca_cert` unset and set `disable_local_ca_jwt` to `true`, Vault uses the system's trust store for TLS certificate verification.
Use the Vault client's JWT as the reviewer JWT

When configuring Kubernetes auth, you can omit the token_reviewer_jwt, and Vault will use the Vault client's JWT as its own auth token when communicating with the Kubernetes TokenReview API. If Vault is running in Kubernetes, you also need to set disable_local_ca_jwt=true.

This means Vault does not store any JWTs and allows you to use short-lived tokens everywhere but adds some operational overhead to maintain the cluster role bindings on the set of service accounts you want to be able to authenticate with Vault. Each client of Vault would need the system:auth-delegator ClusterRole:

$ kubectl create clusterrolebinding vault-client-auth-delegator \
    --clusterrole=system:auth-delegator \
    --group=group1 \
    --serviceaccount=default:svcaccount1 \
    ...
Continue using long-lived tokens

You can create a long-lived secret using the instructions here and use that as the token_reviewer_jwt. In this example, the vault service account would need the system:auth-delegator ClusterRole:

$ kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
  name: vault-k8s-auth-secret
  annotations:
    kubernetes.io/service-account.name: vault
type: kubernetes.io/service-account-token
EOF

Using this maintains previous workflows but does not benefit from the improved security posture of short-lived tokens.

Use JWT auth

Kubernetes auth is specialized to use Kubernetes' TokenReview API. However, the JWT tokens Kubernetes generates can also be verified using Kubernetes as an OIDC provider. The JWT auth method documentation has instructions for setting up JWT auth with Kubernetes as the OIDC provider.

This solution allows you to use short-lived tokens for all clients and removes the need for a reviewer JWT. However, the client tokens cannot be revoked before their TTL expires, so it is recommended to keep the TTL short with that limitation in mind.

Discovering the service account issuer

Note: From Vault 1.9.0, disable_iss_validation and issuer are deprecated and the default for disable_iss_validation has changed to true for new Kubernetes auth mounts. The following section only applies if you have set disable_iss_validation=false or created your mount before 1.9 with the default value, but disable_iss_validation=true is the new recommended value for all versions of Vault.

Kubernetes 1.21+ clusters may require setting the service account issuer to the same value as kube-apiserver's --service-account-issuer flag. This is because the service account JWTs for these clusters may have an issuer specific to the cluster itself, instead of the old default of kubernetes/serviceaccount. If you are unable to check this value directly, you can run the following and look for the "iss" field to find the required value:

$ echo '{"apiVersion": "authentication.k8s.io/v1", "kind": "TokenRequest"}' \
  | kubectl create -f- --raw /api/v1/namespaces/default/serviceaccounts/default/token \
  | jq -r '.status.token' \
  | cut -d . -f2 \
  | base64 -d

Most clusters will also have that information available at the .well-known/openid-configuration endpoint:

$ kubectl get --raw /.well-known/openid-configuration | jq -r .issuer

This value is then used when configuring Kubernetes auth, e.g.:

$ vault write auth/kubernetes/config \
    kubernetes_host="https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT" \
    issuer="\"test-aks-cluster-dns-d6cbb78e.hcp.uksouth.azmk8s.io\""

This auth method accesses the Kubernetes TokenReview API to validate the provided JWT is still valid. Kubernetes should be running with --service-account-lookup. This is defaulted to true from Kubernetes 1.7. Otherwise deleted tokens in Kubernetes will not be properly revoked and will be able to authenticate to this auth method.

Service Accounts used in this auth method will need to have access to the TokenReview API. If Kubernetes is configured to use RBAC roles, the Service Account should be granted permissions to access this API. The following example ClusterRoleBinding could be used to grant these permissions:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: role-tokenreview-binding
  namespace: default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:auth-delegator
subjects:
  - kind: ServiceAccount
    name: vault-auth
    namespace: default

The Kubernetes Auth Plugin has a full HTTP API. Please see the API docs for more details.

Refer to the following workflow examples for Kubernetes auth method usage:

Working with templated policies

Set use_annotations_as_alias_metadata=true in your Kubernetes auth configuration to use Kubernetes Service Account annotations for Vault alias metadata.

When use_annotations_as_alias_metadata is true, you can use the identity.entity.aliases.<mount accessor>.metadata.<metadata key> template parameter when you create templated policies.

To use annotations as alias metadata, you must give Vault permission to read service accounts from the Kubernetes API.

Scenario Introduction

Assume you have the following policy requirement:

Applications can perform read operations on their allocated key/value secret path: (env-kv/data/<env>)

Annotate Kubernetes Service Accounts with their dedicated secret paths
apiVersion: v1
kind: ServiceAccount
metadata:
  name: app
  namespace: demo
  annotations:
    vault.hashicorp.com/alias-metadata-env: demo/app

When the application, app, logs in with JWT for the service account, Vault renders the alias metadata as env : demo/app.

Create a templated ACL policy

The env-tmpl policy lets applications read their secrets defined in KV v2 secret engine. Use the mount accessor value (auth_kubernetes_bcecb1e1) from the sys/auth endpoint or the vault auth list command.

$ tee env-tmpl.hcl <<EOF
path "env-kv/data/{{identity.entity.aliases.auth_kubernetes_bcecb1e1.metadata.env}}" {
  capabilities = [ "read" ]
}
EOF
$ vault policy write env-tmpl env-tmpl.hcl
Create a Kubernetes role with the templated ACL policy

The Kubernetes role lets users login as the env-reader role to read from the secret path described in the env-tmpl policy.

$ vault write auth/kubernetes/role/env-reader \
    bound_service_account_names=app \
    bound_service_account_namespaces=demo \
    policies=default,env-tmpl \
    ttl=1h

The following example demonstrates the Kubernetes auth method to authenticate with Vault.

package main

import (
    "fmt"
    "os"

    vault "github.com/hashicorp/vault/api"
    auth "github.com/hashicorp/vault/api/auth/kubernetes"
)

// Fetches a key-value secret (kv-v2) after authenticating to Vault with a Kubernetes service account.
// For a more in-depth setup explanation, please see the relevant readme in the hashicorp/vault-examples repo.
func getSecretWithKubernetesAuth() (string, error) {
    // If set, the VAULT_ADDR environment variable will be the address that
    // your pod uses to communicate with Vault.
    config := vault.DefaultConfig() // modify for more granular configuration

    client, err := vault.NewClient(config)
    if err != nil {
        return "", fmt.Errorf("unable to initialize Vault client: %w", err)
    }

    // The service-account token will be read from the path where the token's
    // Kubernetes Secret is mounted. By default, Kubernetes will mount it to
    // /var/run/secrets/kubernetes.io/serviceaccount/token, but an administrator
    // may have configured it to be mounted elsewhere.
    // In that case, we'll use the option WithServiceAccountTokenPath to look
    // for the token there.
    k8sAuth, err := auth.NewKubernetesAuth(
        "dev-role-k8s",
        auth.WithServiceAccountTokenPath("path/to/service-account-token"),
    )
    if err != nil {
        return "", fmt.Errorf("unable to initialize Kubernetes auth method: %w", err)
    }

    authInfo, err := client.Auth().Login(context.TODO(), k8sAuth)
    if err != nil {
        return "", fmt.Errorf("unable to log in with Kubernetes auth: %w", err)
    }
    if authInfo == nil {
        return "", fmt.Errorf("no auth info was returned after login")
    }

    // get secret from Vault, from the default mount path for KV v2 in dev mode, "secret"
    secret, err := client.KVv2("secret").Get(context.Background(), "creds")
    if err != nil {
        return "", fmt.Errorf("unable to read secret: %w", err)
    }

    // data map can contain more than one key-value pair,
    // in this case we're just grabbing one of them
    value, ok := secret.Data["password"].(string)
    if !ok {
        return "", fmt.Errorf("value type assertion failed: %T %#v", secret.Data["password"], secret.Data["password"])
    }

    return value, nil
}
using System;
using System.IO;
using VaultSharp;
using VaultSharp.V1.AuthMethods;
using VaultSharp.V1.AuthMethods.Kubernetes;
using VaultSharp.V1.Commons;

namespace Examples
{
    public class KubernetesAuthExample
    {
        const string DefaultTokenPath = "path/to/service-account-token";

        // Fetches a key-value secret (kv-v2) after authenticating to Vault with a Kubernetes service account.
        // For a more in-depth setup explanation, please see the relevant readme in the hashicorp/vault-examples repo.
        public string GetSecretWithK8s()
        {
            var vaultAddr = Environment.GetEnvironmentVariable("VAULT_ADDR");
            if(String.IsNullOrEmpty(vaultAddr))
            {
                throw new System.ArgumentNullException("Vault Address");
            }

            var roleName = Environment.GetEnvironmentVariable("VAULT_ROLE");
            if(String.IsNullOrEmpty(roleName))
            {
                throw new System.ArgumentNullException("Vault Role Name");
            }

            // Get the path to service account token or fall back on default path
            string pathToToken = String.IsNullOrEmpty(Environment.GetEnvironmentVariable("SA_TOKEN_PATH")) ? DefaultTokenPath : Environment.GetEnvironmentVariable("SA_TOKEN_PATH");
            string jwt = File.ReadAllText(pathToToken);

            IAuthMethodInfo authMethod = new KubernetesAuthMethodInfo(roleName, jwt);
            var vaultClientSettings = new VaultClientSettings(vaultAddr, authMethod);

            IVaultClient vaultClient = new VaultClient(vaultClientSettings);

            // We can retrieve the secret after creating our VaultClient object
            Secret<SecretData> kv2Secret = null;
            kv2Secret = vaultClient.V1.Secrets.KeyValue.V2.ReadSecretAsync(path: "/creds").Result;

            var password = kv2Secret.Data.Data["password"];

            return password.ToString();
        }
    }
}

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4