vault.go 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415
  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. "context"
  15. "crypto/tls"
  16. "crypto/x509"
  17. "encoding/json"
  18. "errors"
  19. "fmt"
  20. "net/http"
  21. "os"
  22. "strconv"
  23. "strings"
  24. "github.com/go-logr/logr"
  25. vault "github.com/hashicorp/vault/api"
  26. approle "github.com/hashicorp/vault/api/auth/approle"
  27. authkubernetes "github.com/hashicorp/vault/api/auth/kubernetes"
  28. authldap "github.com/hashicorp/vault/api/auth/ldap"
  29. "github.com/tidwall/gjson"
  30. authenticationv1 "k8s.io/api/authentication/v1"
  31. corev1 "k8s.io/api/core/v1"
  32. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  33. "k8s.io/apimachinery/pkg/types"
  34. "k8s.io/client-go/kubernetes"
  35. typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
  36. ctrl "sigs.k8s.io/controller-runtime"
  37. kclient "sigs.k8s.io/controller-runtime/pkg/client"
  38. ctrlcfg "sigs.k8s.io/controller-runtime/pkg/client/config"
  39. esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
  40. esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
  41. "github.com/external-secrets/external-secrets/pkg/find"
  42. "github.com/external-secrets/external-secrets/pkg/utils"
  43. )
  44. var (
  45. _ esv1beta1.Provider = &connector{}
  46. _ esv1beta1.SecretsClient = &client{}
  47. EnableCache bool
  48. VaultClientCache clientCache
  49. )
  50. const (
  51. serviceAccTokenPath = "/var/run/secrets/kubernetes.io/serviceaccount/token"
  52. errVaultStore = "received invalid Vault SecretStore resource: %w"
  53. errVaultCacheCreate = "cannot create Vault client cache: %s"
  54. errVaultCacheRemove = "error removing item from Vault client cache: %w"
  55. errVaultCacheEviction = "unexpected eviction from Vault client cache"
  56. errVaultClient = "cannot setup new vault client: %w"
  57. errVaultCert = "cannot set Vault CA certificate: %w"
  58. errReadSecret = "cannot read secret data from Vault: %w"
  59. errAuthFormat = "cannot initialize Vault client: no valid auth method specified"
  60. errInvalidCredentials = "invalid vault credentials: %w"
  61. errDataField = "failed to find data field"
  62. errJSONUnmarshall = "failed to unmarshall JSON"
  63. errPathInvalid = "provided Path isn't a valid kv v2 path"
  64. errSecretFormat = "secret data not in expected format"
  65. errUnexpectedKey = "unexpected key in data: %s"
  66. errVaultToken = "cannot parse Vault authentication token: %w"
  67. errVaultRequest = "error from Vault request: %w"
  68. errServiceAccount = "cannot read Kubernetes service account token from file system: %w"
  69. errJwtNoTokenSource = "neither `secretRef` nor `kubernetesServiceAccountToken` was supplied as token source for jwt authentication"
  70. errUnsupportedKvVersion = "cannot perform find operations with kv version v1"
  71. errNotFound = "secret not found"
  72. errGetKubeSA = "cannot get Kubernetes service account %q: %w"
  73. errGetKubeSASecrets = "cannot find secrets bound to service account: %q"
  74. errGetKubeSANoToken = "cannot find token in secrets bound to service account: %q"
  75. errGetKubeSATokenRequest = "cannot request Kubernetes service account token for service account %q: %w"
  76. errGetKubeSecret = "cannot get Kubernetes secret %q: %w"
  77. errSecretKeyFmt = "cannot find secret data for key: %q"
  78. errConfigMapFmt = "cannot find config map data for key: %q"
  79. errClientTLSAuth = "error from Client TLS Auth: %q"
  80. errVaultRevokeToken = "error while revoking token: %w"
  81. errUnknownCAProvider = "unknown caProvider type given"
  82. errCANamespace = "cannot read secret for CAProvider due to missing namespace on kind ClusterSecretStore"
  83. errInvalidStore = "invalid store"
  84. errInvalidStoreSpec = "invalid store spec"
  85. errInvalidStoreProv = "invalid store provider"
  86. errInvalidVaultProv = "invalid vault provider"
  87. errInvalidAppRoleSec = "invalid Auth.AppRole.SecretRef: %w"
  88. errInvalidClientCert = "invalid Auth.Cert.ClientCert: %w"
  89. errInvalidCertSec = "invalid Auth.Cert.SecretRef: %w"
  90. errInvalidJwtSec = "invalid Auth.Jwt.SecretRef: %w"
  91. errInvalidJwtK8sSA = "invalid Auth.Jwt.KubernetesServiceAccountToken.ServiceAccountRef: %w"
  92. errInvalidKubeSA = "invalid Auth.Kubernetes.ServiceAccountRef: %w"
  93. errInvalidKubeSec = "invalid Auth.Kubernetes.SecretRef: %w"
  94. errInvalidLdapSec = "invalid Auth.Ldap.SecretRef: %w"
  95. errInvalidTokenRef = "invalid Auth.TokenSecretRef: %w"
  96. )
  97. // https://github.com/external-secrets/external-secrets/issues/644
  98. var _ esv1beta1.SecretsClient = &client{}
  99. var _ esv1beta1.Provider = &connector{}
  100. type Auth interface {
  101. Login(ctx context.Context, authMethod vault.AuthMethod) (*vault.Secret, error)
  102. }
  103. type Token interface {
  104. RevokeSelfWithContext(ctx context.Context, token string) error
  105. LookupSelfWithContext(ctx context.Context) (*vault.Secret, error)
  106. }
  107. type Logical interface {
  108. ReadWithDataWithContext(ctx context.Context, path string, data map[string][]string) (*vault.Secret, error)
  109. ListWithContext(ctx context.Context, path string) (*vault.Secret, error)
  110. WriteWithContext(ctx context.Context, path string, data map[string]interface{}) (*vault.Secret, error)
  111. DeleteWithContext(ctx context.Context, path string) (*vault.Secret, error)
  112. }
  113. type Client interface {
  114. SetToken(v string)
  115. Token() string
  116. ClearToken()
  117. Auth() Auth
  118. Logical() Logical
  119. AuthToken() Token
  120. SetNamespace(namespace string)
  121. AddHeader(key, value string)
  122. }
  123. type VClient struct {
  124. setToken func(v string)
  125. token func() string
  126. clearToken func()
  127. auth Auth
  128. logical Logical
  129. authToken Token
  130. setNamespace func(namespace string)
  131. addHeader func(key, value string)
  132. }
  133. func (v VClient) AddHeader(key, value string) {
  134. v.addHeader(key, value)
  135. }
  136. func (v VClient) SetNamespace(namespace string) {
  137. v.setNamespace(namespace)
  138. }
  139. func (v VClient) ClearToken() {
  140. v.clearToken()
  141. }
  142. func (v VClient) Token() string {
  143. return v.token()
  144. }
  145. func (v VClient) SetToken(token string) {
  146. v.setToken(token)
  147. }
  148. func (v VClient) Auth() Auth {
  149. return v.auth
  150. }
  151. func (v VClient) AuthToken() Token {
  152. return v.authToken
  153. }
  154. func (v VClient) Logical() Logical {
  155. return v.logical
  156. }
  157. type client struct {
  158. kube kclient.Client
  159. store *esv1beta1.VaultProvider
  160. log logr.Logger
  161. corev1 typedcorev1.CoreV1Interface
  162. client Client
  163. auth Auth
  164. logical Logical
  165. token Token
  166. namespace string
  167. storeKind string
  168. }
  169. func init() {
  170. esv1beta1.Register(&connector{
  171. newVaultClient: newVaultClient,
  172. }, &esv1beta1.SecretStoreProvider{
  173. Vault: &esv1beta1.VaultProvider{},
  174. })
  175. }
  176. func newVaultClient(c *vault.Config) (Client, error) {
  177. cl, err := vault.NewClient(c)
  178. if err != nil {
  179. return nil, err
  180. }
  181. auth := cl.Auth()
  182. logical := cl.Logical()
  183. token := cl.Auth().Token()
  184. out := VClient{
  185. setToken: cl.SetToken,
  186. token: cl.Token,
  187. clearToken: cl.ClearToken,
  188. auth: auth,
  189. authToken: token,
  190. logical: logical,
  191. setNamespace: cl.SetNamespace,
  192. addHeader: cl.AddHeader,
  193. }
  194. return out, nil
  195. }
  196. func getVaultClient(ctx context.Context, c *connector, store esv1beta1.GenericStore, cfg *vault.Config) (Client, error) {
  197. isStaticToken := store.GetSpec().Provider.Vault.Auth.TokenSecretRef != nil
  198. useCache := EnableCache && !isStaticToken
  199. if useCache {
  200. VaultClientCache.lock()
  201. defer VaultClientCache.unlock()
  202. err := VaultClientCache.initialize()
  203. if err != nil {
  204. return nil, err
  205. }
  206. }
  207. key := clientCacheKey{
  208. Name: store.GetObjectMeta().Name,
  209. Namespace: store.GetObjectMeta().Namespace,
  210. Kind: store.GetTypeMeta().Kind,
  211. }
  212. if useCache {
  213. client, ok, err := VaultClientCache.get(ctx, store, key)
  214. if err != nil {
  215. return nil, err
  216. }
  217. if ok {
  218. return client, nil
  219. }
  220. }
  221. client, err := c.newVaultClient(cfg)
  222. if err != nil {
  223. return nil, fmt.Errorf(errVaultClient, err)
  224. }
  225. if useCache && !VaultClientCache.contains(key) {
  226. err = VaultClientCache.add(ctx, store, key, client)
  227. if err != nil {
  228. return nil, err
  229. }
  230. }
  231. return client, nil
  232. }
  233. type connector struct {
  234. newVaultClient func(c *vault.Config) (Client, error)
  235. }
  236. // Capabilities return the provider supported capabilities (ReadOnly, WriteOnly, ReadWrite).
  237. func (c *connector) Capabilities() esv1beta1.SecretStoreCapabilities {
  238. return esv1beta1.SecretStoreReadWrite
  239. }
  240. func (c *connector) NewClient(ctx context.Context, store esv1beta1.GenericStore, kube kclient.Client, namespace string) (esv1beta1.SecretsClient, error) {
  241. // controller-runtime/client does not support TokenRequest or other subresource APIs
  242. // so we need to construct our own client and use it to fetch tokens
  243. // (for Kubernetes service account token auth)
  244. restCfg, err := ctrlcfg.GetConfig()
  245. if err != nil {
  246. return nil, err
  247. }
  248. clientset, err := kubernetes.NewForConfig(restCfg)
  249. if err != nil {
  250. return nil, err
  251. }
  252. return c.newClient(ctx, store, kube, clientset.CoreV1(), namespace)
  253. }
  254. func (c *connector) newClient(ctx context.Context, store esv1beta1.GenericStore, kube kclient.Client, corev1 typedcorev1.CoreV1Interface, namespace string) (esv1beta1.SecretsClient, error) {
  255. storeSpec := store.GetSpec()
  256. if storeSpec == nil || storeSpec.Provider == nil || storeSpec.Provider.Vault == nil {
  257. return nil, errors.New(errVaultStore)
  258. }
  259. vaultSpec := storeSpec.Provider.Vault
  260. vStore := &client{
  261. kube: kube,
  262. corev1: corev1,
  263. store: vaultSpec,
  264. log: ctrl.Log.WithName("provider").WithName("vault"),
  265. namespace: namespace,
  266. storeKind: store.GetObjectKind().GroupVersionKind().Kind,
  267. }
  268. cfg, err := vStore.newConfig()
  269. if err != nil {
  270. return nil, err
  271. }
  272. client, err := getVaultClient(ctx, c, store, cfg)
  273. if err != nil {
  274. return nil, fmt.Errorf(errVaultClient, err)
  275. }
  276. if vaultSpec.Namespace != nil {
  277. client.SetNamespace(*vaultSpec.Namespace)
  278. }
  279. if vaultSpec.ReadYourWrites && vaultSpec.ForwardInconsistent {
  280. client.AddHeader("X-Vault-Inconsistent", "forward-active-node")
  281. }
  282. vStore.client = client
  283. vStore.auth = client.Auth()
  284. vStore.logical = client.Logical()
  285. vStore.token = client.AuthToken()
  286. // allow SecretStore controller validation to pass
  287. // when using referent namespace.
  288. if vStore.storeKind == esv1beta1.ClusterSecretStoreKind && vStore.namespace == "" && isReferentSpec(vaultSpec) {
  289. return vStore, nil
  290. }
  291. if err := vStore.setAuth(ctx, cfg); err != nil {
  292. return nil, err
  293. }
  294. return vStore, nil
  295. }
  296. func (c *connector) ValidateStore(store esv1beta1.GenericStore) error {
  297. if store == nil {
  298. return fmt.Errorf(errInvalidStore)
  299. }
  300. spc := store.GetSpec()
  301. if spc == nil {
  302. return fmt.Errorf(errInvalidStoreSpec)
  303. }
  304. if spc.Provider == nil {
  305. return fmt.Errorf(errInvalidStoreProv)
  306. }
  307. p := spc.Provider.Vault
  308. if p == nil {
  309. return fmt.Errorf(errInvalidVaultProv)
  310. }
  311. if p.Auth.AppRole != nil {
  312. if err := utils.ValidateReferentSecretSelector(store, p.Auth.AppRole.SecretRef); err != nil {
  313. return fmt.Errorf(errInvalidAppRoleSec, err)
  314. }
  315. }
  316. if p.Auth.Cert != nil {
  317. if err := utils.ValidateReferentSecretSelector(store, p.Auth.Cert.ClientCert); err != nil {
  318. return fmt.Errorf(errInvalidClientCert, err)
  319. }
  320. if err := utils.ValidateReferentSecretSelector(store, p.Auth.Cert.SecretRef); err != nil {
  321. return fmt.Errorf(errInvalidCertSec, err)
  322. }
  323. }
  324. if p.Auth.Jwt != nil {
  325. if p.Auth.Jwt.SecretRef != nil {
  326. if err := utils.ValidateReferentSecretSelector(store, *p.Auth.Jwt.SecretRef); err != nil {
  327. return fmt.Errorf(errInvalidJwtSec, err)
  328. }
  329. } else if p.Auth.Jwt.KubernetesServiceAccountToken != nil {
  330. if err := utils.ValidateReferentServiceAccountSelector(store, p.Auth.Jwt.KubernetesServiceAccountToken.ServiceAccountRef); err != nil {
  331. return fmt.Errorf(errInvalidJwtK8sSA, err)
  332. }
  333. } else {
  334. return fmt.Errorf(errJwtNoTokenSource)
  335. }
  336. }
  337. if p.Auth.Kubernetes != nil {
  338. if p.Auth.Kubernetes.ServiceAccountRef != nil {
  339. if err := utils.ValidateReferentServiceAccountSelector(store, *p.Auth.Kubernetes.ServiceAccountRef); err != nil {
  340. return fmt.Errorf(errInvalidKubeSA, err)
  341. }
  342. }
  343. if p.Auth.Kubernetes.SecretRef != nil {
  344. if err := utils.ValidateReferentSecretSelector(store, *p.Auth.Kubernetes.SecretRef); err != nil {
  345. return fmt.Errorf(errInvalidKubeSec, err)
  346. }
  347. }
  348. }
  349. if p.Auth.Ldap != nil {
  350. if err := utils.ValidateReferentSecretSelector(store, p.Auth.Ldap.SecretRef); err != nil {
  351. return fmt.Errorf(errInvalidLdapSec, err)
  352. }
  353. }
  354. if p.Auth.TokenSecretRef != nil {
  355. if err := utils.ValidateReferentSecretSelector(store, *p.Auth.TokenSecretRef); err != nil {
  356. return fmt.Errorf(errInvalidTokenRef, err)
  357. }
  358. }
  359. return nil
  360. }
  361. func (v *client) DeleteSecret(ctx context.Context, remoteRef esv1beta1.PushRemoteRef) error {
  362. path := v.buildPath(remoteRef.GetRemoteKey())
  363. metaPath, err := v.buildMetadataPath(remoteRef.GetRemoteKey())
  364. if err != nil {
  365. return err
  366. }
  367. // Retrieve the secret map from vault and convert the secret value in string form.
  368. _, err = v.logical.ReadWithDataWithContext(ctx, path, nil)
  369. // If error is not of type secret not found, we should error
  370. if err != nil && !strings.Contains(err.Error(), "secret not found") {
  371. return nil
  372. }
  373. if err != nil {
  374. return err
  375. }
  376. metadata, err := v.readSecretMetadata(ctx, remoteRef.GetRemoteKey())
  377. if err != nil {
  378. return err
  379. }
  380. manager, ok := metadata["managed-by"]
  381. if !ok || manager != "external-secrets" {
  382. return nil
  383. }
  384. _, err = v.logical.DeleteWithContext(ctx, path)
  385. if err != nil {
  386. return fmt.Errorf("could not delete secret %v: %w", remoteRef.GetRemoteKey(), err)
  387. }
  388. _, err = v.logical.DeleteWithContext(ctx, metaPath)
  389. if err != nil {
  390. return fmt.Errorf("could not delete secret metadata %v: %w", remoteRef.GetRemoteKey(), err)
  391. }
  392. return nil
  393. }
  394. func (v *client) PushSecret(ctx context.Context, value []byte, remoteRef esv1beta1.PushRemoteRef) error {
  395. label := map[string]interface{}{
  396. "custom_metadata": map[string]string{
  397. "managed-by": "external-secrets",
  398. },
  399. }
  400. secretToPush := map[string]interface{}{
  401. "data": map[string]string{
  402. remoteRef.GetRemoteKey(): string(value),
  403. },
  404. }
  405. path := v.buildPath(remoteRef.GetRemoteKey())
  406. metaPath, err := v.buildMetadataPath(remoteRef.GetRemoteKey())
  407. if err != nil {
  408. return err
  409. }
  410. // Retrieve the secret map from vault and convert the secret value in string form.
  411. vaultSecret, err := v.GetSecretMap(ctx, esv1beta1.ExternalSecretDataRemoteRef{Key: path})
  412. vaultSecretValue := string(vaultSecret[remoteRef.GetRemoteKey()])
  413. // If error is not of type secret not found, we should error
  414. if err != nil && !strings.Contains(err.Error(), "secret not found") {
  415. return err
  416. }
  417. // Retrieve the secret value to be pushed and convert it to string form.
  418. pushSecretValue := string(value)
  419. if vaultSecretValue == pushSecretValue {
  420. return nil
  421. }
  422. // If the secret exists (err == nil), we should check if it is managed by external-secrets
  423. if err == nil {
  424. metadata, err := v.readSecretMetadata(ctx, remoteRef.GetRemoteKey())
  425. if err != nil {
  426. return err
  427. }
  428. manager, ok := metadata["managed-by"]
  429. if !ok || manager != "external-secrets" {
  430. return fmt.Errorf("secret not managed by external-secrets")
  431. }
  432. }
  433. _, err = v.logical.WriteWithContext(ctx, metaPath, label)
  434. if err != nil {
  435. return err
  436. }
  437. // Otherwise, create or update the version.
  438. _, err = v.logical.WriteWithContext(ctx, path, secretToPush)
  439. return err
  440. }
  441. // GetAllSecrets gets multiple secrets from the provider and loads into a kubernetes secret.
  442. // First load all secrets from secretStore path configuration
  443. // Then, gets secrets from a matching name or matching custom_metadata.
  444. func (v *client) GetAllSecrets(ctx context.Context, ref esv1beta1.ExternalSecretFind) (map[string][]byte, error) {
  445. if v.store.Version == esv1beta1.VaultKVStoreV1 {
  446. return nil, errors.New(errUnsupportedKvVersion)
  447. }
  448. searchPath := ""
  449. if ref.Path != nil {
  450. searchPath = *ref.Path + "/"
  451. }
  452. potentialSecrets, err := v.listSecrets(ctx, searchPath)
  453. if err != nil {
  454. return nil, err
  455. }
  456. if ref.Name != nil {
  457. return v.findSecretsFromName(ctx, potentialSecrets, *ref.Name)
  458. }
  459. return v.findSecretsFromTags(ctx, potentialSecrets, ref.Tags)
  460. }
  461. func (v *client) findSecretsFromTags(ctx context.Context, candidates []string, tags map[string]string) (map[string][]byte, error) {
  462. secrets := make(map[string][]byte)
  463. for _, name := range candidates {
  464. match := true
  465. metadata, err := v.readSecretMetadata(ctx, name)
  466. if err != nil {
  467. return nil, err
  468. }
  469. for tk, tv := range tags {
  470. p, ok := metadata[tk]
  471. if !ok || p != tv {
  472. match = false
  473. break
  474. }
  475. }
  476. if match {
  477. secret, err := v.GetSecret(ctx, esv1beta1.ExternalSecretDataRemoteRef{Key: name})
  478. if err != nil {
  479. return nil, err
  480. }
  481. if secret != nil {
  482. secrets[name] = secret
  483. }
  484. }
  485. }
  486. return secrets, nil
  487. }
  488. func (v *client) findSecretsFromName(ctx context.Context, candidates []string, ref esv1beta1.FindName) (map[string][]byte, error) {
  489. secrets := make(map[string][]byte)
  490. matcher, err := find.New(ref)
  491. if err != nil {
  492. return nil, err
  493. }
  494. for _, name := range candidates {
  495. ok := matcher.MatchName(name)
  496. if ok {
  497. secret, err := v.GetSecret(ctx, esv1beta1.ExternalSecretDataRemoteRef{Key: name})
  498. if err != nil {
  499. return nil, err
  500. }
  501. if secret != nil {
  502. secrets[name] = secret
  503. }
  504. }
  505. }
  506. return secrets, nil
  507. }
  508. func (v *client) listSecrets(ctx context.Context, path string) ([]string, error) {
  509. secrets := make([]string, 0)
  510. url, err := v.buildMetadataPath(path)
  511. if err != nil {
  512. return nil, err
  513. }
  514. secret, err := v.logical.ListWithContext(ctx, url)
  515. if err != nil {
  516. return nil, fmt.Errorf(errReadSecret, err)
  517. }
  518. if secret == nil {
  519. return nil, fmt.Errorf("provided path %v does not contain any secrets", url)
  520. }
  521. t, ok := secret.Data["keys"]
  522. if !ok {
  523. return nil, nil
  524. }
  525. paths := t.([]interface{})
  526. for _, p := range paths {
  527. strPath := p.(string)
  528. fullPath := path + strPath // because path always ends with a /
  529. if path == "" {
  530. fullPath = strPath
  531. }
  532. // Recurrently find secrets
  533. if !strings.HasSuffix(p.(string), "/") {
  534. secrets = append(secrets, fullPath)
  535. } else {
  536. partial, err := v.listSecrets(ctx, fullPath)
  537. if err != nil {
  538. return nil, err
  539. }
  540. secrets = append(secrets, partial...)
  541. }
  542. }
  543. return secrets, nil
  544. }
  545. func (v *client) readSecretMetadata(ctx context.Context, path string) (map[string]string, error) {
  546. metadata := make(map[string]string)
  547. url, err := v.buildMetadataPath(path)
  548. if err != nil {
  549. return nil, err
  550. }
  551. secret, err := v.logical.ReadWithDataWithContext(ctx, url, nil)
  552. if err != nil {
  553. return nil, fmt.Errorf(errReadSecret, err)
  554. }
  555. if secret == nil {
  556. return nil, errors.New(errNotFound)
  557. }
  558. t, ok := secret.Data["custom_metadata"]
  559. if !ok {
  560. return nil, nil
  561. }
  562. d, ok := t.(map[string]interface{})
  563. if !ok {
  564. return metadata, nil
  565. }
  566. for k, v := range d {
  567. metadata[k] = v.(string)
  568. }
  569. return metadata, nil
  570. }
  571. // GetSecret supports two types:
  572. // 1. get the full secret as json-encoded value
  573. // by leaving the ref.Property empty.
  574. // 2. get a key from the secret.
  575. // Nested values are supported by specifying a gjson expression
  576. func (v *client) GetSecret(ctx context.Context, ref esv1beta1.ExternalSecretDataRemoteRef) ([]byte, error) {
  577. data, err := v.readSecret(ctx, ref.Key, ref.Version)
  578. if err != nil {
  579. return nil, err
  580. }
  581. // Return nil if secret value is null
  582. if data == nil {
  583. return nil, nil
  584. }
  585. jsonStr, err := json.Marshal(data)
  586. if err != nil {
  587. return nil, err
  588. }
  589. // (1): return raw json if no property is defined
  590. if ref.Property == "" {
  591. return jsonStr, nil
  592. }
  593. // For backwards compatibility we want the
  594. // actual keys to take precedence over gjson syntax
  595. // (2): extract key from secret with property
  596. if _, ok := data[ref.Property]; ok {
  597. return getTypedKey(data, ref.Property)
  598. }
  599. // (3): extract key from secret using gjson
  600. val := gjson.Get(string(jsonStr), ref.Property)
  601. if !val.Exists() {
  602. return nil, fmt.Errorf(errSecretKeyFmt, ref.Property)
  603. }
  604. return []byte(val.String()), nil
  605. }
  606. // GetSecretMap supports two modes of operation:
  607. // 1. get the full secret from the vault data payload (by leaving .property empty).
  608. // 2. extract key/value pairs from a (nested) object.
  609. func (v *client) GetSecretMap(ctx context.Context, ref esv1beta1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
  610. data, err := v.GetSecret(ctx, ref)
  611. if err != nil {
  612. return nil, err
  613. }
  614. var secretData map[string]interface{}
  615. err = json.Unmarshal(data, &secretData)
  616. if err != nil {
  617. return nil, err
  618. }
  619. byteMap := make(map[string][]byte, len(secretData))
  620. for k := range secretData {
  621. byteMap[k], err = getTypedKey(secretData, k)
  622. if err != nil {
  623. return nil, err
  624. }
  625. }
  626. return byteMap, nil
  627. }
  628. func getTypedKey(data map[string]interface{}, key string) ([]byte, error) {
  629. v, ok := data[key]
  630. if !ok {
  631. return nil, fmt.Errorf(errUnexpectedKey, key)
  632. }
  633. switch t := v.(type) {
  634. case string:
  635. return []byte(t), nil
  636. case map[string]interface{}:
  637. return json.Marshal(t)
  638. case []byte:
  639. return t, nil
  640. // also covers int and float32 due to json.Marshal
  641. case float64:
  642. return []byte(strconv.FormatFloat(t, 'f', -1, 64)), nil
  643. case bool:
  644. return []byte(strconv.FormatBool(t)), nil
  645. case nil:
  646. return []byte(nil), nil
  647. default:
  648. return nil, errors.New(errSecretFormat)
  649. }
  650. }
  651. func (v *client) Close(ctx context.Context) error {
  652. // Revoke the token if we have one set, it wasn't sourced from a TokenSecretRef,
  653. // and token caching isn't enabled
  654. if !EnableCache && v.client.Token() != "" && v.store.Auth.TokenSecretRef == nil {
  655. err := revokeTokenIfValid(ctx, v.client)
  656. if err != nil {
  657. return err
  658. }
  659. }
  660. return nil
  661. }
  662. func isReferentSpec(prov *esv1beta1.VaultProvider) bool {
  663. if prov.Auth.TokenSecretRef != nil && prov.Auth.TokenSecretRef.Namespace == nil {
  664. return true
  665. }
  666. if prov.Auth.AppRole != nil && prov.Auth.AppRole.SecretRef.Namespace == nil {
  667. return true
  668. }
  669. if prov.Auth.Kubernetes != nil && prov.Auth.Kubernetes.SecretRef != nil && prov.Auth.Kubernetes.SecretRef.Namespace == nil {
  670. return true
  671. }
  672. if prov.Auth.Kubernetes != nil && prov.Auth.Kubernetes.ServiceAccountRef != nil && prov.Auth.Kubernetes.ServiceAccountRef.Namespace == nil {
  673. return true
  674. }
  675. if prov.Auth.Ldap != nil && prov.Auth.Ldap.SecretRef.Namespace == nil {
  676. return true
  677. }
  678. if prov.Auth.Jwt != nil && prov.Auth.Jwt.SecretRef != nil && prov.Auth.Jwt.SecretRef.Namespace == nil {
  679. return true
  680. }
  681. if prov.Auth.Jwt != nil && prov.Auth.Jwt.KubernetesServiceAccountToken != nil && prov.Auth.Jwt.KubernetesServiceAccountToken.ServiceAccountRef.Namespace == nil {
  682. return true
  683. }
  684. if prov.Auth.Cert != nil && prov.Auth.Cert.SecretRef.Namespace == nil {
  685. return true
  686. }
  687. return false
  688. }
  689. func (v *client) Validate() (esv1beta1.ValidationResult, error) {
  690. // when using referent namespace we can not validate the token
  691. // because the namespace is not known yet when Validate() is called
  692. // from the SecretStore controller.
  693. if v.storeKind == esv1beta1.ClusterSecretStoreKind && isReferentSpec(v.store) {
  694. return esv1beta1.ValidationResultUnknown, nil
  695. }
  696. _, err := checkToken(context.Background(), v.token)
  697. if err != nil {
  698. return esv1beta1.ValidationResultError, fmt.Errorf(errInvalidCredentials, err)
  699. }
  700. return esv1beta1.ValidationResultReady, nil
  701. }
  702. func (v *client) buildMetadataPath(path string) (string, error) {
  703. var url string
  704. if v.store.Path == nil && !strings.Contains(path, "data") {
  705. return "", fmt.Errorf(errPathInvalid)
  706. }
  707. if v.store.Path == nil {
  708. path = strings.Replace(path, "data", "metadata", 1)
  709. url = path
  710. } else {
  711. url = fmt.Sprintf("%s/metadata/%s", *v.store.Path, path)
  712. }
  713. return url, nil
  714. }
  715. /*
  716. buildPath is a helper method to build the vault equivalent path
  717. from ExternalSecrets and SecretStore manifests. the path build logic
  718. varies depending on the SecretStore KV version:
  719. Example inputs/outputs:
  720. # simple build:
  721. kv version == "v2":
  722. provider_path: "secret/path"
  723. input: "foo"
  724. output: "secret/path/data/foo" # provider_path and data are prepended
  725. kv version == "v1":
  726. provider_path: "secret/path"
  727. input: "foo"
  728. output: "secret/path/foo" # provider_path is prepended
  729. # inheriting paths:
  730. kv version == "v2":
  731. provider_path: "secret/path"
  732. input: "secret/path/foo"
  733. output: "secret/path/data/foo" #data is prepended
  734. kv version == "v2":
  735. provider_path: "secret/path"
  736. input: "secret/path/data/foo"
  737. output: "secret/path/data/foo" #noop
  738. kv version == "v1":
  739. provider_path: "secret/path"
  740. input: "secret/path/foo"
  741. output: "secret/path/foo" #noop
  742. # provider path not defined:
  743. kv version == "v2":
  744. provider_path: nil
  745. input: "secret/path/foo"
  746. output: "secret/data/path/foo" # data is prepended to secret/
  747. kv version == "v2":
  748. provider_path: nil
  749. input: "secret/path/data/foo"
  750. output: "secret/path/data/foo" #noop
  751. kv version == "v1":
  752. provider_path: nil
  753. input: "secret/path/foo"
  754. output: "secret/path/foo" #noop
  755. */
  756. func (v *client) buildPath(path string) string {
  757. optionalMount := v.store.Path
  758. out := path
  759. // if optionalMount is Set, remove it from path if its there
  760. if optionalMount != nil {
  761. cut := *optionalMount + "/"
  762. if strings.HasPrefix(out, cut) {
  763. // This current logic induces a bug when the actual secret resides on same path names as the mount path.
  764. _, out, _ = strings.Cut(out, cut)
  765. // if data succeeds optionalMount on v2 store, we should remove it as well
  766. if strings.HasPrefix(out, "data/") && v.store.Version == esv1beta1.VaultKVStoreV2 {
  767. _, out, _ = strings.Cut(out, "data/")
  768. }
  769. }
  770. buildPath := strings.Split(out, "/")
  771. buildMount := strings.Split(*optionalMount, "/")
  772. if v.store.Version == esv1beta1.VaultKVStoreV2 {
  773. buildMount = append(buildMount, "data")
  774. }
  775. buildMount = append(buildMount, buildPath...)
  776. out = strings.Join(buildMount, "/")
  777. return out
  778. }
  779. if !strings.Contains(out, "/data/") && v.store.Version == esv1beta1.VaultKVStoreV2 {
  780. buildPath := strings.Split(out, "/")
  781. buildMount := []string{buildPath[0], "data"}
  782. buildMount = append(buildMount, buildPath[1:]...)
  783. out = strings.Join(buildMount, "/")
  784. return out
  785. }
  786. return out
  787. }
  788. func (v *client) readSecret(ctx context.Context, path, version string) (map[string]interface{}, error) {
  789. dataPath := v.buildPath(path)
  790. // path formated according to vault docs for v1 and v2 API
  791. // v1: https://www.vaultproject.io/api-docs/secret/kv/kv-v1#read-secret
  792. // v2: https://www.vaultproject.io/api/secret/kv/kv-v2#read-secret-version
  793. var params map[string][]string
  794. if version != "" {
  795. params = make(map[string][]string)
  796. params["version"] = []string{version}
  797. }
  798. vaultSecret, err := v.logical.ReadWithDataWithContext(ctx, dataPath, params)
  799. if err != nil {
  800. return nil, fmt.Errorf(errReadSecret, err)
  801. }
  802. if vaultSecret == nil {
  803. return nil, errors.New(errNotFound)
  804. }
  805. secretData := vaultSecret.Data
  806. if v.store.Version == esv1beta1.VaultKVStoreV2 {
  807. // Vault KV2 has data embedded within sub-field
  808. // reference - https://www.vaultproject.io/api/secret/kv/kv-v2#read-secret-version
  809. dataInt, ok := vaultSecret.Data["data"]
  810. if !ok {
  811. return nil, errors.New(errDataField)
  812. }
  813. if dataInt == nil {
  814. return nil, nil
  815. }
  816. secretData, ok = dataInt.(map[string]interface{})
  817. if !ok {
  818. return nil, errors.New(errJSONUnmarshall)
  819. }
  820. }
  821. return secretData, nil
  822. }
  823. func (v *client) newConfig() (*vault.Config, error) {
  824. cfg := vault.DefaultConfig()
  825. cfg.Address = v.store.Server
  826. // In a controller-runtime context, we rely on the reconciliation process for retrying
  827. cfg.MaxRetries = 0
  828. if len(v.store.CABundle) == 0 && v.store.CAProvider == nil {
  829. return cfg, nil
  830. }
  831. caCertPool := x509.NewCertPool()
  832. if len(v.store.CABundle) > 0 {
  833. ok := caCertPool.AppendCertsFromPEM(v.store.CABundle)
  834. if !ok {
  835. return nil, errors.New(errVaultCert)
  836. }
  837. }
  838. if v.store.CAProvider != nil && v.storeKind == esv1beta1.ClusterSecretStoreKind && v.store.CAProvider.Namespace == nil {
  839. return nil, errors.New(errCANamespace)
  840. }
  841. if v.store.CAProvider != nil {
  842. var cert []byte
  843. var err error
  844. switch v.store.CAProvider.Type {
  845. case esv1beta1.CAProviderTypeSecret:
  846. cert, err = getCertFromSecret(v)
  847. case esv1beta1.CAProviderTypeConfigMap:
  848. cert, err = getCertFromConfigMap(v)
  849. default:
  850. return nil, errors.New(errUnknownCAProvider)
  851. }
  852. if err != nil {
  853. return nil, err
  854. }
  855. ok := caCertPool.AppendCertsFromPEM(cert)
  856. if !ok {
  857. return nil, errors.New(errVaultCert)
  858. }
  859. }
  860. if transport, ok := cfg.HttpClient.Transport.(*http.Transport); ok {
  861. transport.TLSClientConfig.RootCAs = caCertPool
  862. }
  863. // If either read-after-write consistency feature is enabled, enable ReadYourWrites
  864. cfg.ReadYourWrites = v.store.ReadYourWrites || v.store.ForwardInconsistent
  865. return cfg, nil
  866. }
  867. func getCertFromSecret(v *client) ([]byte, error) {
  868. secretRef := esmeta.SecretKeySelector{
  869. Name: v.store.CAProvider.Name,
  870. Key: v.store.CAProvider.Key,
  871. }
  872. if v.store.CAProvider.Namespace != nil {
  873. secretRef.Namespace = v.store.CAProvider.Namespace
  874. }
  875. ctx := context.Background()
  876. res, err := v.secretKeyRef(ctx, &secretRef)
  877. if err != nil {
  878. return nil, fmt.Errorf(errVaultCert, err)
  879. }
  880. return []byte(res), nil
  881. }
  882. func getCertFromConfigMap(v *client) ([]byte, error) {
  883. objKey := types.NamespacedName{
  884. Name: v.store.CAProvider.Name,
  885. }
  886. if v.store.CAProvider.Namespace != nil {
  887. objKey.Namespace = *v.store.CAProvider.Namespace
  888. }
  889. configMapRef := &corev1.ConfigMap{}
  890. ctx := context.Background()
  891. err := v.kube.Get(ctx, objKey, configMapRef)
  892. if err != nil {
  893. return nil, fmt.Errorf(errVaultCert, err)
  894. }
  895. val, ok := configMapRef.Data[v.store.CAProvider.Key]
  896. if !ok {
  897. return nil, fmt.Errorf(errConfigMapFmt, v.store.CAProvider.Key)
  898. }
  899. return []byte(val), nil
  900. }
  901. /*
  902. setAuth gets a new token using the configured mechanism.
  903. If there's already a valid token, does nothing.
  904. */
  905. func (v *client) setAuth(ctx context.Context, cfg *vault.Config) error {
  906. tokenExists := false
  907. var err error
  908. if v.client.Token() != "" {
  909. tokenExists, err = checkToken(ctx, v.token)
  910. }
  911. if tokenExists {
  912. v.log.V(1).Info("Re-using existing token")
  913. return err
  914. }
  915. tokenExists, err = setSecretKeyToken(ctx, v)
  916. if tokenExists {
  917. v.log.V(1).Info("Set token from secret")
  918. return err
  919. }
  920. tokenExists, err = setAppRoleToken(ctx, v)
  921. if tokenExists {
  922. v.log.V(1).Info("Retrieved new token using AppRole auth")
  923. return err
  924. }
  925. tokenExists, err = setKubernetesAuthToken(ctx, v)
  926. if tokenExists {
  927. v.log.V(1).Info("Retrieved new token using Kubernetes auth")
  928. return err
  929. }
  930. tokenExists, err = setLdapAuthToken(ctx, v)
  931. if tokenExists {
  932. v.log.V(1).Info("Retrieved new token using LDAP auth")
  933. return err
  934. }
  935. tokenExists, err = setJwtAuthToken(ctx, v)
  936. if tokenExists {
  937. v.log.V(1).Info("Retrieved new token using JWT auth")
  938. return err
  939. }
  940. tokenExists, err = setCertAuthToken(ctx, v, cfg)
  941. if tokenExists {
  942. v.log.V(1).Info("Retrieved new token using certificate auth")
  943. return err
  944. }
  945. return errors.New(errAuthFormat)
  946. }
  947. func setSecretKeyToken(ctx context.Context, v *client) (bool, error) {
  948. tokenRef := v.store.Auth.TokenSecretRef
  949. if tokenRef != nil {
  950. token, err := v.secretKeyRef(ctx, tokenRef)
  951. if err != nil {
  952. return true, err
  953. }
  954. v.client.SetToken(token)
  955. return true, nil
  956. }
  957. return false, nil
  958. }
  959. func setAppRoleToken(ctx context.Context, v *client) (bool, error) {
  960. appRole := v.store.Auth.AppRole
  961. if appRole != nil {
  962. err := v.requestTokenWithAppRoleRef(ctx, appRole)
  963. if err != nil {
  964. return true, err
  965. }
  966. return true, nil
  967. }
  968. return false, nil
  969. }
  970. func setKubernetesAuthToken(ctx context.Context, v *client) (bool, error) {
  971. kubernetesAuth := v.store.Auth.Kubernetes
  972. if kubernetesAuth != nil {
  973. err := v.requestTokenWithKubernetesAuth(ctx, kubernetesAuth)
  974. if err != nil {
  975. return true, err
  976. }
  977. return true, nil
  978. }
  979. return false, nil
  980. }
  981. func setLdapAuthToken(ctx context.Context, v *client) (bool, error) {
  982. ldapAuth := v.store.Auth.Ldap
  983. if ldapAuth != nil {
  984. err := v.requestTokenWithLdapAuth(ctx, ldapAuth)
  985. if err != nil {
  986. return true, err
  987. }
  988. return true, nil
  989. }
  990. return false, nil
  991. }
  992. func setJwtAuthToken(ctx context.Context, v *client) (bool, error) {
  993. jwtAuth := v.store.Auth.Jwt
  994. if jwtAuth != nil {
  995. err := v.requestTokenWithJwtAuth(ctx, jwtAuth)
  996. if err != nil {
  997. return true, err
  998. }
  999. return true, nil
  1000. }
  1001. return false, nil
  1002. }
  1003. func setCertAuthToken(ctx context.Context, v *client, cfg *vault.Config) (bool, error) {
  1004. certAuth := v.store.Auth.Cert
  1005. if certAuth != nil {
  1006. err := v.requestTokenWithCertAuth(ctx, certAuth, cfg)
  1007. if err != nil {
  1008. return true, err
  1009. }
  1010. return true, nil
  1011. }
  1012. return false, nil
  1013. }
  1014. func (v *client) secretKeyRefForServiceAccount(ctx context.Context, serviceAccountRef *esmeta.ServiceAccountSelector) (string, error) {
  1015. serviceAccount := &corev1.ServiceAccount{}
  1016. ref := types.NamespacedName{
  1017. Namespace: v.namespace,
  1018. Name: serviceAccountRef.Name,
  1019. }
  1020. if (v.storeKind == esv1beta1.ClusterSecretStoreKind) &&
  1021. (serviceAccountRef.Namespace != nil) {
  1022. ref.Namespace = *serviceAccountRef.Namespace
  1023. }
  1024. err := v.kube.Get(ctx, ref, serviceAccount)
  1025. if err != nil {
  1026. return "", fmt.Errorf(errGetKubeSA, ref.Name, err)
  1027. }
  1028. if len(serviceAccount.Secrets) == 0 {
  1029. return "", fmt.Errorf(errGetKubeSASecrets, ref.Name)
  1030. }
  1031. for _, tokenRef := range serviceAccount.Secrets {
  1032. retval, err := v.secretKeyRef(ctx, &esmeta.SecretKeySelector{
  1033. Name: tokenRef.Name,
  1034. Namespace: &ref.Namespace,
  1035. Key: "token",
  1036. })
  1037. if err != nil {
  1038. continue
  1039. }
  1040. return retval, nil
  1041. }
  1042. return "", fmt.Errorf(errGetKubeSANoToken, ref.Name)
  1043. }
  1044. func (v *client) secretKeyRef(ctx context.Context, secretRef *esmeta.SecretKeySelector) (string, error) {
  1045. secret := &corev1.Secret{}
  1046. ref := types.NamespacedName{
  1047. Namespace: v.namespace,
  1048. Name: secretRef.Name,
  1049. }
  1050. if (v.storeKind == esv1beta1.ClusterSecretStoreKind) &&
  1051. (secretRef.Namespace != nil) {
  1052. ref.Namespace = *secretRef.Namespace
  1053. }
  1054. err := v.kube.Get(ctx, ref, secret)
  1055. if err != nil {
  1056. return "", fmt.Errorf(errGetKubeSecret, ref.Name, err)
  1057. }
  1058. keyBytes, ok := secret.Data[secretRef.Key]
  1059. if !ok {
  1060. return "", fmt.Errorf(errSecretKeyFmt, secretRef.Key)
  1061. }
  1062. value := string(keyBytes)
  1063. valueStr := strings.TrimSpace(value)
  1064. return valueStr, nil
  1065. }
  1066. func (v *client) serviceAccountToken(ctx context.Context, serviceAccountRef esmeta.ServiceAccountSelector, additionalAud []string, expirationSeconds int64) (string, error) {
  1067. audiences := serviceAccountRef.Audiences
  1068. if len(additionalAud) > 0 {
  1069. audiences = append(audiences, additionalAud...)
  1070. }
  1071. tokenRequest := &authenticationv1.TokenRequest{
  1072. ObjectMeta: metav1.ObjectMeta{
  1073. Namespace: v.namespace,
  1074. },
  1075. Spec: authenticationv1.TokenRequestSpec{
  1076. Audiences: audiences,
  1077. ExpirationSeconds: &expirationSeconds,
  1078. },
  1079. }
  1080. if (v.storeKind == esv1beta1.ClusterSecretStoreKind) &&
  1081. (serviceAccountRef.Namespace != nil) {
  1082. tokenRequest.Namespace = *serviceAccountRef.Namespace
  1083. }
  1084. tokenResponse, err := v.corev1.ServiceAccounts(tokenRequest.Namespace).CreateToken(ctx, serviceAccountRef.Name, tokenRequest, metav1.CreateOptions{})
  1085. if err != nil {
  1086. return "", fmt.Errorf(errGetKubeSATokenRequest, serviceAccountRef.Name, err)
  1087. }
  1088. return tokenResponse.Status.Token, nil
  1089. }
  1090. // checkToken does a lookup and checks if the provided token exists.
  1091. func checkToken(ctx context.Context, token Token) (bool, error) {
  1092. // https://www.vaultproject.io/api-docs/auth/token#lookup-a-token-self
  1093. resp, err := token.LookupSelfWithContext(ctx)
  1094. if err != nil {
  1095. return false, err
  1096. }
  1097. t, ok := resp.Data["type"]
  1098. if !ok {
  1099. return false, fmt.Errorf("could not assert token type")
  1100. }
  1101. tokenType := t.(string)
  1102. if tokenType == "batch" {
  1103. return false, nil
  1104. }
  1105. return true, nil
  1106. }
  1107. func revokeTokenIfValid(ctx context.Context, client Client) error {
  1108. valid, err := checkToken(ctx, client.AuthToken())
  1109. if err != nil {
  1110. return fmt.Errorf(errVaultRevokeToken, err)
  1111. }
  1112. if valid {
  1113. err = client.AuthToken().RevokeSelfWithContext(ctx, client.Token())
  1114. if err != nil {
  1115. return fmt.Errorf(errVaultRevokeToken, err)
  1116. }
  1117. client.ClearToken()
  1118. }
  1119. return nil
  1120. }
  1121. func (v *client) requestTokenWithAppRoleRef(ctx context.Context, appRole *esv1beta1.VaultAppRole) error {
  1122. roleID := strings.TrimSpace(appRole.RoleID)
  1123. secretID, err := v.secretKeyRef(ctx, &appRole.SecretRef)
  1124. if err != nil {
  1125. return err
  1126. }
  1127. secret := approle.SecretID{FromString: secretID}
  1128. appRoleClient, err := approle.NewAppRoleAuth(roleID, &secret, approle.WithMountPath(appRole.Path))
  1129. if err != nil {
  1130. return err
  1131. }
  1132. _, err = v.auth.Login(ctx, appRoleClient)
  1133. if err != nil {
  1134. return err
  1135. }
  1136. return nil
  1137. }
  1138. func (v *client) requestTokenWithKubernetesAuth(ctx context.Context, kubernetesAuth *esv1beta1.VaultKubernetesAuth) error {
  1139. jwtString, err := getJwtString(ctx, v, kubernetesAuth)
  1140. if err != nil {
  1141. return err
  1142. }
  1143. k, err := authkubernetes.NewKubernetesAuth(kubernetesAuth.Role, authkubernetes.WithServiceAccountToken(jwtString), authkubernetes.WithMountPath(kubernetesAuth.Path))
  1144. if err != nil {
  1145. return err
  1146. }
  1147. _, err = v.auth.Login(ctx, k)
  1148. if err != nil {
  1149. return err
  1150. }
  1151. return nil
  1152. }
  1153. func getJwtString(ctx context.Context, v *client, kubernetesAuth *esv1beta1.VaultKubernetesAuth) (string, error) {
  1154. if kubernetesAuth.ServiceAccountRef != nil {
  1155. // Kubernetes <v1.24 fetch token via ServiceAccount.Secrets[]
  1156. // this behavior was removed in v1.24 and we must use TokenRequest API (see below)
  1157. jwt, err := v.secretKeyRefForServiceAccount(ctx, kubernetesAuth.ServiceAccountRef)
  1158. if jwt != "" {
  1159. return jwt, err
  1160. }
  1161. if err != nil {
  1162. v.log.V(1).Info("unable to fetch jwt from service account secret, trying service account token next")
  1163. }
  1164. // Kubernetes >=v1.24: fetch token via TokenRequest API
  1165. // note: this is a massive change from vault perspective: the `iss` claim will very likely change.
  1166. // Vault 1.9 deprecated issuer validation by default, and authentication with Vault clusters <1.9 will likely fail.
  1167. jwt, err = v.serviceAccountToken(ctx, *kubernetesAuth.ServiceAccountRef, nil, 600)
  1168. if err != nil {
  1169. return "", err
  1170. }
  1171. return jwt, nil
  1172. } else if kubernetesAuth.SecretRef != nil {
  1173. tokenRef := kubernetesAuth.SecretRef
  1174. if tokenRef.Key == "" {
  1175. tokenRef = kubernetesAuth.SecretRef.DeepCopy()
  1176. tokenRef.Key = "token"
  1177. }
  1178. jwt, err := v.secretKeyRef(ctx, tokenRef)
  1179. if err != nil {
  1180. return "", err
  1181. }
  1182. return jwt, nil
  1183. } else {
  1184. // Kubernetes authentication is specified, but without a referenced
  1185. // Kubernetes secret. We check if the file path for in-cluster service account
  1186. // exists and attempt to use the token for Vault Kubernetes auth.
  1187. if _, err := os.Stat(serviceAccTokenPath); err != nil {
  1188. return "", fmt.Errorf(errServiceAccount, err)
  1189. }
  1190. jwtByte, err := os.ReadFile(serviceAccTokenPath)
  1191. if err != nil {
  1192. return "", fmt.Errorf(errServiceAccount, err)
  1193. }
  1194. return string(jwtByte), nil
  1195. }
  1196. }
  1197. func (v *client) requestTokenWithLdapAuth(ctx context.Context, ldapAuth *esv1beta1.VaultLdapAuth) error {
  1198. username := strings.TrimSpace(ldapAuth.Username)
  1199. password, err := v.secretKeyRef(ctx, &ldapAuth.SecretRef)
  1200. if err != nil {
  1201. return err
  1202. }
  1203. pass := authldap.Password{FromString: password}
  1204. l, err := authldap.NewLDAPAuth(username, &pass, authldap.WithMountPath(ldapAuth.Path))
  1205. if err != nil {
  1206. return err
  1207. }
  1208. _, err = v.auth.Login(ctx, l)
  1209. if err != nil {
  1210. return err
  1211. }
  1212. return nil
  1213. }
  1214. func (v *client) requestTokenWithJwtAuth(ctx context.Context, jwtAuth *esv1beta1.VaultJwtAuth) error {
  1215. role := strings.TrimSpace(jwtAuth.Role)
  1216. var jwt string
  1217. var err error
  1218. if jwtAuth.SecretRef != nil {
  1219. jwt, err = v.secretKeyRef(ctx, jwtAuth.SecretRef)
  1220. } else if k8sServiceAccountToken := jwtAuth.KubernetesServiceAccountToken; k8sServiceAccountToken != nil {
  1221. audiences := k8sServiceAccountToken.Audiences
  1222. if audiences == nil {
  1223. audiences = &[]string{"vault"}
  1224. }
  1225. expirationSeconds := k8sServiceAccountToken.ExpirationSeconds
  1226. if expirationSeconds == nil {
  1227. tmp := int64(600)
  1228. expirationSeconds = &tmp
  1229. }
  1230. jwt, err = v.serviceAccountToken(ctx, k8sServiceAccountToken.ServiceAccountRef, *audiences, *expirationSeconds)
  1231. } else {
  1232. err = fmt.Errorf(errJwtNoTokenSource)
  1233. }
  1234. if err != nil {
  1235. return err
  1236. }
  1237. parameters := map[string]interface{}{
  1238. "role": role,
  1239. "jwt": jwt,
  1240. }
  1241. url := strings.Join([]string{"auth", jwtAuth.Path, "login"}, "/")
  1242. vaultResult, err := v.logical.WriteWithContext(ctx, url, parameters)
  1243. if err != nil {
  1244. return err
  1245. }
  1246. token, err := vaultResult.TokenID()
  1247. if err != nil {
  1248. return fmt.Errorf(errVaultToken, err)
  1249. }
  1250. v.client.SetToken(token)
  1251. return nil
  1252. }
  1253. func (v *client) requestTokenWithCertAuth(ctx context.Context, certAuth *esv1beta1.VaultCertAuth, cfg *vault.Config) error {
  1254. clientKey, err := v.secretKeyRef(ctx, &certAuth.SecretRef)
  1255. if err != nil {
  1256. return err
  1257. }
  1258. clientCert, err := v.secretKeyRef(ctx, &certAuth.ClientCert)
  1259. if err != nil {
  1260. return err
  1261. }
  1262. cert, err := tls.X509KeyPair([]byte(clientCert), []byte(clientKey))
  1263. if err != nil {
  1264. return fmt.Errorf(errClientTLSAuth, err)
  1265. }
  1266. if transport, ok := cfg.HttpClient.Transport.(*http.Transport); ok {
  1267. transport.TLSClientConfig.Certificates = []tls.Certificate{cert}
  1268. }
  1269. url := strings.Join([]string{"auth", "cert", "login"}, "/")
  1270. vaultResult, err := v.logical.WriteWithContext(ctx, url, nil)
  1271. if err != nil {
  1272. return fmt.Errorf(errVaultRequest, err)
  1273. }
  1274. token, err := vaultResult.TokenID()
  1275. if err != nil {
  1276. return fmt.Errorf(errVaultToken, err)
  1277. }
  1278. v.client.SetToken(token)
  1279. return nil
  1280. }