vault.go 58 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806
  1. /*
  2. Licensed under the Apache License, Version 2.0 (the "License");
  3. you may not use this file except in compliance with the License.
  4. You may obtain a copy of the License at
  5. http://www.apache.org/licenses/LICENSE-2.0
  6. Unless required by applicable law or agreed to in writing, software
  7. distributed under the License is distributed on an "AS IS" BASIS,
  8. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9. See the License for the specific language governing permissions and
  10. limitations under the License.
  11. */
  12. package vault
  13. import (
  14. "bytes"
  15. "context"
  16. "crypto/tls"
  17. "crypto/x509"
  18. "encoding/json"
  19. "errors"
  20. "fmt"
  21. "net/http"
  22. "os"
  23. "strings"
  24. "time"
  25. "github.com/aws/aws-sdk-go/aws"
  26. "github.com/aws/aws-sdk-go/aws/credentials"
  27. "github.com/aws/aws-sdk-go/aws/credentials/stscreds"
  28. "github.com/go-logr/logr"
  29. "github.com/golang-jwt/jwt/v5"
  30. vault "github.com/hashicorp/vault/api"
  31. approle "github.com/hashicorp/vault/api/auth/approle"
  32. authaws "github.com/hashicorp/vault/api/auth/aws"
  33. authkubernetes "github.com/hashicorp/vault/api/auth/kubernetes"
  34. authldap "github.com/hashicorp/vault/api/auth/ldap"
  35. authuserpass "github.com/hashicorp/vault/api/auth/userpass"
  36. "github.com/spf13/pflag"
  37. "github.com/tidwall/gjson"
  38. authenticationv1 "k8s.io/api/authentication/v1"
  39. corev1 "k8s.io/api/core/v1"
  40. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  41. "k8s.io/apimachinery/pkg/types"
  42. "k8s.io/client-go/kubernetes"
  43. typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
  44. ctrl "sigs.k8s.io/controller-runtime"
  45. kclient "sigs.k8s.io/controller-runtime/pkg/client"
  46. ctrlcfg "sigs.k8s.io/controller-runtime/pkg/client/config"
  47. esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
  48. esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
  49. "github.com/external-secrets/external-secrets/pkg/cache"
  50. "github.com/external-secrets/external-secrets/pkg/constants"
  51. "github.com/external-secrets/external-secrets/pkg/feature"
  52. "github.com/external-secrets/external-secrets/pkg/find"
  53. "github.com/external-secrets/external-secrets/pkg/metrics"
  54. vaultiamauth "github.com/external-secrets/external-secrets/pkg/provider/vault/iamauth"
  55. "github.com/external-secrets/external-secrets/pkg/provider/vault/util"
  56. "github.com/external-secrets/external-secrets/pkg/utils"
  57. )
  58. var (
  59. _ esv1beta1.Provider = &Connector{}
  60. _ esv1beta1.SecretsClient = &client{}
  61. enableCache bool
  62. logger = ctrl.Log.WithName("provider").WithName("vault")
  63. clientCache *cache.Cache[util.Client]
  64. )
  65. const (
  66. serviceAccTokenPath = "/var/run/secrets/kubernetes.io/serviceaccount/token"
  67. defaultAWSRegion = "us-east-1"
  68. defaultAWSAuthMountPath = "aws"
  69. errVaultStore = "received invalid Vault SecretStore resource: %w"
  70. errVaultCacheCreate = "cannot create Vault client cache: %s"
  71. errVaultCacheRemove = "error removing item from Vault client cache: %w"
  72. errVaultCacheEviction = "unexpected eviction from Vault client cache"
  73. errVaultClient = "cannot setup new vault client: %w"
  74. errVaultCert = "cannot set Vault CA certificate: %w"
  75. errReadSecret = "cannot read secret data from Vault: %w"
  76. errAuthFormat = "cannot initialize Vault client: no valid auth method specified"
  77. errInvalidCredentials = "invalid vault credentials: %w"
  78. errDataField = "failed to find data field"
  79. errJSONUnmarshall = "failed to unmarshall JSON"
  80. errPathInvalid = "provided Path isn't a valid kv v2 path"
  81. errUnexpectedKey = "unexpected key in data: %s"
  82. errVaultToken = "cannot parse Vault authentication token: %w"
  83. errVaultRequest = "error from Vault request: %w"
  84. errServiceAccount = "cannot read Kubernetes service account token from file system: %w"
  85. errJwtNoTokenSource = "neither `secretRef` nor `kubernetesServiceAccountToken` was supplied as token source for jwt authentication"
  86. errUnsupportedKvVersion = "cannot perform find operations with kv version v1"
  87. errUnsupportedMetadataKvVersion = "cannot perform metadata fetch operations with kv version v1"
  88. errNotFound = "secret not found"
  89. errIrsaTokenEnvVarNotFoundOnPod = "expected env variable: %s not found on controller's pod"
  90. errIrsaTokenFileNotFoundOnPod = "web ddentity token file not found at %s location: %w"
  91. errIrsaTokenFileNotReadable = "could not read the web identity token from the file %s: %w"
  92. errIrsaTokenNotValidJWT = "could not parse web identity token available at %s. not a valid jwt?: %w"
  93. errPodInfoNotFoundOnToken = "could not find pod identity info on token %s: %w"
  94. errGetKubeSA = "cannot get Kubernetes service account %q: %w"
  95. errGetKubeSASecrets = "cannot find secrets bound to service account: %q"
  96. errGetKubeSANoToken = "cannot find token in secrets bound to service account: %q"
  97. errGetKubeSATokenRequest = "cannot request Kubernetes service account token for service account %q: %w"
  98. errGetKubeSecret = "cannot get Kubernetes secret %q in namespace %q: %w"
  99. errSecretKeyFmt = "cannot find secret data for key: %q"
  100. errConfigMapFmt = "cannot find config map data for key: %q"
  101. errClientTLSAuth = "error from Client TLS Auth: %q"
  102. errVaultRevokeToken = "error while revoking token: %w"
  103. errUnknownCAProvider = "unknown caProvider type given"
  104. errCANamespace = "cannot read secret for CAProvider due to missing namespace on kind ClusterSecretStore"
  105. errInvalidStore = "invalid store"
  106. errInvalidStoreSpec = "invalid store spec"
  107. errInvalidStoreProv = "invalid store provider"
  108. errInvalidVaultProv = "invalid vault provider"
  109. errInvalidAppRoleID = "invalid Auth.AppRole: neither `roleId` nor `roleRef` was supplied"
  110. errInvalidAppRoleRef = "invalid Auth.AppRole.RoleRef: %w"
  111. errInvalidAppRoleSec = "invalid Auth.AppRole.SecretRef: %w"
  112. errInvalidClientCert = "invalid Auth.Cert.ClientCert: %w"
  113. errInvalidCertSec = "invalid Auth.Cert.SecretRef: %w"
  114. errInvalidJwtSec = "invalid Auth.Jwt.SecretRef: %w"
  115. errInvalidJwtK8sSA = "invalid Auth.Jwt.KubernetesServiceAccountToken.ServiceAccountRef: %w"
  116. errInvalidKubeSA = "invalid Auth.Kubernetes.ServiceAccountRef: %w"
  117. errInvalidKubeSec = "invalid Auth.Kubernetes.SecretRef: %w"
  118. errInvalidLdapSec = "invalid Auth.Ldap.SecretRef: %w"
  119. errInvalidTokenRef = "invalid Auth.TokenSecretRef: %w"
  120. errInvalidUserPassSec = "invalid Auth.UserPass.SecretRef: %w"
  121. errInvalidClientTLSCert = "invalid ClientTLS.ClientCert: %w"
  122. errInvalidClientTLSSecret = "invalid ClientTLS.SecretRef: %w"
  123. errInvalidClientTLS = "when provided, both ClientTLS.ClientCert and ClientTLS.SecretRef should be provided"
  124. )
  125. // https://github.com/external-secrets/external-secrets/issues/644
  126. var _ esv1beta1.SecretsClient = &client{}
  127. var _ esv1beta1.Provider = &Connector{}
  128. type client struct {
  129. kube kclient.Client
  130. store *esv1beta1.VaultProvider
  131. log logr.Logger
  132. corev1 typedcorev1.CoreV1Interface
  133. client util.Client
  134. auth util.Auth
  135. logical util.Logical
  136. token util.Token
  137. namespace string
  138. storeKind string
  139. }
  140. func NewVaultClient(c *vault.Config) (util.Client, error) {
  141. cl, err := vault.NewClient(c)
  142. if err != nil {
  143. return nil, err
  144. }
  145. auth := cl.Auth()
  146. logical := cl.Logical()
  147. token := cl.Auth().Token()
  148. out := util.VClient{
  149. SetTokenFunc: cl.SetToken,
  150. TokenFunc: cl.Token,
  151. ClearTokenFunc: cl.ClearToken,
  152. AuthField: auth,
  153. AuthTokenField: token,
  154. LogicalField: logical,
  155. SetNamespaceFunc: cl.SetNamespace,
  156. AddHeaderFunc: cl.AddHeader,
  157. }
  158. return &out, nil
  159. }
  160. func getVaultClient(c *Connector, store esv1beta1.GenericStore, cfg *vault.Config) (util.Client, error) {
  161. isStaticToken := store.GetSpec().Provider.Vault.Auth.TokenSecretRef != nil
  162. useCache := enableCache && !isStaticToken
  163. key := cache.Key{
  164. Name: store.GetObjectMeta().Name,
  165. Namespace: store.GetObjectMeta().Namespace,
  166. Kind: store.GetTypeMeta().Kind,
  167. }
  168. if useCache {
  169. client, ok := clientCache.Get(store.GetObjectMeta().ResourceVersion, key)
  170. if ok {
  171. return client, nil
  172. }
  173. }
  174. client, err := c.NewVaultClient(cfg)
  175. if err != nil {
  176. return nil, fmt.Errorf(errVaultClient, err)
  177. }
  178. if useCache && !clientCache.Contains(key) {
  179. clientCache.Add(store.GetObjectMeta().ResourceVersion, key, client)
  180. }
  181. return client, nil
  182. }
  183. type Connector struct {
  184. NewVaultClient func(c *vault.Config) (util.Client, error)
  185. }
  186. // Capabilities return the provider supported capabilities (ReadOnly, WriteOnly, ReadWrite).
  187. func (c *Connector) Capabilities() esv1beta1.SecretStoreCapabilities {
  188. return esv1beta1.SecretStoreReadWrite
  189. }
  190. func (c *Connector) NewClient(ctx context.Context, store esv1beta1.GenericStore, kube kclient.Client, namespace string) (esv1beta1.SecretsClient, error) {
  191. // controller-runtime/client does not support TokenRequest or other subresource APIs
  192. // so we need to construct our own client and use it to fetch tokens
  193. // (for Kubernetes service account token auth)
  194. restCfg, err := ctrlcfg.GetConfig()
  195. if err != nil {
  196. return nil, err
  197. }
  198. clientset, err := kubernetes.NewForConfig(restCfg)
  199. if err != nil {
  200. return nil, err
  201. }
  202. return c.newClient(ctx, store, kube, clientset.CoreV1(), namespace)
  203. }
  204. func (c *Connector) newClient(ctx context.Context, store esv1beta1.GenericStore, kube kclient.Client, corev1 typedcorev1.CoreV1Interface, namespace string) (esv1beta1.SecretsClient, error) {
  205. storeSpec := store.GetSpec()
  206. if storeSpec == nil || storeSpec.Provider == nil || storeSpec.Provider.Vault == nil {
  207. return nil, errors.New(errVaultStore)
  208. }
  209. vaultSpec := storeSpec.Provider.Vault
  210. vStore, cfg, err := c.prepareConfig(ctx, kube, corev1, vaultSpec, storeSpec.RetrySettings, namespace, store.GetObjectKind().GroupVersionKind().Kind)
  211. if err != nil {
  212. return nil, err
  213. }
  214. client, err := getVaultClient(c, store, cfg)
  215. if err != nil {
  216. return nil, fmt.Errorf(errVaultClient, err)
  217. }
  218. return c.initClient(ctx, vStore, client, cfg, vaultSpec)
  219. }
  220. func (c *Connector) NewGeneratorClient(ctx context.Context, kube kclient.Client, corev1 typedcorev1.CoreV1Interface, vaultSpec *esv1beta1.VaultProvider, namespace string) (util.Client, error) {
  221. vStore, cfg, err := c.prepareConfig(ctx, kube, corev1, vaultSpec, nil, namespace, "Generator")
  222. if err != nil {
  223. return nil, err
  224. }
  225. client, err := c.NewVaultClient(cfg)
  226. if err != nil {
  227. return nil, err
  228. }
  229. _, err = c.initClient(ctx, vStore, client, cfg, vaultSpec)
  230. if err != nil {
  231. return nil, err
  232. }
  233. return client, nil
  234. }
  235. func (c *Connector) prepareConfig(ctx context.Context, kube kclient.Client, corev1 typedcorev1.CoreV1Interface, vaultSpec *esv1beta1.VaultProvider, retrySettings *esv1beta1.SecretStoreRetrySettings, namespace, storeKind string) (*client, *vault.Config, error) {
  236. vStore := &client{
  237. kube: kube,
  238. corev1: corev1,
  239. store: vaultSpec,
  240. log: logger,
  241. namespace: namespace,
  242. storeKind: storeKind,
  243. }
  244. cfg, err := vStore.newConfig(ctx)
  245. if err != nil {
  246. return nil, nil, err
  247. }
  248. // Setup retry options if present
  249. if retrySettings != nil {
  250. if retrySettings.MaxRetries != nil {
  251. cfg.MaxRetries = int(*retrySettings.MaxRetries)
  252. } else {
  253. // By default we rely only on the reconciliation process for retrying
  254. cfg.MaxRetries = 0
  255. }
  256. if retrySettings.RetryInterval != nil {
  257. retryWait, err := time.ParseDuration(*retrySettings.RetryInterval)
  258. if err != nil {
  259. return nil, nil, err
  260. }
  261. cfg.MinRetryWait = retryWait
  262. cfg.MaxRetryWait = retryWait
  263. }
  264. }
  265. return vStore, cfg, nil
  266. }
  267. func (c *Connector) initClient(ctx context.Context, vStore *client, client util.Client, cfg *vault.Config, vaultSpec *esv1beta1.VaultProvider) (esv1beta1.SecretsClient, error) {
  268. if vaultSpec.Namespace != nil {
  269. client.SetNamespace(*vaultSpec.Namespace)
  270. }
  271. if vaultSpec.ReadYourWrites && vaultSpec.ForwardInconsistent {
  272. client.AddHeader("X-Vault-Inconsistent", "forward-active-node")
  273. }
  274. vStore.client = client
  275. vStore.auth = client.Auth()
  276. vStore.logical = client.Logical()
  277. vStore.token = client.AuthToken()
  278. // allow SecretStore controller validation to pass
  279. // when using referent namespace.
  280. if vStore.storeKind == esv1beta1.ClusterSecretStoreKind && vStore.namespace == "" && isReferentSpec(vaultSpec) {
  281. return vStore, nil
  282. }
  283. if err := vStore.setAuth(ctx, cfg); err != nil {
  284. return nil, err
  285. }
  286. return vStore, nil
  287. }
  288. func (c *Connector) ValidateStore(store esv1beta1.GenericStore) error {
  289. if store == nil {
  290. return fmt.Errorf(errInvalidStore)
  291. }
  292. spc := store.GetSpec()
  293. if spc == nil {
  294. return fmt.Errorf(errInvalidStoreSpec)
  295. }
  296. if spc.Provider == nil {
  297. return fmt.Errorf(errInvalidStoreProv)
  298. }
  299. p := spc.Provider.Vault
  300. if p == nil {
  301. return fmt.Errorf(errInvalidVaultProv)
  302. }
  303. if p.Auth.AppRole != nil {
  304. // check SecretRef for valid configuration
  305. if err := utils.ValidateReferentSecretSelector(store, p.Auth.AppRole.SecretRef); err != nil {
  306. return fmt.Errorf(errInvalidAppRoleSec, err)
  307. }
  308. // prefer .auth.appRole.roleId, fallback to .auth.appRole.roleRef, give up after that.
  309. if p.Auth.AppRole.RoleID == "" { // prevents further RoleID tests if .auth.appRole.roleId is given
  310. if p.Auth.AppRole.RoleRef != nil { // check RoleRef for valid configuration
  311. if err := utils.ValidateReferentSecretSelector(store, *p.Auth.AppRole.RoleRef); err != nil {
  312. return fmt.Errorf(errInvalidAppRoleRef, err)
  313. }
  314. } else { // we ran out of ways to get RoleID. return an appropriate error
  315. return fmt.Errorf(errInvalidAppRoleID)
  316. }
  317. }
  318. }
  319. if p.Auth.Cert != nil {
  320. if err := utils.ValidateReferentSecretSelector(store, p.Auth.Cert.ClientCert); err != nil {
  321. return fmt.Errorf(errInvalidClientCert, err)
  322. }
  323. if err := utils.ValidateReferentSecretSelector(store, p.Auth.Cert.SecretRef); err != nil {
  324. return fmt.Errorf(errInvalidCertSec, err)
  325. }
  326. }
  327. if p.Auth.Jwt != nil {
  328. if p.Auth.Jwt.SecretRef != nil {
  329. if err := utils.ValidateReferentSecretSelector(store, *p.Auth.Jwt.SecretRef); err != nil {
  330. return fmt.Errorf(errInvalidJwtSec, err)
  331. }
  332. } else if p.Auth.Jwt.KubernetesServiceAccountToken != nil {
  333. if err := utils.ValidateReferentServiceAccountSelector(store, p.Auth.Jwt.KubernetesServiceAccountToken.ServiceAccountRef); err != nil {
  334. return fmt.Errorf(errInvalidJwtK8sSA, err)
  335. }
  336. } else {
  337. return fmt.Errorf(errJwtNoTokenSource)
  338. }
  339. }
  340. if p.Auth.Kubernetes != nil {
  341. if p.Auth.Kubernetes.ServiceAccountRef != nil {
  342. if err := utils.ValidateReferentServiceAccountSelector(store, *p.Auth.Kubernetes.ServiceAccountRef); err != nil {
  343. return fmt.Errorf(errInvalidKubeSA, err)
  344. }
  345. }
  346. if p.Auth.Kubernetes.SecretRef != nil {
  347. if err := utils.ValidateReferentSecretSelector(store, *p.Auth.Kubernetes.SecretRef); err != nil {
  348. return fmt.Errorf(errInvalidKubeSec, err)
  349. }
  350. }
  351. }
  352. if p.Auth.Ldap != nil {
  353. if err := utils.ValidateReferentSecretSelector(store, p.Auth.Ldap.SecretRef); err != nil {
  354. return fmt.Errorf(errInvalidLdapSec, err)
  355. }
  356. }
  357. if p.Auth.UserPass != nil {
  358. if err := utils.ValidateReferentSecretSelector(store, p.Auth.UserPass.SecretRef); err != nil {
  359. return fmt.Errorf(errInvalidUserPassSec, err)
  360. }
  361. }
  362. if p.Auth.TokenSecretRef != nil {
  363. if err := utils.ValidateReferentSecretSelector(store, *p.Auth.TokenSecretRef); err != nil {
  364. return fmt.Errorf(errInvalidTokenRef, err)
  365. }
  366. }
  367. if p.Auth.Iam != nil {
  368. if p.Auth.Iam.JWTAuth != nil {
  369. if p.Auth.Iam.JWTAuth.ServiceAccountRef != nil {
  370. if err := utils.ValidateReferentServiceAccountSelector(store, *p.Auth.Iam.JWTAuth.ServiceAccountRef); err != nil {
  371. return fmt.Errorf(errInvalidTokenRef, err)
  372. }
  373. }
  374. }
  375. if p.Auth.Iam.SecretRef != nil {
  376. if err := utils.ValidateReferentSecretSelector(store, p.Auth.Iam.SecretRef.AccessKeyID); err != nil {
  377. return fmt.Errorf(errInvalidTokenRef, err)
  378. }
  379. if err := utils.ValidateReferentSecretSelector(store, p.Auth.Iam.SecretRef.SecretAccessKey); err != nil {
  380. return fmt.Errorf(errInvalidTokenRef, err)
  381. }
  382. if p.Auth.Iam.SecretRef.SessionToken != nil {
  383. if err := utils.ValidateReferentSecretSelector(store, *p.Auth.Iam.SecretRef.SessionToken); err != nil {
  384. return fmt.Errorf(errInvalidTokenRef, err)
  385. }
  386. }
  387. }
  388. }
  389. if p.ClientTLS.CertSecretRef != nil && p.ClientTLS.KeySecretRef != nil {
  390. if err := utils.ValidateReferentSecretSelector(store, *p.ClientTLS.CertSecretRef); err != nil {
  391. return fmt.Errorf(errInvalidClientTLSCert, err)
  392. }
  393. if err := utils.ValidateReferentSecretSelector(store, *p.ClientTLS.KeySecretRef); err != nil {
  394. return fmt.Errorf(errInvalidClientTLSSecret, err)
  395. }
  396. } else if p.ClientTLS.CertSecretRef != nil || p.ClientTLS.KeySecretRef != nil {
  397. return errors.New(errInvalidClientTLS)
  398. }
  399. return nil
  400. }
  401. func (v *client) DeleteSecret(ctx context.Context, remoteRef esv1beta1.PushSecretRemoteRef) error {
  402. path := v.buildPath(remoteRef.GetRemoteKey())
  403. metaPath, err := v.buildMetadataPath(remoteRef.GetRemoteKey())
  404. if err != nil {
  405. return err
  406. }
  407. // Retrieve the secret map from vault and convert the secret value in string form.
  408. secretVal, err := v.readSecret(ctx, path, "")
  409. // If error is not of type secret not found, we should error
  410. if err != nil && errors.Is(err, esv1beta1.NoSecretError{}) {
  411. return nil
  412. }
  413. if err != nil {
  414. return err
  415. }
  416. metadata, err := v.readSecretMetadata(ctx, remoteRef.GetRemoteKey())
  417. if err != nil {
  418. return err
  419. }
  420. manager, ok := metadata["managed-by"]
  421. if !ok || manager != "external-secrets" {
  422. return nil
  423. }
  424. // If Push for a Property, we need to delete the property and update the secret
  425. if remoteRef.GetProperty() != "" {
  426. delete(secretVal, remoteRef.GetProperty())
  427. // If the only key left in the remote secret is the reference of the metadata.
  428. if v.store.Version == esv1beta1.VaultKVStoreV1 && len(secretVal) == 1 {
  429. delete(secretVal, "custom_metadata")
  430. }
  431. if len(secretVal) > 0 {
  432. secretToPush := secretVal
  433. if v.store.Version == esv1beta1.VaultKVStoreV2 {
  434. secretToPush = map[string]interface{}{
  435. "data": secretVal,
  436. }
  437. }
  438. _, err = v.logical.WriteWithContext(ctx, path, secretToPush)
  439. metrics.ObserveAPICall(constants.ProviderHCVault, constants.CallHCVaultDeleteSecret, err)
  440. return err
  441. }
  442. }
  443. _, err = v.logical.DeleteWithContext(ctx, path)
  444. metrics.ObserveAPICall(constants.ProviderHCVault, constants.CallHCVaultDeleteSecret, err)
  445. if err != nil {
  446. return fmt.Errorf("could not delete secret %v: %w", remoteRef.GetRemoteKey(), err)
  447. }
  448. if v.store.Version == esv1beta1.VaultKVStoreV2 {
  449. _, err = v.logical.DeleteWithContext(ctx, metaPath)
  450. metrics.ObserveAPICall(constants.ProviderHCVault, constants.CallHCVaultDeleteSecret, err)
  451. if err != nil {
  452. return fmt.Errorf("could not delete secret metadata %v: %w", remoteRef.GetRemoteKey(), err)
  453. }
  454. }
  455. return nil
  456. }
  457. func (v *client) PushSecret(ctx context.Context, secret *corev1.Secret, data esv1beta1.PushSecretData) error {
  458. value := secret.Data[data.GetSecretKey()]
  459. label := map[string]interface{}{
  460. "custom_metadata": map[string]string{
  461. "managed-by": "external-secrets",
  462. },
  463. }
  464. secretVal := make(map[string]interface{})
  465. path := v.buildPath(data.GetRemoteKey())
  466. metaPath, err := v.buildMetadataPath(data.GetRemoteKey())
  467. if err != nil {
  468. return err
  469. }
  470. // Retrieve the secret map from vault and convert the secret value in string form.
  471. vaultSecret, err := v.readSecret(ctx, path, "")
  472. // If error is not of type secret not found, we should error
  473. if err != nil && !errors.Is(err, esv1beta1.NoSecretError{}) {
  474. return err
  475. }
  476. // If the secret exists (err == nil), we should check if it is managed by external-secrets
  477. if err == nil {
  478. metadata, err := v.readSecretMetadata(ctx, data.GetRemoteKey())
  479. if err != nil {
  480. return err
  481. }
  482. manager, ok := metadata["managed-by"]
  483. if !ok || manager != "external-secrets" {
  484. return fmt.Errorf("secret not managed by external-secrets")
  485. }
  486. }
  487. // Remove the metadata map to check the reconcile difference
  488. if v.store.Version == esv1beta1.VaultKVStoreV1 {
  489. delete(vaultSecret, "custom_metadata")
  490. }
  491. buf := &bytes.Buffer{}
  492. enc := json.NewEncoder(buf)
  493. enc.SetEscapeHTML(false)
  494. err = enc.Encode(vaultSecret)
  495. if err != nil {
  496. return fmt.Errorf("error encoding vault secret: %w", err)
  497. }
  498. vaultSecretValue := bytes.TrimSpace(buf.Bytes())
  499. if err != nil {
  500. return fmt.Errorf("error marshaling vault secret: %w", err)
  501. }
  502. if bytes.Equal(vaultSecretValue, value) {
  503. return nil
  504. }
  505. // If a Push of a property only, we should merge and add/update the property
  506. if data.GetProperty() != "" {
  507. if _, ok := vaultSecret[data.GetProperty()]; ok {
  508. d := vaultSecret[data.GetProperty()].(string)
  509. if err != nil {
  510. return fmt.Errorf("error marshaling vault secret: %w", err)
  511. }
  512. // If the property has the same value, don't update the secret
  513. if bytes.Equal([]byte(d), value) {
  514. return nil
  515. }
  516. }
  517. for k, v := range vaultSecret {
  518. secretVal[k] = v
  519. }
  520. // Secret got from vault is already on map[string]string format
  521. secretVal[data.GetProperty()] = string(value)
  522. } else {
  523. err = json.Unmarshal(value, &secretVal)
  524. if err != nil {
  525. return fmt.Errorf("error unmarshalling vault secret: %w", err)
  526. }
  527. }
  528. secretToPush := secretVal
  529. // Adding custom_metadata to the secret for KV v1
  530. if v.store.Version == esv1beta1.VaultKVStoreV1 {
  531. secretToPush["custom_metadata"] = label["custom_metadata"]
  532. }
  533. if v.store.Version == esv1beta1.VaultKVStoreV2 {
  534. secretToPush = map[string]interface{}{
  535. "data": secretVal,
  536. }
  537. }
  538. if err != nil {
  539. return fmt.Errorf("failed to convert value to a valid JSON: %w", err)
  540. }
  541. // Secret metadata should be pushed separately only for KV2
  542. if v.store.Version == esv1beta1.VaultKVStoreV2 {
  543. _, err = v.logical.WriteWithContext(ctx, metaPath, label)
  544. metrics.ObserveAPICall(constants.ProviderHCVault, constants.CallHCVaultWriteSecretData, err)
  545. if err != nil {
  546. return err
  547. }
  548. }
  549. // Otherwise, create or update the version.
  550. _, err = v.logical.WriteWithContext(ctx, path, secretToPush)
  551. metrics.ObserveAPICall(constants.ProviderHCVault, constants.CallHCVaultWriteSecretData, err)
  552. return err
  553. }
  554. // GetAllSecrets gets multiple secrets from the provider and loads into a kubernetes secret.
  555. // First load all secrets from secretStore path configuration
  556. // Then, gets secrets from a matching name or matching custom_metadata.
  557. func (v *client) GetAllSecrets(ctx context.Context, ref esv1beta1.ExternalSecretFind) (map[string][]byte, error) {
  558. if v.store.Version == esv1beta1.VaultKVStoreV1 {
  559. return nil, errors.New(errUnsupportedKvVersion)
  560. }
  561. searchPath := ""
  562. if ref.Path != nil {
  563. searchPath = *ref.Path + "/"
  564. }
  565. potentialSecrets, err := v.listSecrets(ctx, searchPath)
  566. if err != nil {
  567. return nil, err
  568. }
  569. if ref.Name != nil {
  570. return v.findSecretsFromName(ctx, potentialSecrets, *ref.Name)
  571. }
  572. return v.findSecretsFromTags(ctx, potentialSecrets, ref.Tags)
  573. }
  574. func (v *client) findSecretsFromTags(ctx context.Context, candidates []string, tags map[string]string) (map[string][]byte, error) {
  575. secrets := make(map[string][]byte)
  576. for _, name := range candidates {
  577. match := true
  578. metadata, err := v.readSecretMetadata(ctx, name)
  579. if err != nil {
  580. return nil, err
  581. }
  582. for tk, tv := range tags {
  583. p, ok := metadata[tk]
  584. if !ok || p != tv {
  585. match = false
  586. break
  587. }
  588. }
  589. if match {
  590. secret, err := v.GetSecret(ctx, esv1beta1.ExternalSecretDataRemoteRef{Key: name})
  591. if errors.Is(err, esv1beta1.NoSecretError{}) {
  592. continue
  593. }
  594. if err != nil {
  595. return nil, err
  596. }
  597. if secret != nil {
  598. secrets[name] = secret
  599. }
  600. }
  601. }
  602. return secrets, nil
  603. }
  604. func (v *client) findSecretsFromName(ctx context.Context, candidates []string, ref esv1beta1.FindName) (map[string][]byte, error) {
  605. secrets := make(map[string][]byte)
  606. matcher, err := find.New(ref)
  607. if err != nil {
  608. return nil, err
  609. }
  610. for _, name := range candidates {
  611. ok := matcher.MatchName(name)
  612. if ok {
  613. secret, err := v.GetSecret(ctx, esv1beta1.ExternalSecretDataRemoteRef{Key: name})
  614. if errors.Is(err, esv1beta1.NoSecretError{}) {
  615. continue
  616. }
  617. if err != nil {
  618. return nil, err
  619. }
  620. if secret != nil {
  621. secrets[name] = secret
  622. }
  623. }
  624. }
  625. return secrets, nil
  626. }
  627. func (v *client) listSecrets(ctx context.Context, path string) ([]string, error) {
  628. secrets := make([]string, 0)
  629. url, err := v.buildMetadataPath(path)
  630. if err != nil {
  631. return nil, err
  632. }
  633. secret, err := v.logical.ListWithContext(ctx, url)
  634. metrics.ObserveAPICall(constants.ProviderHCVault, constants.CallHCVaultListSecrets, err)
  635. if err != nil {
  636. return nil, fmt.Errorf(errReadSecret, err)
  637. }
  638. if secret == nil {
  639. return nil, fmt.Errorf("provided path %v does not contain any secrets", url)
  640. }
  641. t, ok := secret.Data["keys"]
  642. if !ok {
  643. return nil, nil
  644. }
  645. paths := t.([]interface{})
  646. for _, p := range paths {
  647. strPath := p.(string)
  648. fullPath := path + strPath // because path always ends with a /
  649. if path == "" {
  650. fullPath = strPath
  651. }
  652. // Recurrently find secrets
  653. if !strings.HasSuffix(p.(string), "/") {
  654. secrets = append(secrets, fullPath)
  655. } else {
  656. partial, err := v.listSecrets(ctx, fullPath)
  657. if err != nil {
  658. return nil, err
  659. }
  660. secrets = append(secrets, partial...)
  661. }
  662. }
  663. return secrets, nil
  664. }
  665. func (v *client) readSecretMetadata(ctx context.Context, path string) (map[string]string, error) {
  666. metadata := make(map[string]string)
  667. url, err := v.buildMetadataPath(path)
  668. if err != nil {
  669. return nil, err
  670. }
  671. secret, err := v.logical.ReadWithDataWithContext(ctx, url, nil)
  672. metrics.ObserveAPICall(constants.ProviderHCVault, constants.CallHCVaultReadSecretData, err)
  673. if err != nil {
  674. return nil, fmt.Errorf(errReadSecret, err)
  675. }
  676. if secret == nil {
  677. return nil, errors.New(errNotFound)
  678. }
  679. t, ok := secret.Data["custom_metadata"]
  680. if !ok {
  681. return nil, nil
  682. }
  683. d, ok := t.(map[string]interface{})
  684. if !ok {
  685. return metadata, nil
  686. }
  687. for k, v := range d {
  688. metadata[k] = v.(string)
  689. }
  690. return metadata, nil
  691. }
  692. // GetSecret supports two types:
  693. // 1. get the full secret as json-encoded value
  694. // by leaving the ref.Property empty.
  695. // 2. get a key from the secret.
  696. // Nested values are supported by specifying a gjson expression
  697. func (v *client) GetSecret(ctx context.Context, ref esv1beta1.ExternalSecretDataRemoteRef) ([]byte, error) {
  698. var data map[string]interface{}
  699. var err error
  700. if ref.MetadataPolicy == esv1beta1.ExternalSecretMetadataPolicyFetch {
  701. if v.store.Version == esv1beta1.VaultKVStoreV1 {
  702. return nil, errors.New(errUnsupportedMetadataKvVersion)
  703. }
  704. metadata, err := v.readSecretMetadata(ctx, ref.Key)
  705. if err != nil {
  706. return nil, err
  707. }
  708. if len(metadata) == 0 {
  709. return nil, nil
  710. }
  711. data = make(map[string]interface{}, len(metadata))
  712. for k, v := range metadata {
  713. data[k] = v
  714. }
  715. } else {
  716. data, err = v.readSecret(ctx, ref.Key, ref.Version)
  717. if err != nil {
  718. return nil, err
  719. }
  720. }
  721. // Return nil if secret value is null
  722. if data == nil {
  723. return nil, esv1beta1.NoSecretError{}
  724. }
  725. jsonStr, err := json.Marshal(data)
  726. if err != nil {
  727. return nil, err
  728. }
  729. // (1): return raw json if no property is defined
  730. if ref.Property == "" {
  731. return jsonStr, nil
  732. }
  733. // For backwards compatibility we want the
  734. // actual keys to take precedence over gjson syntax
  735. // (2): extract key from secret with property
  736. if _, ok := data[ref.Property]; ok {
  737. return utils.GetByteValueFromMap(data, ref.Property)
  738. }
  739. // (3): extract key from secret using gjson
  740. val := gjson.Get(string(jsonStr), ref.Property)
  741. if !val.Exists() {
  742. return nil, fmt.Errorf(errSecretKeyFmt, ref.Property)
  743. }
  744. return []byte(val.String()), nil
  745. }
  746. // GetSecretMap supports two modes of operation:
  747. // 1. get the full secret from the vault data payload (by leaving .property empty).
  748. // 2. extract key/value pairs from a (nested) object.
  749. func (v *client) GetSecretMap(ctx context.Context, ref esv1beta1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
  750. data, err := v.GetSecret(ctx, ref)
  751. if err != nil {
  752. return nil, err
  753. }
  754. var secretData map[string]interface{}
  755. err = json.Unmarshal(data, &secretData)
  756. if err != nil {
  757. return nil, err
  758. }
  759. byteMap := make(map[string][]byte, len(secretData))
  760. for k := range secretData {
  761. byteMap[k], err = utils.GetByteValueFromMap(secretData, k)
  762. if err != nil {
  763. return nil, err
  764. }
  765. }
  766. return byteMap, nil
  767. }
  768. func (v *client) Close(ctx context.Context) error {
  769. // Revoke the token if we have one set, it wasn't sourced from a TokenSecretRef,
  770. // and token caching isn't enabled
  771. if !enableCache && v.client.Token() != "" && v.store.Auth.TokenSecretRef == nil {
  772. err := revokeTokenIfValid(ctx, v.client)
  773. if err != nil {
  774. return err
  775. }
  776. }
  777. return nil
  778. }
  779. func isReferentSpec(prov *esv1beta1.VaultProvider) bool {
  780. if prov.Auth.TokenSecretRef != nil && prov.Auth.TokenSecretRef.Namespace == nil {
  781. return true
  782. }
  783. if prov.Auth.AppRole != nil && prov.Auth.AppRole.SecretRef.Namespace == nil {
  784. return true
  785. }
  786. if prov.Auth.Kubernetes != nil && prov.Auth.Kubernetes.SecretRef != nil && prov.Auth.Kubernetes.SecretRef.Namespace == nil {
  787. return true
  788. }
  789. if prov.Auth.Kubernetes != nil && prov.Auth.Kubernetes.ServiceAccountRef != nil && prov.Auth.Kubernetes.ServiceAccountRef.Namespace == nil {
  790. return true
  791. }
  792. if prov.Auth.Ldap != nil && prov.Auth.Ldap.SecretRef.Namespace == nil {
  793. return true
  794. }
  795. if prov.Auth.UserPass != nil && prov.Auth.UserPass.SecretRef.Namespace == nil {
  796. return true
  797. }
  798. if prov.Auth.Jwt != nil && prov.Auth.Jwt.SecretRef != nil && prov.Auth.Jwt.SecretRef.Namespace == nil {
  799. return true
  800. }
  801. if prov.Auth.Jwt != nil && prov.Auth.Jwt.KubernetesServiceAccountToken != nil && prov.Auth.Jwt.KubernetesServiceAccountToken.ServiceAccountRef.Namespace == nil {
  802. return true
  803. }
  804. if prov.Auth.Cert != nil && prov.Auth.Cert.SecretRef.Namespace == nil {
  805. return true
  806. }
  807. if prov.Auth.Iam != nil && prov.Auth.Iam.JWTAuth != nil && prov.Auth.Iam.JWTAuth.ServiceAccountRef != nil && prov.Auth.Iam.JWTAuth.ServiceAccountRef.Namespace == nil {
  808. return true
  809. }
  810. if prov.Auth.Iam != nil && prov.Auth.Iam.SecretRef != nil &&
  811. (prov.Auth.Iam.SecretRef.AccessKeyID.Namespace == nil ||
  812. prov.Auth.Iam.SecretRef.SecretAccessKey.Namespace == nil ||
  813. (prov.Auth.Iam.SecretRef.SessionToken != nil && prov.Auth.Iam.SecretRef.SessionToken.Namespace == nil)) {
  814. return true
  815. }
  816. return false
  817. }
  818. func (v *client) Validate() (esv1beta1.ValidationResult, error) {
  819. // when using referent namespace we can not validate the token
  820. // because the namespace is not known yet when Validate() is called
  821. // from the SecretStore controller.
  822. if v.storeKind == esv1beta1.ClusterSecretStoreKind && isReferentSpec(v.store) {
  823. return esv1beta1.ValidationResultUnknown, nil
  824. }
  825. _, err := checkToken(context.Background(), v.token)
  826. if err != nil {
  827. return esv1beta1.ValidationResultError, fmt.Errorf(errInvalidCredentials, err)
  828. }
  829. return esv1beta1.ValidationResultReady, nil
  830. }
  831. func (v *client) buildMetadataPath(path string) (string, error) {
  832. var url string
  833. if v.store.Version == esv1beta1.VaultKVStoreV1 {
  834. url = fmt.Sprintf("%s/%s", *v.store.Path, path)
  835. } else { // KV v2 is used
  836. if v.store.Path == nil && !strings.Contains(path, "data") {
  837. return "", fmt.Errorf(errPathInvalid)
  838. }
  839. if v.store.Path == nil {
  840. path = strings.Replace(path, "data", "metadata", 1)
  841. url = path
  842. } else {
  843. url = fmt.Sprintf("%s/metadata/%s", *v.store.Path, path)
  844. }
  845. }
  846. return url, nil
  847. }
  848. /*
  849. buildPath is a helper method to build the vault equivalent path
  850. from ExternalSecrets and SecretStore manifests. the path build logic
  851. varies depending on the SecretStore KV version:
  852. Example inputs/outputs:
  853. # simple build:
  854. kv version == "v2":
  855. provider_path: "secret/path"
  856. input: "foo"
  857. output: "secret/path/data/foo" # provider_path and data are prepended
  858. kv version == "v1":
  859. provider_path: "secret/path"
  860. input: "foo"
  861. output: "secret/path/foo" # provider_path is prepended
  862. # inheriting paths:
  863. kv version == "v2":
  864. provider_path: "secret/path"
  865. input: "secret/path/foo"
  866. output: "secret/path/data/foo" #data is prepended
  867. kv version == "v2":
  868. provider_path: "secret/path"
  869. input: "secret/path/data/foo"
  870. output: "secret/path/data/foo" #noop
  871. kv version == "v1":
  872. provider_path: "secret/path"
  873. input: "secret/path/foo"
  874. output: "secret/path/foo" #noop
  875. # provider path not defined:
  876. kv version == "v2":
  877. provider_path: nil
  878. input: "secret/path/foo"
  879. output: "secret/data/path/foo" # data is prepended to secret/
  880. kv version == "v2":
  881. provider_path: nil
  882. input: "secret/path/data/foo"
  883. output: "secret/path/data/foo" #noop
  884. kv version == "v1":
  885. provider_path: nil
  886. input: "secret/path/foo"
  887. output: "secret/path/foo" #noop
  888. */
  889. func (v *client) buildPath(path string) string {
  890. optionalMount := v.store.Path
  891. out := path
  892. // if optionalMount is Set, remove it from path if its there
  893. if optionalMount != nil {
  894. cut := *optionalMount + "/"
  895. if strings.HasPrefix(out, cut) {
  896. // This current logic induces a bug when the actual secret resides on same path names as the mount path.
  897. _, out, _ = strings.Cut(out, cut)
  898. // if data succeeds optionalMount on v2 store, we should remove it as well
  899. if strings.HasPrefix(out, "data/") && v.store.Version == esv1beta1.VaultKVStoreV2 {
  900. _, out, _ = strings.Cut(out, "data/")
  901. }
  902. }
  903. buildPath := strings.Split(out, "/")
  904. buildMount := strings.Split(*optionalMount, "/")
  905. if v.store.Version == esv1beta1.VaultKVStoreV2 {
  906. buildMount = append(buildMount, "data")
  907. }
  908. buildMount = append(buildMount, buildPath...)
  909. out = strings.Join(buildMount, "/")
  910. return out
  911. }
  912. if !strings.Contains(out, "/data/") && v.store.Version == esv1beta1.VaultKVStoreV2 {
  913. buildPath := strings.Split(out, "/")
  914. buildMount := []string{buildPath[0], "data"}
  915. buildMount = append(buildMount, buildPath[1:]...)
  916. out = strings.Join(buildMount, "/")
  917. return out
  918. }
  919. return out
  920. }
  921. func (v *client) readSecret(ctx context.Context, path, version string) (map[string]interface{}, error) {
  922. dataPath := v.buildPath(path)
  923. // path formated according to vault docs for v1 and v2 API
  924. // v1: https://www.vaultproject.io/api-docs/secret/kv/kv-v1#read-secret
  925. // v2: https://www.vaultproject.io/api/secret/kv/kv-v2#read-secret-version
  926. var params map[string][]string
  927. if version != "" {
  928. params = make(map[string][]string)
  929. params["version"] = []string{version}
  930. }
  931. vaultSecret, err := v.logical.ReadWithDataWithContext(ctx, dataPath, params)
  932. metrics.ObserveAPICall(constants.ProviderHCVault, constants.CallHCVaultReadSecretData, err)
  933. if err != nil {
  934. return nil, fmt.Errorf(errReadSecret, err)
  935. }
  936. if vaultSecret == nil {
  937. return nil, esv1beta1.NoSecretError{}
  938. }
  939. secretData := vaultSecret.Data
  940. if v.store.Version == esv1beta1.VaultKVStoreV2 {
  941. // Vault KV2 has data embedded within sub-field
  942. // reference - https://www.vaultproject.io/api/secret/kv/kv-v2#read-secret-version
  943. dataInt, ok := vaultSecret.Data["data"]
  944. if !ok {
  945. return nil, errors.New(errDataField)
  946. }
  947. if dataInt == nil {
  948. return nil, esv1beta1.NoSecretError{}
  949. }
  950. secretData, ok = dataInt.(map[string]interface{})
  951. if !ok {
  952. return nil, errors.New(errJSONUnmarshall)
  953. }
  954. }
  955. return secretData, nil
  956. }
  957. func (v *client) newConfig(ctx context.Context) (*vault.Config, error) {
  958. cfg := vault.DefaultConfig()
  959. cfg.Address = v.store.Server
  960. if len(v.store.CABundle) != 0 || v.store.CAProvider != nil {
  961. caCertPool := x509.NewCertPool()
  962. if len(v.store.CABundle) > 0 {
  963. ok := caCertPool.AppendCertsFromPEM(v.store.CABundle)
  964. if !ok {
  965. return nil, fmt.Errorf(errVaultCert, errors.New("failed to parse certificates from CertPool"))
  966. }
  967. }
  968. if v.store.CAProvider != nil && v.storeKind == esv1beta1.ClusterSecretStoreKind && v.store.CAProvider.Namespace == nil {
  969. return nil, errors.New(errCANamespace)
  970. }
  971. if v.store.CAProvider != nil {
  972. var cert []byte
  973. var err error
  974. switch v.store.CAProvider.Type {
  975. case esv1beta1.CAProviderTypeSecret:
  976. cert, err = getCertFromSecret(v)
  977. case esv1beta1.CAProviderTypeConfigMap:
  978. cert, err = getCertFromConfigMap(v)
  979. default:
  980. return nil, errors.New(errUnknownCAProvider)
  981. }
  982. if err != nil {
  983. return nil, err
  984. }
  985. ok := caCertPool.AppendCertsFromPEM(cert)
  986. if !ok {
  987. return nil, fmt.Errorf(errVaultCert, errors.New("failed to parse certificates from CertPool"))
  988. }
  989. }
  990. if transport, ok := cfg.HttpClient.Transport.(*http.Transport); ok {
  991. transport.TLSClientConfig.RootCAs = caCertPool
  992. }
  993. }
  994. err := v.configureClientTLS(ctx, cfg)
  995. if err != nil {
  996. return nil, err
  997. }
  998. // If either read-after-write consistency feature is enabled, enable ReadYourWrites
  999. cfg.ReadYourWrites = v.store.ReadYourWrites || v.store.ForwardInconsistent
  1000. return cfg, nil
  1001. }
  1002. func (v *client) configureClientTLS(ctx context.Context, cfg *vault.Config) error {
  1003. clientTLS := v.store.ClientTLS
  1004. if clientTLS.CertSecretRef != nil && clientTLS.KeySecretRef != nil {
  1005. if clientTLS.KeySecretRef.Key == "" {
  1006. clientTLS.KeySecretRef.Key = corev1.TLSPrivateKeyKey
  1007. }
  1008. clientKey, err := v.secretKeyRef(ctx, clientTLS.KeySecretRef)
  1009. if err != nil {
  1010. return err
  1011. }
  1012. if clientTLS.CertSecretRef.Key == "" {
  1013. clientTLS.CertSecretRef.Key = corev1.TLSCertKey
  1014. }
  1015. clientCert, err := v.secretKeyRef(ctx, clientTLS.CertSecretRef)
  1016. if err != nil {
  1017. return err
  1018. }
  1019. cert, err := tls.X509KeyPair([]byte(clientCert), []byte(clientKey))
  1020. if err != nil {
  1021. return fmt.Errorf(errClientTLSAuth, err)
  1022. }
  1023. if transport, ok := cfg.HttpClient.Transport.(*http.Transport); ok {
  1024. transport.TLSClientConfig.Certificates = []tls.Certificate{cert}
  1025. }
  1026. }
  1027. return nil
  1028. }
  1029. func getCertFromSecret(v *client) ([]byte, error) {
  1030. secretRef := esmeta.SecretKeySelector{
  1031. Name: v.store.CAProvider.Name,
  1032. Namespace: &v.namespace,
  1033. Key: v.store.CAProvider.Key,
  1034. }
  1035. if v.store.CAProvider.Namespace != nil {
  1036. secretRef.Namespace = v.store.CAProvider.Namespace
  1037. }
  1038. ctx := context.Background()
  1039. res, err := v.secretKeyRef(ctx, &secretRef)
  1040. if err != nil {
  1041. return nil, fmt.Errorf(errVaultCert, err)
  1042. }
  1043. return []byte(res), nil
  1044. }
  1045. func getCertFromConfigMap(v *client) ([]byte, error) {
  1046. objKey := types.NamespacedName{
  1047. Name: v.store.CAProvider.Name,
  1048. Namespace: v.namespace,
  1049. }
  1050. if v.store.CAProvider.Namespace != nil {
  1051. objKey.Namespace = *v.store.CAProvider.Namespace
  1052. }
  1053. configMapRef := &corev1.ConfigMap{}
  1054. ctx := context.Background()
  1055. err := v.kube.Get(ctx, objKey, configMapRef)
  1056. if err != nil {
  1057. return nil, fmt.Errorf(errVaultCert, err)
  1058. }
  1059. val, ok := configMapRef.Data[v.store.CAProvider.Key]
  1060. if !ok {
  1061. return nil, fmt.Errorf(errConfigMapFmt, v.store.CAProvider.Key)
  1062. }
  1063. return []byte(val), nil
  1064. }
  1065. /*
  1066. setAuth gets a new token using the configured mechanism.
  1067. If there's already a valid token, does nothing.
  1068. */
  1069. func (v *client) setAuth(ctx context.Context, cfg *vault.Config) error {
  1070. tokenExists := false
  1071. var err error
  1072. if v.client.Token() != "" {
  1073. tokenExists, err = checkToken(ctx, v.token)
  1074. }
  1075. if tokenExists {
  1076. v.log.V(1).Info("Re-using existing token")
  1077. return err
  1078. }
  1079. tokenExists, err = setSecretKeyToken(ctx, v)
  1080. if tokenExists {
  1081. v.log.V(1).Info("Set token from secret")
  1082. return err
  1083. }
  1084. tokenExists, err = setAppRoleToken(ctx, v)
  1085. if tokenExists {
  1086. v.log.V(1).Info("Retrieved new token using AppRole auth")
  1087. return err
  1088. }
  1089. tokenExists, err = setKubernetesAuthToken(ctx, v)
  1090. if tokenExists {
  1091. v.log.V(1).Info("Retrieved new token using Kubernetes auth")
  1092. return err
  1093. }
  1094. tokenExists, err = setLdapAuthToken(ctx, v)
  1095. if tokenExists {
  1096. v.log.V(1).Info("Retrieved new token using LDAP auth")
  1097. return err
  1098. }
  1099. tokenExists, err = setUserPassAuthToken(ctx, v)
  1100. if tokenExists {
  1101. v.log.V(1).Info("Retrieved new token using userPass auth")
  1102. return err
  1103. }
  1104. tokenExists, err = setJwtAuthToken(ctx, v)
  1105. if tokenExists {
  1106. v.log.V(1).Info("Retrieved new token using JWT auth")
  1107. return err
  1108. }
  1109. tokenExists, err = setCertAuthToken(ctx, v, cfg)
  1110. if tokenExists {
  1111. v.log.V(1).Info("Retrieved new token using certificate auth")
  1112. return err
  1113. }
  1114. tokenExists, err = setIamAuthToken(ctx, v, vaultiamauth.DefaultJWTProvider, vaultiamauth.DefaultSTSProvider)
  1115. if tokenExists {
  1116. v.log.V(1).Info("Retrieved new token using IAM auth")
  1117. return err
  1118. }
  1119. return errors.New(errAuthFormat)
  1120. }
  1121. func setSecretKeyToken(ctx context.Context, v *client) (bool, error) {
  1122. tokenRef := v.store.Auth.TokenSecretRef
  1123. if tokenRef != nil {
  1124. token, err := v.secretKeyRef(ctx, tokenRef)
  1125. if err != nil {
  1126. return true, err
  1127. }
  1128. v.client.SetToken(token)
  1129. return true, nil
  1130. }
  1131. return false, nil
  1132. }
  1133. func setAppRoleToken(ctx context.Context, v *client) (bool, error) {
  1134. appRole := v.store.Auth.AppRole
  1135. if appRole != nil {
  1136. err := v.requestTokenWithAppRoleRef(ctx, appRole)
  1137. if err != nil {
  1138. return true, err
  1139. }
  1140. return true, nil
  1141. }
  1142. return false, nil
  1143. }
  1144. func setKubernetesAuthToken(ctx context.Context, v *client) (bool, error) {
  1145. kubernetesAuth := v.store.Auth.Kubernetes
  1146. if kubernetesAuth != nil {
  1147. err := v.requestTokenWithKubernetesAuth(ctx, kubernetesAuth)
  1148. if err != nil {
  1149. return true, err
  1150. }
  1151. return true, nil
  1152. }
  1153. return false, nil
  1154. }
  1155. func setLdapAuthToken(ctx context.Context, v *client) (bool, error) {
  1156. ldapAuth := v.store.Auth.Ldap
  1157. if ldapAuth != nil {
  1158. err := v.requestTokenWithLdapAuth(ctx, ldapAuth)
  1159. if err != nil {
  1160. return true, err
  1161. }
  1162. return true, nil
  1163. }
  1164. return false, nil
  1165. }
  1166. func setUserPassAuthToken(ctx context.Context, v *client) (bool, error) {
  1167. userPassAuth := v.store.Auth.UserPass
  1168. if userPassAuth != nil {
  1169. err := v.requestTokenWithUserPassAuth(ctx, userPassAuth)
  1170. if err != nil {
  1171. return true, err
  1172. }
  1173. return true, nil
  1174. }
  1175. return false, nil
  1176. }
  1177. func setJwtAuthToken(ctx context.Context, v *client) (bool, error) {
  1178. jwtAuth := v.store.Auth.Jwt
  1179. if jwtAuth != nil {
  1180. err := v.requestTokenWithJwtAuth(ctx, jwtAuth)
  1181. if err != nil {
  1182. return true, err
  1183. }
  1184. return true, nil
  1185. }
  1186. return false, nil
  1187. }
  1188. func setCertAuthToken(ctx context.Context, v *client, cfg *vault.Config) (bool, error) {
  1189. certAuth := v.store.Auth.Cert
  1190. if certAuth != nil {
  1191. err := v.requestTokenWithCertAuth(ctx, certAuth, cfg)
  1192. if err != nil {
  1193. return true, err
  1194. }
  1195. return true, nil
  1196. }
  1197. return false, nil
  1198. }
  1199. func setIamAuthToken(ctx context.Context, v *client, jwtProvider util.JwtProviderFactory, assumeRoler vaultiamauth.STSProvider) (bool, error) {
  1200. iamAuth := v.store.Auth.Iam
  1201. isClusterKind := v.storeKind == esv1beta1.ClusterSecretStoreKind
  1202. if iamAuth != nil {
  1203. err := v.requestTokenWithIamAuth(ctx, iamAuth, isClusterKind, v.kube, v.namespace, jwtProvider, assumeRoler)
  1204. if err != nil {
  1205. return true, err
  1206. }
  1207. return true, nil
  1208. }
  1209. return false, nil
  1210. }
  1211. func (v *client) secretKeyRefForServiceAccount(ctx context.Context, serviceAccountRef *esmeta.ServiceAccountSelector) (string, error) {
  1212. serviceAccount := &corev1.ServiceAccount{}
  1213. ref := types.NamespacedName{
  1214. Namespace: v.namespace,
  1215. Name: serviceAccountRef.Name,
  1216. }
  1217. if (v.storeKind == esv1beta1.ClusterSecretStoreKind) &&
  1218. (serviceAccountRef.Namespace != nil) {
  1219. ref.Namespace = *serviceAccountRef.Namespace
  1220. }
  1221. err := v.kube.Get(ctx, ref, serviceAccount)
  1222. if err != nil {
  1223. return "", fmt.Errorf(errGetKubeSA, ref.Name, err)
  1224. }
  1225. if len(serviceAccount.Secrets) == 0 {
  1226. return "", fmt.Errorf(errGetKubeSASecrets, ref.Name)
  1227. }
  1228. for _, tokenRef := range serviceAccount.Secrets {
  1229. retval, err := v.secretKeyRef(ctx, &esmeta.SecretKeySelector{
  1230. Name: tokenRef.Name,
  1231. Namespace: &ref.Namespace,
  1232. Key: "token",
  1233. })
  1234. if err != nil {
  1235. continue
  1236. }
  1237. return retval, nil
  1238. }
  1239. return "", fmt.Errorf(errGetKubeSANoToken, ref.Name)
  1240. }
  1241. func (v *client) secretKeyRef(ctx context.Context, secretRef *esmeta.SecretKeySelector) (string, error) {
  1242. secret := &corev1.Secret{}
  1243. ref := types.NamespacedName{
  1244. Namespace: v.namespace,
  1245. Name: secretRef.Name,
  1246. }
  1247. if (v.storeKind == esv1beta1.ClusterSecretStoreKind) &&
  1248. (secretRef.Namespace != nil) {
  1249. ref.Namespace = *secretRef.Namespace
  1250. }
  1251. err := v.kube.Get(ctx, ref, secret)
  1252. if err != nil {
  1253. return "", fmt.Errorf(errGetKubeSecret, ref.Name, ref.Namespace, err)
  1254. }
  1255. keyBytes, ok := secret.Data[secretRef.Key]
  1256. if !ok {
  1257. return "", fmt.Errorf(errSecretKeyFmt, secretRef.Key)
  1258. }
  1259. value := string(keyBytes)
  1260. valueStr := strings.TrimSpace(value)
  1261. return valueStr, nil
  1262. }
  1263. func (v *client) serviceAccountToken(ctx context.Context, serviceAccountRef esmeta.ServiceAccountSelector, additionalAud []string, expirationSeconds int64) (string, error) {
  1264. audiences := serviceAccountRef.Audiences
  1265. if len(additionalAud) > 0 {
  1266. audiences = append(audiences, additionalAud...)
  1267. }
  1268. tokenRequest := &authenticationv1.TokenRequest{
  1269. ObjectMeta: metav1.ObjectMeta{
  1270. Namespace: v.namespace,
  1271. },
  1272. Spec: authenticationv1.TokenRequestSpec{
  1273. Audiences: audiences,
  1274. ExpirationSeconds: &expirationSeconds,
  1275. },
  1276. }
  1277. if (v.storeKind == esv1beta1.ClusterSecretStoreKind) &&
  1278. (serviceAccountRef.Namespace != nil) {
  1279. tokenRequest.Namespace = *serviceAccountRef.Namespace
  1280. }
  1281. tokenResponse, err := v.corev1.ServiceAccounts(tokenRequest.Namespace).CreateToken(ctx, serviceAccountRef.Name, tokenRequest, metav1.CreateOptions{})
  1282. if err != nil {
  1283. return "", fmt.Errorf(errGetKubeSATokenRequest, serviceAccountRef.Name, err)
  1284. }
  1285. return tokenResponse.Status.Token, nil
  1286. }
  1287. // checkToken does a lookup and checks if the provided token exists.
  1288. func checkToken(ctx context.Context, token util.Token) (bool, error) {
  1289. // https://www.vaultproject.io/api-docs/auth/token#lookup-a-token-self
  1290. resp, err := token.LookupSelfWithContext(ctx)
  1291. metrics.ObserveAPICall(constants.ProviderHCVault, constants.CallHCVaultLookupSelf, err)
  1292. if err != nil {
  1293. return false, err
  1294. }
  1295. t, ok := resp.Data["type"]
  1296. if !ok {
  1297. return false, fmt.Errorf("could not assert token type")
  1298. }
  1299. tokenType := t.(string)
  1300. if tokenType == "batch" {
  1301. return false, nil
  1302. }
  1303. return true, nil
  1304. }
  1305. func revokeTokenIfValid(ctx context.Context, client util.Client) error {
  1306. valid, err := checkToken(ctx, client.AuthToken())
  1307. if err != nil {
  1308. return fmt.Errorf(errVaultRevokeToken, err)
  1309. }
  1310. if valid {
  1311. err = client.AuthToken().RevokeSelfWithContext(ctx, client.Token())
  1312. metrics.ObserveAPICall(constants.ProviderHCVault, constants.CallHCVaultRevokeSelf, err)
  1313. if err != nil {
  1314. return fmt.Errorf(errVaultRevokeToken, err)
  1315. }
  1316. client.ClearToken()
  1317. }
  1318. return nil
  1319. }
  1320. func (v *client) requestTokenWithAppRoleRef(ctx context.Context, appRole *esv1beta1.VaultAppRole) error {
  1321. var err error
  1322. var roleID string // becomes the RoleID used to authenticate with HashiCorp Vault
  1323. // prefer .auth.appRole.roleId, fallback to .auth.appRole.roleRef, give up after that.
  1324. if appRole.RoleID != "" { // use roleId from CRD, if configured
  1325. roleID = strings.TrimSpace(appRole.RoleID)
  1326. } else if appRole.RoleRef != nil { // use RoleID from Secret, if configured
  1327. roleID, err = v.secretKeyRef(ctx, appRole.RoleRef)
  1328. if err != nil {
  1329. return err
  1330. }
  1331. } else { // we ran out of ways to get RoleID. return an appropriate error
  1332. return fmt.Errorf(errInvalidAppRoleID)
  1333. }
  1334. secretID, err := v.secretKeyRef(ctx, &appRole.SecretRef)
  1335. if err != nil {
  1336. return err
  1337. }
  1338. secret := approle.SecretID{FromString: secretID}
  1339. appRoleClient, err := approle.NewAppRoleAuth(roleID, &secret, approle.WithMountPath(appRole.Path))
  1340. if err != nil {
  1341. return err
  1342. }
  1343. _, err = v.auth.Login(ctx, appRoleClient)
  1344. metrics.ObserveAPICall(constants.ProviderHCVault, constants.CallHCVaultLogin, err)
  1345. if err != nil {
  1346. return err
  1347. }
  1348. return nil
  1349. }
  1350. func (v *client) requestTokenWithKubernetesAuth(ctx context.Context, kubernetesAuth *esv1beta1.VaultKubernetesAuth) error {
  1351. jwtString, err := getJwtString(ctx, v, kubernetesAuth)
  1352. if err != nil {
  1353. return err
  1354. }
  1355. k, err := authkubernetes.NewKubernetesAuth(kubernetesAuth.Role, authkubernetes.WithServiceAccountToken(jwtString), authkubernetes.WithMountPath(kubernetesAuth.Path))
  1356. if err != nil {
  1357. return err
  1358. }
  1359. _, err = v.auth.Login(ctx, k)
  1360. metrics.ObserveAPICall(constants.ProviderHCVault, constants.CallHCVaultLogin, err)
  1361. if err != nil {
  1362. return err
  1363. }
  1364. return nil
  1365. }
  1366. func getJwtString(ctx context.Context, v *client, kubernetesAuth *esv1beta1.VaultKubernetesAuth) (string, error) {
  1367. if kubernetesAuth.ServiceAccountRef != nil {
  1368. // Kubernetes <v1.24 fetch token via ServiceAccount.Secrets[]
  1369. // this behavior was removed in v1.24 and we must use TokenRequest API (see below)
  1370. jwt, err := v.secretKeyRefForServiceAccount(ctx, kubernetesAuth.ServiceAccountRef)
  1371. if jwt != "" {
  1372. return jwt, err
  1373. }
  1374. if err != nil {
  1375. v.log.V(1).Info("unable to fetch jwt from service account secret, trying service account token next")
  1376. }
  1377. // Kubernetes >=v1.24: fetch token via TokenRequest API
  1378. // note: this is a massive change from vault perspective: the `iss` claim will very likely change.
  1379. // Vault 1.9 deprecated issuer validation by default, and authentication with Vault clusters <1.9 will likely fail.
  1380. jwt, err = v.serviceAccountToken(ctx, *kubernetesAuth.ServiceAccountRef, nil, 600)
  1381. if err != nil {
  1382. return "", err
  1383. }
  1384. return jwt, nil
  1385. } else if kubernetesAuth.SecretRef != nil {
  1386. tokenRef := kubernetesAuth.SecretRef
  1387. if tokenRef.Key == "" {
  1388. tokenRef = kubernetesAuth.SecretRef.DeepCopy()
  1389. tokenRef.Key = "token"
  1390. }
  1391. jwt, err := v.secretKeyRef(ctx, tokenRef)
  1392. if err != nil {
  1393. return "", err
  1394. }
  1395. return jwt, nil
  1396. } else {
  1397. // Kubernetes authentication is specified, but without a referenced
  1398. // Kubernetes secret. We check if the file path for in-cluster service account
  1399. // exists and attempt to use the token for Vault Kubernetes auth.
  1400. if _, err := os.Stat(serviceAccTokenPath); err != nil {
  1401. return "", fmt.Errorf(errServiceAccount, err)
  1402. }
  1403. jwtByte, err := os.ReadFile(serviceAccTokenPath)
  1404. if err != nil {
  1405. return "", fmt.Errorf(errServiceAccount, err)
  1406. }
  1407. return string(jwtByte), nil
  1408. }
  1409. }
  1410. func (v *client) requestTokenWithLdapAuth(ctx context.Context, ldapAuth *esv1beta1.VaultLdapAuth) error {
  1411. username := strings.TrimSpace(ldapAuth.Username)
  1412. password, err := v.secretKeyRef(ctx, &ldapAuth.SecretRef)
  1413. if err != nil {
  1414. return err
  1415. }
  1416. pass := authldap.Password{FromString: password}
  1417. l, err := authldap.NewLDAPAuth(username, &pass, authldap.WithMountPath(ldapAuth.Path))
  1418. if err != nil {
  1419. return err
  1420. }
  1421. _, err = v.auth.Login(ctx, l)
  1422. metrics.ObserveAPICall(constants.ProviderHCVault, constants.CallHCVaultLogin, err)
  1423. if err != nil {
  1424. return err
  1425. }
  1426. return nil
  1427. }
  1428. func (v *client) requestTokenWithUserPassAuth(ctx context.Context, userPassAuth *esv1beta1.VaultUserPassAuth) error {
  1429. username := strings.TrimSpace(userPassAuth.Username)
  1430. password, err := v.secretKeyRef(ctx, &userPassAuth.SecretRef)
  1431. if err != nil {
  1432. return err
  1433. }
  1434. pass := authuserpass.Password{FromString: password}
  1435. l, err := authuserpass.NewUserpassAuth(username, &pass, authuserpass.WithMountPath(userPassAuth.Path))
  1436. if err != nil {
  1437. return err
  1438. }
  1439. _, err = v.auth.Login(ctx, l)
  1440. metrics.ObserveAPICall(constants.ProviderHCVault, constants.CallHCVaultLogin, err)
  1441. if err != nil {
  1442. return err
  1443. }
  1444. return nil
  1445. }
  1446. func (v *client) requestTokenWithJwtAuth(ctx context.Context, jwtAuth *esv1beta1.VaultJwtAuth) error {
  1447. role := strings.TrimSpace(jwtAuth.Role)
  1448. var jwt string
  1449. var err error
  1450. if jwtAuth.SecretRef != nil {
  1451. jwt, err = v.secretKeyRef(ctx, jwtAuth.SecretRef)
  1452. } else if k8sServiceAccountToken := jwtAuth.KubernetesServiceAccountToken; k8sServiceAccountToken != nil {
  1453. audiences := k8sServiceAccountToken.Audiences
  1454. if audiences == nil {
  1455. audiences = &[]string{"vault"}
  1456. }
  1457. expirationSeconds := k8sServiceAccountToken.ExpirationSeconds
  1458. if expirationSeconds == nil {
  1459. tmp := int64(600)
  1460. expirationSeconds = &tmp
  1461. }
  1462. jwt, err = v.serviceAccountToken(ctx, k8sServiceAccountToken.ServiceAccountRef, *audiences, *expirationSeconds)
  1463. } else {
  1464. err = fmt.Errorf(errJwtNoTokenSource)
  1465. }
  1466. if err != nil {
  1467. return err
  1468. }
  1469. parameters := map[string]interface{}{
  1470. "role": role,
  1471. "jwt": jwt,
  1472. }
  1473. url := strings.Join([]string{"auth", jwtAuth.Path, "login"}, "/")
  1474. vaultResult, err := v.logical.WriteWithContext(ctx, url, parameters)
  1475. metrics.ObserveAPICall(constants.ProviderHCVault, constants.CallHCVaultWriteSecretData, err)
  1476. if err != nil {
  1477. return err
  1478. }
  1479. token, err := vaultResult.TokenID()
  1480. if err != nil {
  1481. return fmt.Errorf(errVaultToken, err)
  1482. }
  1483. v.client.SetToken(token)
  1484. return nil
  1485. }
  1486. func (v *client) requestTokenWithCertAuth(ctx context.Context, certAuth *esv1beta1.VaultCertAuth, cfg *vault.Config) error {
  1487. clientKey, err := v.secretKeyRef(ctx, &certAuth.SecretRef)
  1488. if err != nil {
  1489. return err
  1490. }
  1491. clientCert, err := v.secretKeyRef(ctx, &certAuth.ClientCert)
  1492. if err != nil {
  1493. return err
  1494. }
  1495. cert, err := tls.X509KeyPair([]byte(clientCert), []byte(clientKey))
  1496. if err != nil {
  1497. return fmt.Errorf(errClientTLSAuth, err)
  1498. }
  1499. if transport, ok := cfg.HttpClient.Transport.(*http.Transport); ok {
  1500. transport.TLSClientConfig.Certificates = []tls.Certificate{cert}
  1501. }
  1502. url := strings.Join([]string{"auth", "cert", "login"}, "/")
  1503. vaultResult, err := v.logical.WriteWithContext(ctx, url, nil)
  1504. metrics.ObserveAPICall(constants.ProviderHCVault, constants.CallHCVaultWriteSecretData, err)
  1505. if err != nil {
  1506. return fmt.Errorf(errVaultRequest, err)
  1507. }
  1508. token, err := vaultResult.TokenID()
  1509. if err != nil {
  1510. return fmt.Errorf(errVaultToken, err)
  1511. }
  1512. v.client.SetToken(token)
  1513. return nil
  1514. }
  1515. func (v *client) requestTokenWithIamAuth(ctx context.Context, iamAuth *esv1beta1.VaultIamAuth, ick bool, k kclient.Client, n string, jwtProvider util.JwtProviderFactory, assumeRoler vaultiamauth.STSProvider) error {
  1516. jwtAuth := iamAuth.JWTAuth
  1517. secretRefAuth := iamAuth.SecretRef
  1518. regionAWS := defaultAWSRegion
  1519. awsAuthMountPath := defaultAWSAuthMountPath
  1520. if iamAuth.Region != "" {
  1521. regionAWS = iamAuth.Region
  1522. }
  1523. if iamAuth.Path != "" {
  1524. awsAuthMountPath = iamAuth.Path
  1525. }
  1526. var creds *credentials.Credentials
  1527. var err error
  1528. if jwtAuth != nil { // use credentials from a sa explicitly defined and referenced. Highest preference is given to this method/configuration.
  1529. creds, err = vaultiamauth.CredsFromServiceAccount(ctx, *iamAuth, regionAWS, ick, k, n, jwtProvider)
  1530. if err != nil {
  1531. return err
  1532. }
  1533. } else if secretRefAuth != nil { // if jwtAuth is not defined, check if secretRef is defined. Second preference.
  1534. logger.V(1).Info("using credentials from secretRef")
  1535. creds, err = vaultiamauth.CredsFromSecretRef(ctx, *iamAuth, ick, k, n)
  1536. if err != nil {
  1537. return err
  1538. }
  1539. }
  1540. // Neither of jwtAuth or secretRefAuth defined. Last preference.
  1541. // Default to controller pod's identity
  1542. if jwtAuth == nil && secretRefAuth == nil {
  1543. // Checking if controller pod's service account is IRSA enabled and Web Identity token is available on pod
  1544. tknFile, tknFileEnvVarPresent := os.LookupEnv(vaultiamauth.AWSWebIdentityTokenFileEnvVar)
  1545. if !tknFileEnvVarPresent {
  1546. return fmt.Errorf(errIrsaTokenEnvVarNotFoundOnPod, vaultiamauth.AWSWebIdentityTokenFileEnvVar) // No Web Identity(IRSA) token found on pod
  1547. }
  1548. // IRSA enabled service account, let's check that the jwt token filemount and file exists
  1549. if _, err := os.Stat(tknFile); err != nil {
  1550. return fmt.Errorf(errIrsaTokenFileNotFoundOnPod, tknFile, err)
  1551. }
  1552. // everything looks good so far, let's fetch the jwt token from AWS_WEB_IDENTITY_TOKEN_FILE
  1553. jwtByte, err := os.ReadFile(tknFile)
  1554. if err != nil {
  1555. return fmt.Errorf(errIrsaTokenFileNotReadable, tknFile, err)
  1556. }
  1557. // let's parse the jwt token
  1558. parser := jwt.NewParser(jwt.WithoutClaimsValidation())
  1559. token, _, err := parser.ParseUnverified(string(jwtByte), jwt.MapClaims{})
  1560. if err != nil {
  1561. return fmt.Errorf(errIrsaTokenNotValidJWT, tknFile, err) // JWT token parser error
  1562. }
  1563. var ns string
  1564. var sa string
  1565. // let's fetch the namespace and serviceaccount from parsed jwt token
  1566. if claims, ok := token.Claims.(jwt.MapClaims); ok {
  1567. ns = claims["kubernetes.io"].(map[string]interface{})["namespace"].(string)
  1568. sa = claims["kubernetes.io"].(map[string]interface{})["serviceaccount"].(map[string]interface{})["name"].(string)
  1569. } else {
  1570. return fmt.Errorf(errPodInfoNotFoundOnToken, tknFile, err)
  1571. }
  1572. creds, err = vaultiamauth.CredsFromControllerServiceAccount(ctx, sa, ns, regionAWS, k, jwtProvider)
  1573. if err != nil {
  1574. return err
  1575. }
  1576. }
  1577. config := aws.NewConfig().WithEndpointResolver(vaultiamauth.ResolveEndpoint())
  1578. if creds != nil {
  1579. config.WithCredentials(creds)
  1580. }
  1581. if regionAWS != "" {
  1582. config.WithRegion(regionAWS)
  1583. }
  1584. sess, err := vaultiamauth.GetAWSSession(config)
  1585. if err != nil {
  1586. return err
  1587. }
  1588. if iamAuth.AWSIAMRole != "" {
  1589. stsclient := assumeRoler(sess)
  1590. if iamAuth.ExternalID != "" {
  1591. var setExternalID = func(p *stscreds.AssumeRoleProvider) {
  1592. p.ExternalID = aws.String(iamAuth.ExternalID)
  1593. }
  1594. sess.Config.WithCredentials(stscreds.NewCredentialsWithClient(stsclient, iamAuth.AWSIAMRole, setExternalID))
  1595. } else {
  1596. sess.Config.WithCredentials(stscreds.NewCredentialsWithClient(stsclient, iamAuth.AWSIAMRole))
  1597. }
  1598. }
  1599. getCreds, err := sess.Config.Credentials.Get()
  1600. if err != nil {
  1601. return err
  1602. }
  1603. // Set environment variables. These would be fetched by Login
  1604. os.Setenv("AWS_ACCESS_KEY_ID", getCreds.AccessKeyID)
  1605. os.Setenv("AWS_SECRET_ACCESS_KEY", getCreds.SecretAccessKey)
  1606. os.Setenv("AWS_SESSION_TOKEN", getCreds.SessionToken)
  1607. var awsAuthClient *authaws.AWSAuth
  1608. if iamAuth.VaultAWSIAMServerID != "" {
  1609. awsAuthClient, err = authaws.NewAWSAuth(authaws.WithRegion(regionAWS), authaws.WithIAMAuth(), authaws.WithRole(iamAuth.Role), authaws.WithMountPath(awsAuthMountPath), authaws.WithIAMServerIDHeader(iamAuth.VaultAWSIAMServerID))
  1610. if err != nil {
  1611. return err
  1612. }
  1613. } else {
  1614. awsAuthClient, err = authaws.NewAWSAuth(authaws.WithRegion(regionAWS), authaws.WithIAMAuth(), authaws.WithRole(iamAuth.Role), authaws.WithMountPath(awsAuthMountPath))
  1615. if err != nil {
  1616. return err
  1617. }
  1618. }
  1619. _, err = v.auth.Login(ctx, awsAuthClient)
  1620. metrics.ObserveAPICall(constants.ProviderHCVault, constants.CallHCVaultLogin, err)
  1621. if err != nil {
  1622. return err
  1623. }
  1624. return nil
  1625. }
  1626. func init() {
  1627. var vaultTokenCacheSize int
  1628. fs := pflag.NewFlagSet("vault", pflag.ExitOnError)
  1629. fs.BoolVar(&enableCache, "experimental-enable-vault-token-cache", false, "Enable experimental Vault token cache. External secrets will reuse the Vault token without creating a new one on each request.")
  1630. // max. 265k vault leases with 30bytes each ~= 7MB
  1631. fs.IntVar(&vaultTokenCacheSize, "experimental-vault-token-cache-size", 2<<17, "Maximum size of Vault token cache. When more tokens than Only used if --experimental-enable-vault-token-cache is set.")
  1632. lateInit := func() {
  1633. logger.Info("initializing vault cache", "size", vaultTokenCacheSize)
  1634. clientCache = cache.Must(vaultTokenCacheSize, func(client util.Client) {
  1635. err := revokeTokenIfValid(context.Background(), client)
  1636. if err != nil {
  1637. logger.Error(err, "unable to revoke cached token on eviction")
  1638. }
  1639. })
  1640. }
  1641. feature.Register(feature.Feature{
  1642. Flags: fs,
  1643. Initialize: lateInit,
  1644. })
  1645. esv1beta1.Register(&Connector{
  1646. NewVaultClient: NewVaultClient,
  1647. }, &esv1beta1.SecretStoreProvider{
  1648. Vault: &esv1beta1.VaultProvider{},
  1649. })
  1650. }