vault.go 38 KB

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