vault.go 41 KB

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