Skip to content

Commit

Permalink
feat: add kubernetes vault auth
Browse files Browse the repository at this point in the history
  • Loading branch information
soerenschneider committed Sep 10, 2023
1 parent 917bfdf commit 0abdc46
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 8 deletions.
4 changes: 4 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ func buildVaultAuth(conf config.AcmeVaultServerConfig) (vault.Auth, error) {
FromString: conf.SecretId,
}
return vault.NewApproleAuth(conf.RoleId, secretId)
case "k8s":
return vault.NewVaultKubernetesAuth(conf.K8sRoleId, conf.K8sMountPath)
case "implicit":
return vault.NewImplicitAuth()
default:
return nil, fmt.Errorf("no valid auth method: %s", conf.AuthMethod)
}
Expand Down
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ require (
github.com/blushft/go-diagrams v0.0.0-20201006005127-c78c821223d9
github.com/go-acme/lego/v4 v4.13.3
github.com/go-playground/validator/v10 v10.15.0
github.com/hashicorp/vault/api v1.9.2
github.com/hashicorp/vault/api v1.10.0
github.com/hashicorp/vault/api/auth/approle v0.4.1
github.com/hashicorp/vault/api/auth/kubernetes v0.5.0
github.com/prometheus/client_golang v1.16.0
github.com/rs/zerolog v1.30.0
github.com/stretchr/testify v1.8.4
go.uber.org/multierr v1.11.0
golang.org/x/net v0.11.0
)

require (
Expand Down Expand Up @@ -57,7 +59,6 @@ require (
github.com/stretchr/objx v0.5.0 // indirect
golang.org/x/crypto v0.10.0 // indirect
golang.org/x/mod v0.11.0 // indirect
golang.org/x/net v0.11.0 // indirect
golang.org/x/sys v0.9.0 // indirect
golang.org/x/text v0.10.0 // indirect
golang.org/x/time v0.3.0 // indirect
Expand Down
5 changes: 4 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,13 @@ github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjG
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM=
github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM=
github.com/hashicorp/vault/api v1.9.2 h1:YjkZLJ7K3inKgMZ0wzCU9OHqc+UqMQyXsPXnf3Cl2as=
github.com/hashicorp/vault/api v1.9.2/go.mod h1:jo5Y/ET+hNyz+JnKDt8XLAdKs+AM0G5W0Vp1IrFI8N8=
github.com/hashicorp/vault/api v1.10.0 h1:/US7sIjWN6Imp4o/Rj1Ce2Nr5bki/AXi9vAW3p2tOJQ=
github.com/hashicorp/vault/api v1.10.0/go.mod h1:jo5Y/ET+hNyz+JnKDt8XLAdKs+AM0G5W0Vp1IrFI8N8=
github.com/hashicorp/vault/api/auth/approle v0.4.1 h1:NElpX7DZ2uaLGwY+leWXHUqw9tepsYkcHvIowgIZteI=
github.com/hashicorp/vault/api/auth/approle v0.4.1/go.mod h1:rlI2VbmuHkptRun7DngpxOSvRC+JuITqAs/Z09pUucU=
github.com/hashicorp/vault/api/auth/kubernetes v0.5.0 h1:CXO0fD7M3iCGovP/UApeHhPcH4paDFKcu7AjEXi94rI=
github.com/hashicorp/vault/api/auth/kubernetes v0.5.0/go.mod h1:afrElBIO9Q4sHFVuVWgNevG4uAs1bT2AZFA9aEiI608=
github.com/iancoleman/strcase v0.1.1/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
Expand Down
13 changes: 8 additions & 5 deletions internal/config/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@ var validate = validator.New()

type VaultConfig struct {
Addr string `json:"vaultAddr" validate:"required,http_url"`
AuthMethod string `json:"vaultAuthMethod" validate:"required,oneof=token approle"`
Token string `json:"vaultToken" validate:"required_if=RoleId ''"`
AuthMethod string `json:"vaultAuthMethod" validate:"required,oneof=token approle k8s"`
Token string `json:"vaultToken" validate:"required_if=AuthMethod 'token'"`

RoleId string `json:"vaultRoleId" validate:"required_if=Token ''"`
SecretId string `json:"vaultSecretId" validate:"excluded_unless=SecretIdFile '',required_if=SecretIdFile '' Token ''"`
SecretIdFile string `json:"vaultSecretIdFile" validate:"excluded_unless=SecretId '',required_if=SecretId '' Token ''"`
RoleId string `json:"vaultRoleId" validate:"required_if=AuthMethod 'approle'"`
SecretId string `json:"vaultSecretId" validate:"excluded_unless=SecretIdFile '',required_if=SecretIdFile '' AuthMethod 'approle'"`
SecretIdFile string `json:"vaultSecretIdFile" validate:"excluded_unless=SecretId '',required_if=SecretId '' AuthMethod 'approle'"`

K8sRoleId string `json:"vaultK8sRoleId" validate:"required_if=AuthMethod 'k8s'"`
K8sMountPath string `json:"vaultK8sMountPath"`

PathPrefix string `json:"vaultPathPrefix" validate:"required,startsnotwith=/,startsnotwith=/secret,endsnotwith=/,ne=acmevault"`
DomainPathFormat string `json:"domainPathFormat" validate:"omitempty,containsrune=%"`
Expand Down
55 changes: 55 additions & 0 deletions pkg/certstorage/vault/auth_kubernetes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package vault

import (
"fmt"

"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/api/auth/kubernetes"
"golang.org/x/net/context"
)

const (
defaultServiceAccountTokenFile = "/var/run/secrets/kubernetes.io/serviceaccount/token" // #nosec G101
defaultMount = "kubernetes"
)

type KubernetesAuth struct {
role string
serviceAccountTokenFile string
mount string
}

func NewVaultKubernetesAuth(role string, mountPath string) (*KubernetesAuth, error) {
return &KubernetesAuth{
role: role,
mount: mountPath,
serviceAccountTokenFile: defaultServiceAccountTokenFile,
}, nil
}

func (t *KubernetesAuth) Logout(ctx context.Context, client *api.Client) error {
path := "auth/token/revoke-self"
_, err := client.Logical().Write(path, map[string]interface{}{})
return err
}

func (t *KubernetesAuth) Login(ctx context.Context, client *api.Client) (*api.Secret, error) {
k8sAuth, err := kubernetes.NewKubernetesAuth(
t.role,
kubernetes.WithServiceAccountTokenPath(t.serviceAccountTokenFile),
kubernetes.WithMountPath(t.mount))

if err != nil {
return nil, fmt.Errorf("unable to initialize Kubernetes kubernetes method: %w", err)
}

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

return authInfo, nil
}

0 comments on commit 0abdc46

Please sign in to comment.