Skip to content

Commit

Permalink
adding external cluster vault auth APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
vramk23 committed Jan 26, 2024
1 parent b8cdfab commit ab8d941
Show file tree
Hide file tree
Showing 7 changed files with 539 additions and 210 deletions.
4 changes: 0 additions & 4 deletions internal/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ import (
"github.com/pkg/errors"
)

const (
vaultPolicyReadPath = `path "secret/data/%s" {capabilities = ["read"]}`
)

type VaultCredServ struct {
vaultcredpb.UnimplementedVaultCredServer
conf config.VaultEnv
Expand Down
60 changes: 58 additions & 2 deletions internal/api/vault_k8s_role_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,71 @@ import (
"context"
"fmt"

"github.com/intelops/vault-cred/internal/client"
"github.com/intelops/vault-cred/proto/pb/vaultcredpb"
)

func (v *VaultCredServ) ConfigureClusterK8SAuth(ctx context.Context, request *vaultcredpb.ConfigureClusterK8SAuthRequest) (*vaultcredpb.ConfigureClusterK8SAuthResponse, error) {
func (v *VaultCredServ) AddClusterK8SAuth(ctx context.Context, request *vaultcredpb.AddClusterK8SAuthRequest) (*vaultcredpb.AddClusterK8SAuthResponse, error) {
v.log.Infof("add k8s auth request for cluster %s", request.ClusterName)

vc, err := client.NewVaultClientForTokenFromEnv(v.log, v.conf)
if err != nil {
v.log.Infof("error in getting vault client, %v", err)
return &vaultcredpb.AddClusterK8SAuthResponse{Status: vaultcredpb.StatusCode_INTERNRAL_ERROR}, err
}

err = vc.ClusterEnableK8sAuth(request.ClusterName, request.Host, request.CaCert, request.JwtToken)
if err != nil {
v.log.Infof("error in adding k8s auth request for cluster %s, %v", request.ClusterName, err)
return &vaultcredpb.AddClusterK8SAuthResponse{Status: vaultcredpb.StatusCode_INTERNRAL_ERROR}, err
}
v.log.Infof("k8s auth request for cluster %s added", request.ClusterName)
return &vaultcredpb.AddClusterK8SAuthResponse{Status: vaultcredpb.StatusCode_OK}, nil
}

func (v *VaultCredServ) DeleteClusterK8SAuth(ctx context.Context, request *vaultcredpb.DeleteClusterK8SAuthRequest) (*vaultcredpb.DeleteClusterK8SAuthResponse, error) {
return nil, fmt.Errorf("not supported")
}

func (v *VaultCredServ) CreateK8SAuthRole(ctx context.Context, request *vaultcredpb.CreateK8SAuthRoleRequest) (*vaultcredpb.CreateK8SAuthRoleResponse, error) {
return nil, nil
v.log.Infof("create k8s auth role %s for cluster %s", request.RoleName, request.ClusterName)

vc, err := client.NewVaultClientForTokenFromEnv(v.log, v.conf)
if err != nil {
v.log.Infof("error in getting vault client, %v", err)
return &vaultcredpb.CreateK8SAuthRoleResponse{Status: vaultcredpb.StatusCode_INTERNRAL_ERROR}, err
}

var policyData string
for _, secretPolicy := range request.SecretPolicy {
var credPathPolicy string
if secretPolicy.Access == vaultcredpb.SecretAccess_READ {
credPathPolicy = fmt.Sprintf(vaultPolicyReadPath, secretPolicy.SecretPath)
} else if secretPolicy.Access == vaultcredpb.SecretAccess_WRITE {
credPathPolicy = fmt.Sprintf(vaultPolicyWritePath, secretPolicy.SecretPath)
} else {
return &vaultcredpb.CreateK8SAuthRoleResponse{Status: vaultcredpb.StatusCode_INVALID_ARGUMENT}, fmt.Errorf("invalid security policy")
}
policyData = policyData + "\n" + credPathPolicy
}

policyName := "policy-" + request.ClusterName + "-" + request.RoleName
err = vc.CreateOrUpdatePolicy(policyName, policyData)
if err != nil {
v.log.Infof("error in creating k8s auth policy %s, %v", policyName, err)
return &vaultcredpb.CreateK8SAuthRoleResponse{Status: vaultcredpb.StatusCode_INTERNRAL_ERROR}, err
}

v.log.Infof("k8s auth policy %s created", policyName)

roleName := "role-" + request.ClusterName + "-" + request.RoleName
err = vc.CreateOrUpdateClusterRole(request.ClusterName, roleName, request.ServiceAccounts, request.Namespaces, []string{policyName})
if err != nil {
v.log.Infof("error in creating k8s auth policy %s, %v", policyName, err)
return &vaultcredpb.CreateK8SAuthRoleResponse{Status: vaultcredpb.StatusCode_INTERNRAL_ERROR}, err
}

return &vaultcredpb.CreateK8SAuthRoleResponse{Status: vaultcredpb.StatusCode_OK}, nil
}

func (v *VaultCredServ) UpdateK8SAuthRole(ctx context.Context, request *vaultcredpb.UpdateK8SAuthRoleRequest) (*vaultcredpb.UpdateK8SAuthRoleResponse, error) {
Expand Down
29 changes: 29 additions & 0 deletions internal/client/vault_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,32 @@ func (v *VaultClient) AuthenticateWithAppRole(roleName string) (string, error) {

return secret.Auth.ClientToken, nil
}

func (v *VaultClient) ClusterEnableK8sAuth(clusterName, host, caCert, jwtToken string) error {
options := api.MountInput{
Type: "kubernetes",
Description: "Kubernetes authentication",
}

authPath := "k8s-" + clusterName
err := v.c.Sys().EnableAuthWithOptions(authPath, &options)
if err != nil {
return errors.WithMessage(err, "failed to enable auth kubernetes")
}

configData := map[string]interface{}{
"kubernetes_host": host,
"kubernetes_ca_cert": caCert,
"token_reviewer_jwt": jwtToken,
"kubernetes_skip_tls_verify": "true",
}

configPath := "/auth/kubernetes/config/" + clusterName
_, err = v.c.Logical().Write(configPath, configData)
if err != nil {
return errors.WithMessage(err, "failed to write to k8s auth config")
}

v.log.Infof("cluster %s auth kubernetes enabled", clusterName)
return nil
}
20 changes: 20 additions & 0 deletions internal/client/vault_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,26 @@ func (v *VaultClient) CreateOrUpdateRole(roleName string, serviceAccounts, names
return nil
}

func (v *VaultClient) CreateOrUpdateClusterRole(clusterName, roleName string, serviceAccounts, namespaces, policies []string) error {
roleData := make(map[string]interface{})

sa := strings.Join(serviceAccounts, ",")
ns := strings.Join(namespaces, ",")
roleData["bound_service_account_names"] = sa
roleData["bound_service_account_namespaces"] = ns
roleData["policies"] = policies
roleData["max_ttl"] = 1800000

path := fmt.Sprintf("/auth/k8s-%s/role/%s", clusterName, roleName)
_, err := v.c.Logical().Write(path, roleData)
if err != nil {
return err
}

v.log.Infof("Updated role %s", roleName)
return nil
}

func (v *VaultClient) CreateOrUpdateAppRole(roleName string, policies []string) error {
roleData := make(map[string]interface{})

Expand Down
Loading

0 comments on commit ab8d941

Please sign in to comment.