Golang: Authenticate Your vault sdk with Kubenetes

Ankit malik - Sep 17 '21 - - Dev Community

Why we should authenticate vault with Kubenetes

When wer ar running our application in Kubenetes pods then we can directly connect vault and pod which will create a token inside the pod at specific location.
So to access the data from vault we need to generate the token with Kubernetes token.
Benefit: The main benefit of this method is that we don't need the static token for vault.

Example

package main

import (
    "context"
    "encoding/json"
    "fmt"

    "github.com/go-resty/resty/v2"
    "github.com/hashicorp/go-hclog"
    "github.com/hashicorp/vault/command/agent/auth"
    vaultKube "github.com/hashicorp/vault/command/agent/auth/kubernetes"
)

// const can be created for these variables
var kubeTokenVaulPath = "{{your kubernetes vault token file path}}"
var KubeTokenRole = "{{your kube token role}}"
var vaultAddr = "{{your vault address}}"
var mountPath = "/v1/auth/{{path for Kv}}"

type VaultAuth struct {
    ClientToken string `json:"client_token"`
    Accessor    string `json:"accessor"`
}
type CredOutput struct {
    Auth VaultAuth `json:"auth"`
}

func main() {
    appLogger := hclog.New(&hclog.LoggerOptions{
        Name:  "my-app",
        Level: hclog.LevelFromString("DEBUG"),
    })

    auth, err := vaultKube.NewKubernetesAuthMethod(&auth.AuthConfig{
        Logger:    appLogger,
        MountPath: vaultAddr + mountPath,
        Config: map[string]interface{}{
            "role":       KubeTokenRole,
            "token_path": kubeTokenVaulPath,
        },
    })

    if err != nil {
        panic(err)
    }

    // this functions returns
    // path which is the url where we need to request
    // header it will generate the headers required for the request
    // body - it will generated the body token request
    path, header, body, err := auth.Authenticate(context.Background(), nil)
    if err != nil {
        panic(err)
    }
    fmt.Println(path, header, body)

    // I am using Resty because direct vault request client was not working
    client := resty.New()
    resp, err := client.R().
        SetBody(body).
        Post(path)
    if err != nil {
        panic(err)
    }
    fmt.Println("output", string(resp.Body()))

    // creds will be the object where we will get
    // the token generated for vault to access data
    creds := CredOutput{}
    json.Unmarshal(resp.Body(), &creds)
    fmt.Println("final obj", creds)
}

Enter fullscreen mode Exit fullscreen mode

We need to define these 4 params in order to generate the token for vault from Kubernetes pods token.

var kubeTokenVaulPath = "{{your kubernetes vault token file path}}"
var KubeTokenRole = "{{your kube token role}}"
var vaultAddr = "{{your vault address}}"
var mountPath = "/v1/auth/{{path for KV}}"
Enter fullscreen mode Exit fullscreen mode

mountPath: will be used to generate the token path.
Vault have default path with the name secrets for KV path

I am using Resty client because vault's NewRequest was not working.
Look at how we can use vault's inbuild rawRequest method but wasn't working for me.
Not Recommended As of Now

req := client.NewRequest("POST", path)
req.SetJSONBody(output)
resp, err := client.RawRequest(req)
Enter fullscreen mode Exit fullscreen mode
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player