| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- /*
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- package vault
- import (
- "context"
- "errors"
- "fmt"
- "sigs.k8s.io/controller-runtime/pkg/webhook/admission"
- esv1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1"
- "github.com/external-secrets/external-secrets/pkg/utils"
- )
- const (
- errInvalidCredentials = "invalid vault credentials: %w"
- errInvalidStore = "invalid store"
- errInvalidStoreSpec = "invalid store spec"
- errInvalidStoreProv = "invalid store provider"
- errInvalidVaultProv = "invalid vault provider"
- errInvalidAppRoleRef = "invalid Auth.AppRole.RoleRef: %w"
- errInvalidAppRoleSec = "invalid Auth.AppRole.SecretRef: %w"
- errInvalidClientCert = "invalid Auth.Cert.ClientCert: %w"
- errInvalidCertSec = "invalid Auth.Cert.SecretRef: %w"
- errInvalidJwtSec = "invalid Auth.Jwt.SecretRef: %w"
- errInvalidJwtK8sSA = "invalid Auth.Jwt.KubernetesServiceAccountToken.ServiceAccountRef: %w"
- errInvalidKubeSA = "invalid Auth.Kubernetes.ServiceAccountRef: %w"
- errInvalidKubeSec = "invalid Auth.Kubernetes.SecretRef: %w"
- errInvalidLdapSec = "invalid Auth.Ldap.SecretRef: %w"
- errInvalidTokenRef = "invalid Auth.TokenSecretRef: %w"
- errInvalidUserPassSec = "invalid Auth.UserPass.SecretRef: %w"
- errInvalidClientTLSCert = "invalid ClientTLS.ClientCert: %w"
- errInvalidClientTLSSecret = "invalid ClientTLS.SecretRef: %w"
- errInvalidClientTLS = "when provided, both ClientTLS.ClientCert and ClientTLS.SecretRef should be provided"
- errCASNotSupportedInKVv1 = "checkAndSet is not supported with Vault KV version v1"
- )
- func (p *Provider) ValidateStore(store esv1.GenericStore) (admission.Warnings, error) {
- if store == nil {
- return nil, errors.New(errInvalidStore)
- }
- spc := store.GetSpec()
- if spc == nil {
- return nil, errors.New(errInvalidStoreSpec)
- }
- if spc.Provider == nil {
- return nil, errors.New(errInvalidStoreProv)
- }
- vaultProvider := spc.Provider.Vault
- if vaultProvider == nil {
- return nil, errors.New(errInvalidVaultProv)
- }
- if vaultProvider.Auth != nil {
- if vaultProvider.Auth.AppRole != nil {
- // check SecretRef for valid configuration
- if err := utils.ValidateReferentSecretSelector(store, vaultProvider.Auth.AppRole.SecretRef); err != nil {
- return nil, fmt.Errorf(errInvalidAppRoleSec, err)
- }
- // prefer .auth.appRole.roleId, fallback to .auth.appRole.roleRef, give up after that.
- if vaultProvider.Auth.AppRole.RoleID == "" { // prevents further RoleID tests if .auth.appRole.roleId is given
- if vaultProvider.Auth.AppRole.RoleRef != nil { // check RoleRef for valid configuration
- if err := utils.ValidateReferentSecretSelector(store, *vaultProvider.Auth.AppRole.RoleRef); err != nil {
- return nil, fmt.Errorf(errInvalidAppRoleRef, err)
- }
- } else { // we ran out of ways to get RoleID. return an appropriate error
- return nil, errors.New(errInvalidAppRoleID)
- }
- }
- }
- if vaultProvider.Auth.Cert != nil {
- if err := utils.ValidateReferentSecretSelector(store, vaultProvider.Auth.Cert.ClientCert); err != nil {
- return nil, fmt.Errorf(errInvalidClientCert, err)
- }
- if err := utils.ValidateReferentSecretSelector(store, vaultProvider.Auth.Cert.SecretRef); err != nil {
- return nil, fmt.Errorf(errInvalidCertSec, err)
- }
- }
- if vaultProvider.Auth.Jwt != nil {
- if vaultProvider.Auth.Jwt.SecretRef != nil {
- if err := utils.ValidateReferentSecretSelector(store, *vaultProvider.Auth.Jwt.SecretRef); err != nil {
- return nil, fmt.Errorf(errInvalidJwtSec, err)
- }
- } else if vaultProvider.Auth.Jwt.KubernetesServiceAccountToken != nil {
- if err := utils.ValidateReferentServiceAccountSelector(store, vaultProvider.Auth.Jwt.KubernetesServiceAccountToken.ServiceAccountRef); err != nil {
- return nil, fmt.Errorf(errInvalidJwtK8sSA, err)
- }
- } else {
- return nil, errors.New(errJwtNoTokenSource)
- }
- }
- if vaultProvider.Auth.Kubernetes != nil {
- if vaultProvider.Auth.Kubernetes.ServiceAccountRef != nil {
- if err := utils.ValidateReferentServiceAccountSelector(store, *vaultProvider.Auth.Kubernetes.ServiceAccountRef); err != nil {
- return nil, fmt.Errorf(errInvalidKubeSA, err)
- }
- }
- if vaultProvider.Auth.Kubernetes.SecretRef != nil {
- if err := utils.ValidateReferentSecretSelector(store, *vaultProvider.Auth.Kubernetes.SecretRef); err != nil {
- return nil, fmt.Errorf(errInvalidKubeSec, err)
- }
- }
- }
- if vaultProvider.Auth.Ldap != nil {
- if err := utils.ValidateReferentSecretSelector(store, vaultProvider.Auth.Ldap.SecretRef); err != nil {
- return nil, fmt.Errorf(errInvalidLdapSec, err)
- }
- }
- if vaultProvider.Auth.UserPass != nil {
- if err := utils.ValidateReferentSecretSelector(store, vaultProvider.Auth.UserPass.SecretRef); err != nil {
- return nil, fmt.Errorf(errInvalidUserPassSec, err)
- }
- }
- if vaultProvider.Auth.TokenSecretRef != nil {
- if err := utils.ValidateReferentSecretSelector(store, *vaultProvider.Auth.TokenSecretRef); err != nil {
- return nil, fmt.Errorf(errInvalidTokenRef, err)
- }
- }
- if vaultProvider.Auth.Iam != nil {
- if vaultProvider.Auth.Iam.JWTAuth != nil {
- if vaultProvider.Auth.Iam.JWTAuth.ServiceAccountRef != nil {
- if err := utils.ValidateReferentServiceAccountSelector(store, *vaultProvider.Auth.Iam.JWTAuth.ServiceAccountRef); err != nil {
- return nil, fmt.Errorf(errInvalidTokenRef, err)
- }
- }
- }
- if vaultProvider.Auth.Iam.SecretRef != nil {
- if err := utils.ValidateReferentSecretSelector(store, vaultProvider.Auth.Iam.SecretRef.AccessKeyID); err != nil {
- return nil, fmt.Errorf(errInvalidTokenRef, err)
- }
- if err := utils.ValidateReferentSecretSelector(store, vaultProvider.Auth.Iam.SecretRef.SecretAccessKey); err != nil {
- return nil, fmt.Errorf(errInvalidTokenRef, err)
- }
- if vaultProvider.Auth.Iam.SecretRef.SessionToken != nil {
- if err := utils.ValidateReferentSecretSelector(store, *vaultProvider.Auth.Iam.SecretRef.SessionToken); err != nil {
- return nil, fmt.Errorf(errInvalidTokenRef, err)
- }
- }
- }
- }
- }
- if vaultProvider.ClientTLS.CertSecretRef != nil && vaultProvider.ClientTLS.KeySecretRef != nil {
- if err := utils.ValidateReferentSecretSelector(store, *vaultProvider.ClientTLS.CertSecretRef); err != nil {
- return nil, fmt.Errorf(errInvalidClientTLSCert, err)
- }
- if err := utils.ValidateReferentSecretSelector(store, *vaultProvider.ClientTLS.KeySecretRef); err != nil {
- return nil, fmt.Errorf(errInvalidClientTLSSecret, err)
- }
- } else if vaultProvider.ClientTLS.CertSecretRef != nil || vaultProvider.ClientTLS.KeySecretRef != nil {
- return nil, errors.New(errInvalidClientTLS)
- }
- // Validate CAS configuration
- if vaultProvider.CheckAndSet != nil && vaultProvider.CheckAndSet.Required {
- if vaultProvider.Version == esv1.VaultKVStoreV1 {
- return nil, errors.New(errCASNotSupportedInKVv1)
- }
- }
- return nil, nil
- }
- func (c *client) Validate() (esv1.ValidationResult, error) {
- // when using referent namespace we can not validate the token
- // because the namespace is not known yet when Validate() is called
- // from the SecretStore controller.
- if c.storeKind == esv1.ClusterSecretStoreKind && isReferentSpec(c.store) {
- return esv1.ValidationResultUnknown, nil
- }
- _, err := checkToken(context.Background(), c.token)
- if err != nil {
- return esv1.ValidationResultError, fmt.Errorf(errInvalidCredentials, err)
- }
- return esv1.ValidationResultReady, nil
- }
|