From 818502bc835e10da4d61ec89ae3ce5f323077a7c Mon Sep 17 00:00:00 2001 From: Loann Le <84412881+taoism4504@users.noreply.github.com> Date: Fri, 8 Oct 2021 14:57:53 -0700 Subject: [PATCH] Vault documentation: added new code sample to Kubernetes documentation (#12774) * added new code sample for k8s auth * Update kubernetes.mdx removed spacing --- website/content/docs/auth/kubernetes.mdx | 83 ++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/website/content/docs/auth/kubernetes.mdx b/website/content/docs/auth/kubernetes.mdx index 1ba8d4876bf4..3508e06122ae 100644 --- a/website/content/docs/auth/kubernetes.mdx +++ b/website/content/docs/auth/kubernetes.mdx @@ -176,3 +176,86 @@ The Kubernetes Auth Plugin has a full HTTP API. Please see the [API docs](/api/auth/kubernetes) for more details. [k8s-tokenreview]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#tokenreview-v1beta1-authentication-k8s-io + +## Code Example + +The following code snippet demonstrates the Kubernetes auth method to authenticate +with Vault. + + + + + +```go +package main + +import ( + "fmt" + "os" + + vault "github.com/hashicorp/vault/api" +) + +// Fetches a key-value secret (kv-v2) after authenticating to Vault with a Kubernetes service account. +// +// As the client, all we need to do is pass along the JWT token representing our application's Kubernetes Service Account in our login request to Vault. +// +// For a more in-depth setup explanation, please see the full version of this code 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) + } + + // Read the service-account token from the path where the token's Kubernetes Secret is mounted. + // By default, Kubernetes will mount this to /var/run/secrets/kubernetes.io/serviceaccount/token + // but an administrator may have configured it to be mounted elsewhere. + jwt, err := os.ReadFile("path/to/service-account-token") + if err != nil { + return "", fmt.Errorf("unable to read file containing service account token: %w", err) + } + + params := map[string]interface{}{ + "jwt": string(jwt), + "role": "dev-role-k8s", // the name of the role in Vault that was created with this app's Kubernetes service account bound to it + } + + // log in to Vault's Kubernetes auth method + resp, err := client.Logical().Write("auth/kubernetes/login", params) + if err != nil { + return "", fmt.Errorf("unable to log in with Kubernetes auth: %w", err) + } + if resp == nil || resp.Auth == nil || resp.Auth.ClientToken == "" { + return "", fmt.Errorf("login response did not return client token") + } + + // now you will use the resulting Vault token for making all future calls to Vault + client.SetToken(resp.Auth.ClientToken) + + // get secret from Vault + secret, err := client.Logical().Read("kv-v2/data/creds") + if err != nil { + return "", fmt.Errorf("unable to read secret: %w", err) + } + + data, ok := secret.Data["data"].(map[string]interface{}) + if !ok { + return "", fmt.Errorf("data type assertion failed: %T %#v", secret.Data["data"], secret.Data["data"]) + } + + // data map can contain more than one key-value pair, in this case we're just grabbing one of them + key := "password" + value, ok := data[key].(string) + if !ok { + return "", fmt.Errorf("value type assertion failed: %T %#v", data[key], data[key]) + } + + return value, nil +} +``` + + +