vault.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734
  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. "errors"
  18. "fmt"
  19. "io/ioutil"
  20. "net/http"
  21. "os"
  22. "strings"
  23. "github.com/go-logr/logr"
  24. vault "github.com/hashicorp/vault/api"
  25. corev1 "k8s.io/api/core/v1"
  26. "k8s.io/apimachinery/pkg/types"
  27. ctrl "sigs.k8s.io/controller-runtime"
  28. kclient "sigs.k8s.io/controller-runtime/pkg/client"
  29. esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
  30. esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
  31. "github.com/external-secrets/external-secrets/pkg/provider"
  32. "github.com/external-secrets/external-secrets/pkg/provider/schema"
  33. )
  34. var (
  35. _ provider.Provider = &connector{}
  36. _ provider.SecretsClient = &client{}
  37. )
  38. const (
  39. serviceAccTokenPath = "/var/run/secrets/kubernetes.io/serviceaccount/token"
  40. errVaultStore = "received invalid Vault SecretStore resource: %w"
  41. errVaultClient = "cannot setup new vault client: %w"
  42. errVaultCert = "cannot set Vault CA certificate: %w"
  43. errReadSecret = "cannot read secret data from Vault: %w"
  44. errAuthFormat = "cannot initialize Vault client: no valid auth method specified: %w"
  45. errDataField = "failed to find data field"
  46. errJSONUnmarshall = "failed to unmarshall JSON"
  47. errSecretFormat = "secret data not in expected format"
  48. errVaultToken = "cannot parse Vault authentication token: %w"
  49. errVaultReqParams = "cannot set Vault request parameters: %w"
  50. errVaultRequest = "error from Vault request: %w"
  51. errVaultResponse = "cannot parse Vault response: %w"
  52. errServiceAccount = "cannot read Kubernetes service account token from file system: %w"
  53. errGetKubeSA = "cannot get Kubernetes service account %q: %w"
  54. errGetKubeSASecrets = "cannot find secrets bound to service account: %q"
  55. errGetKubeSANoToken = "cannot find token in secrets bound to service account: %q"
  56. errGetKubeSecret = "cannot get Kubernetes secret %q: %w"
  57. errSecretKeyFmt = "cannot find secret data for key: %q"
  58. errConfigMapFmt = "cannot find config map data for key: %q"
  59. errClientTLSAuth = "error from Client TLS Auth: %q"
  60. errVaultRevokeToken = "error while revoking token: %w"
  61. errUnknownCAProvider = "unknown caProvider type given"
  62. )
  63. type Client interface {
  64. NewRequest(method, requestPath string) *vault.Request
  65. RawRequestWithContext(ctx context.Context, r *vault.Request) (*vault.Response, error)
  66. SetToken(v string)
  67. Token() string
  68. ClearToken()
  69. SetNamespace(namespace string)
  70. }
  71. type client struct {
  72. kube kclient.Client
  73. store *esv1alpha1.VaultProvider
  74. log logr.Logger
  75. client Client
  76. namespace string
  77. storeKind string
  78. }
  79. func init() {
  80. schema.Register(&connector{
  81. newVaultClient: newVaultClient,
  82. }, &esv1alpha1.SecretStoreProvider{
  83. Vault: &esv1alpha1.VaultProvider{},
  84. })
  85. }
  86. func newVaultClient(c *vault.Config) (Client, error) {
  87. return vault.NewClient(c)
  88. }
  89. type connector struct {
  90. newVaultClient func(c *vault.Config) (Client, error)
  91. }
  92. func (c *connector) NewClient(ctx context.Context, store esv1alpha1.GenericStore, kube kclient.Client, namespace string) (provider.SecretsClient, error) {
  93. storeSpec := store.GetSpec()
  94. if storeSpec == nil || storeSpec.Provider == nil || storeSpec.Provider.Vault == nil {
  95. return nil, errors.New(errVaultStore)
  96. }
  97. vaultSpec := storeSpec.Provider.Vault
  98. vStore := &client{
  99. kube: kube,
  100. store: vaultSpec,
  101. log: ctrl.Log.WithName("provider").WithName("vault"),
  102. namespace: namespace,
  103. storeKind: store.GetObjectKind().GroupVersionKind().Kind,
  104. }
  105. cfg, err := vStore.newConfig()
  106. if err != nil {
  107. return nil, err
  108. }
  109. client, err := c.newVaultClient(cfg)
  110. if err != nil {
  111. return nil, fmt.Errorf(errVaultClient, err)
  112. }
  113. if vaultSpec.Namespace != nil {
  114. client.SetNamespace(*vaultSpec.Namespace)
  115. }
  116. if err := vStore.setAuth(ctx, client, cfg); err != nil {
  117. return nil, err
  118. }
  119. vStore.client = client
  120. return vStore, nil
  121. }
  122. func (v *client) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error) {
  123. data, err := v.readSecret(ctx, ref.Key, ref.Version)
  124. if err != nil {
  125. return nil, err
  126. }
  127. value, exists := data[ref.Property]
  128. if !exists {
  129. return nil, fmt.Errorf(errSecretKeyFmt, ref.Property)
  130. }
  131. return value, nil
  132. }
  133. func (v *client) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
  134. return v.readSecret(ctx, ref.Key, ref.Version)
  135. }
  136. func (v *client) Close(ctx context.Context) error {
  137. // Revoke the token if we have one set and it wasn't sourced from a TokenSecretRef
  138. if v.client.Token() != "" && v.store.Auth.TokenSecretRef == nil {
  139. req := v.client.NewRequest(http.MethodPost, "/v1/auth/token/revoke-self")
  140. _, err := v.client.RawRequestWithContext(ctx, req)
  141. if err != nil {
  142. return fmt.Errorf(errVaultRevokeToken, err)
  143. }
  144. v.client.ClearToken()
  145. }
  146. return nil
  147. }
  148. func (v *client) readSecret(ctx context.Context, path, version string) (map[string][]byte, error) {
  149. kvPath := v.store.Path
  150. if v.store.Version == esv1alpha1.VaultKVStoreV2 {
  151. if !strings.HasSuffix(kvPath, "/data") {
  152. kvPath = fmt.Sprintf("%s/data", kvPath)
  153. }
  154. }
  155. // path formated according to vault docs for v1 and v2 API
  156. // v1: https://www.vaultproject.io/api-docs/secret/kv/kv-v1#read-secret
  157. // v2: https://www.vaultproject.io/api/secret/kv/kv-v2#read-secret-version
  158. req := v.client.NewRequest(http.MethodGet, fmt.Sprintf("/v1/%s/%s", kvPath, path))
  159. if version != "" {
  160. req.Params.Set("version", version)
  161. }
  162. resp, err := v.client.RawRequestWithContext(ctx, req)
  163. if err != nil {
  164. return nil, fmt.Errorf(errReadSecret, err)
  165. }
  166. vaultSecret, err := vault.ParseSecret(resp.Body)
  167. if err != nil {
  168. return nil, err
  169. }
  170. secretData := vaultSecret.Data
  171. if v.store.Version == esv1alpha1.VaultKVStoreV2 {
  172. // Vault KV2 has data embedded within sub-field
  173. // reference - https://www.vaultproject.io/api/secret/kv/kv-v2#read-secret-version
  174. dataInt, ok := vaultSecret.Data["data"]
  175. if !ok {
  176. return nil, errors.New(errDataField)
  177. }
  178. secretData, ok = dataInt.(map[string]interface{})
  179. if !ok {
  180. return nil, errors.New(errJSONUnmarshall)
  181. }
  182. }
  183. byteMap := make(map[string][]byte, len(secretData))
  184. for k, v := range secretData {
  185. if v == nil {
  186. continue
  187. }
  188. switch t := v.(type) {
  189. case string:
  190. byteMap[k] = []byte(t)
  191. case []byte:
  192. byteMap[k] = t
  193. default:
  194. return nil, errors.New(errSecretFormat)
  195. }
  196. }
  197. return byteMap, nil
  198. }
  199. func (v *client) newConfig() (*vault.Config, error) {
  200. cfg := vault.DefaultConfig()
  201. cfg.Address = v.store.Server
  202. if len(v.store.CABundle) == 0 && v.store.CAProvider == nil {
  203. return cfg, nil
  204. }
  205. caCertPool := x509.NewCertPool()
  206. if len(v.store.CABundle) > 0 {
  207. ok := caCertPool.AppendCertsFromPEM(v.store.CABundle)
  208. if !ok {
  209. return nil, errors.New(errVaultCert)
  210. }
  211. }
  212. if v.store.CAProvider != nil {
  213. var cert []byte
  214. var err error
  215. switch v.store.CAProvider.Type {
  216. case esv1alpha1.CAProviderTypeSecret:
  217. cert, err = getCertFromSecret(v)
  218. case esv1alpha1.CAProviderTypeConfigMap:
  219. cert, err = getCertFromConfigMap(v)
  220. default:
  221. return nil, errors.New(errUnknownCAProvider)
  222. }
  223. if err != nil {
  224. return nil, err
  225. }
  226. ok := caCertPool.AppendCertsFromPEM(cert)
  227. if !ok {
  228. return nil, errors.New(errVaultCert)
  229. }
  230. }
  231. if transport, ok := cfg.HttpClient.Transport.(*http.Transport); ok {
  232. transport.TLSClientConfig.RootCAs = caCertPool
  233. }
  234. return cfg, nil
  235. }
  236. func getCertFromSecret(v *client) ([]byte, error) {
  237. secretRef := esmeta.SecretKeySelector{
  238. Name: v.store.CAProvider.Name,
  239. Namespace: &v.store.CAProvider.Namespace,
  240. Key: v.store.CAProvider.Key,
  241. }
  242. ctx := context.Background()
  243. res, err := v.secretKeyRef(ctx, &secretRef)
  244. if err != nil {
  245. return nil, fmt.Errorf(errVaultCert, err)
  246. }
  247. return []byte(res), nil
  248. }
  249. func getCertFromConfigMap(v *client) ([]byte, error) {
  250. objKey := types.NamespacedName{
  251. Namespace: v.store.CAProvider.Namespace,
  252. Name: v.store.CAProvider.Name,
  253. }
  254. configMapRef := &corev1.ConfigMap{}
  255. ctx := context.Background()
  256. err := v.kube.Get(ctx, objKey, configMapRef)
  257. if err != nil {
  258. return nil, fmt.Errorf(errVaultCert, err)
  259. }
  260. val, ok := configMapRef.Data[v.store.CAProvider.Key]
  261. if !ok {
  262. return nil, fmt.Errorf(errConfigMapFmt, v.store.CAProvider.Key)
  263. }
  264. return []byte(val), nil
  265. }
  266. func (v *client) setAuth(ctx context.Context, client Client, cfg *vault.Config) error {
  267. tokenExists, err := setSecretKeyToken(ctx, v, client)
  268. if tokenExists {
  269. return err
  270. }
  271. tokenExists, err = setAppRoleToken(ctx, v, client)
  272. if tokenExists {
  273. return err
  274. }
  275. tokenExists, err = setKubernetesAuthToken(ctx, v, client)
  276. if tokenExists {
  277. return err
  278. }
  279. tokenExists, err = setLdapAuthToken(ctx, v, client)
  280. if tokenExists {
  281. return err
  282. }
  283. tokenExists, err = setJwtAuthToken(ctx, v, client)
  284. if tokenExists {
  285. return err
  286. }
  287. tokenExists, err = setCertAuthToken(ctx, v, client, cfg)
  288. if tokenExists {
  289. return err
  290. }
  291. return errors.New(errAuthFormat)
  292. }
  293. func setAppRoleToken(ctx context.Context, v *client, client Client) (bool, error) {
  294. tokenRef := v.store.Auth.TokenSecretRef
  295. if tokenRef != nil {
  296. token, err := v.secretKeyRef(ctx, tokenRef)
  297. if err != nil {
  298. return true, err
  299. }
  300. client.SetToken(token)
  301. return true, nil
  302. }
  303. return false, nil
  304. }
  305. func setSecretKeyToken(ctx context.Context, v *client, client Client) (bool, error) {
  306. appRole := v.store.Auth.AppRole
  307. if appRole != nil {
  308. token, err := v.requestTokenWithAppRoleRef(ctx, client, appRole)
  309. if err != nil {
  310. return true, err
  311. }
  312. client.SetToken(token)
  313. return true, nil
  314. }
  315. return false, nil
  316. }
  317. func setKubernetesAuthToken(ctx context.Context, v *client, client Client) (bool, error) {
  318. kubernetesAuth := v.store.Auth.Kubernetes
  319. if kubernetesAuth != nil {
  320. token, err := v.requestTokenWithKubernetesAuth(ctx, client, kubernetesAuth)
  321. if err != nil {
  322. return true, err
  323. }
  324. client.SetToken(token)
  325. return true, nil
  326. }
  327. return false, nil
  328. }
  329. func setLdapAuthToken(ctx context.Context, v *client, client Client) (bool, error) {
  330. ldapAuth := v.store.Auth.Ldap
  331. if ldapAuth != nil {
  332. token, err := v.requestTokenWithLdapAuth(ctx, client, ldapAuth)
  333. if err != nil {
  334. return true, err
  335. }
  336. client.SetToken(token)
  337. return true, nil
  338. }
  339. return false, nil
  340. }
  341. func setJwtAuthToken(ctx context.Context, v *client, client Client) (bool, error) {
  342. jwtAuth := v.store.Auth.Jwt
  343. if jwtAuth != nil {
  344. token, err := v.requestTokenWithJwtAuth(ctx, client, jwtAuth)
  345. if err != nil {
  346. return true, err
  347. }
  348. client.SetToken(token)
  349. return true, nil
  350. }
  351. return false, nil
  352. }
  353. func setCertAuthToken(ctx context.Context, v *client, client Client, cfg *vault.Config) (bool, error) {
  354. certAuth := v.store.Auth.Cert
  355. if certAuth != nil {
  356. token, err := v.requestTokenWithCertAuth(ctx, client, certAuth, cfg)
  357. if err != nil {
  358. return true, err
  359. }
  360. client.SetToken(token)
  361. return true, nil
  362. }
  363. return false, nil
  364. }
  365. func (v *client) secretKeyRefForServiceAccount(ctx context.Context, serviceAccountRef *esmeta.ServiceAccountSelector) (string, error) {
  366. serviceAccount := &corev1.ServiceAccount{}
  367. ref := types.NamespacedName{
  368. Namespace: v.namespace,
  369. Name: serviceAccountRef.Name,
  370. }
  371. if (v.storeKind == esv1alpha1.ClusterSecretStoreKind) &&
  372. (serviceAccountRef.Namespace != nil) {
  373. ref.Namespace = *serviceAccountRef.Namespace
  374. }
  375. err := v.kube.Get(ctx, ref, serviceAccount)
  376. if err != nil {
  377. return "", fmt.Errorf(errGetKubeSA, ref.Name, err)
  378. }
  379. if len(serviceAccount.Secrets) == 0 {
  380. return "", fmt.Errorf(errGetKubeSASecrets, ref.Name)
  381. }
  382. for _, tokenRef := range serviceAccount.Secrets {
  383. retval, err := v.secretKeyRef(ctx, &esmeta.SecretKeySelector{
  384. Name: tokenRef.Name,
  385. Namespace: &ref.Namespace,
  386. Key: "token",
  387. })
  388. if err != nil {
  389. continue
  390. }
  391. return retval, nil
  392. }
  393. return "", fmt.Errorf(errGetKubeSANoToken, ref.Name)
  394. }
  395. func (v *client) secretKeyRef(ctx context.Context, secretRef *esmeta.SecretKeySelector) (string, error) {
  396. secret := &corev1.Secret{}
  397. ref := types.NamespacedName{
  398. Namespace: v.namespace,
  399. Name: secretRef.Name,
  400. }
  401. if (v.storeKind == esv1alpha1.ClusterSecretStoreKind) &&
  402. (secretRef.Namespace != nil) {
  403. ref.Namespace = *secretRef.Namespace
  404. }
  405. err := v.kube.Get(ctx, ref, secret)
  406. if err != nil {
  407. return "", fmt.Errorf(errGetKubeSecret, ref.Name, err)
  408. }
  409. keyBytes, ok := secret.Data[secretRef.Key]
  410. if !ok {
  411. return "", fmt.Errorf(errSecretKeyFmt, secretRef.Key)
  412. }
  413. value := string(keyBytes)
  414. valueStr := strings.TrimSpace(value)
  415. return valueStr, nil
  416. }
  417. // appRoleParameters creates the required body for Vault AppRole Auth.
  418. // Reference - https://www.vaultproject.io/api-docs/auth/approle#login-with-approle
  419. func appRoleParameters(role, secret string) map[string]string {
  420. return map[string]string{
  421. "role_id": role,
  422. "secret_id": secret,
  423. }
  424. }
  425. func (v *client) requestTokenWithAppRoleRef(ctx context.Context, client Client, appRole *esv1alpha1.VaultAppRole) (string, error) {
  426. roleID := strings.TrimSpace(appRole.RoleID)
  427. secretID, err := v.secretKeyRef(ctx, &appRole.SecretRef)
  428. if err != nil {
  429. return "", err
  430. }
  431. parameters := appRoleParameters(roleID, secretID)
  432. url := strings.Join([]string{"/v1", "auth", appRole.Path, "login"}, "/")
  433. request := client.NewRequest("POST", url)
  434. err = request.SetJSONBody(parameters)
  435. if err != nil {
  436. return "", fmt.Errorf(errVaultReqParams, err)
  437. }
  438. resp, err := client.RawRequestWithContext(ctx, request)
  439. if err != nil {
  440. return "", fmt.Errorf(errVaultRequest, err)
  441. }
  442. defer resp.Body.Close()
  443. vaultResult := vault.Secret{}
  444. if err = resp.DecodeJSON(&vaultResult); err != nil {
  445. return "", fmt.Errorf(errVaultResponse, err)
  446. }
  447. token, err := vaultResult.TokenID()
  448. if err != nil {
  449. return "", fmt.Errorf(errVaultToken, err)
  450. }
  451. return token, nil
  452. }
  453. // kubeParameters creates the required body for Vault Kubernetes auth.
  454. // Reference - https://www.vaultproject.io/api/auth/kubernetes#login
  455. func kubeParameters(role, jwt string) map[string]string {
  456. return map[string]string{
  457. "role": role,
  458. "jwt": jwt,
  459. }
  460. }
  461. func (v *client) requestTokenWithKubernetesAuth(ctx context.Context, client Client, kubernetesAuth *esv1alpha1.VaultKubernetesAuth) (string, error) {
  462. jwtString, err := getJwtString(ctx, v, kubernetesAuth)
  463. if err != nil {
  464. return "", err
  465. }
  466. parameters := kubeParameters(kubernetesAuth.Role, jwtString)
  467. url := strings.Join([]string{"/v1", "auth", kubernetesAuth.Path, "login"}, "/")
  468. request := client.NewRequest("POST", url)
  469. err = request.SetJSONBody(parameters)
  470. if err != nil {
  471. return "", fmt.Errorf(errVaultReqParams, err)
  472. }
  473. resp, err := client.RawRequestWithContext(ctx, request)
  474. if err != nil {
  475. return "", fmt.Errorf(errVaultRequest, err)
  476. }
  477. defer resp.Body.Close()
  478. vaultResult := vault.Secret{}
  479. err = resp.DecodeJSON(&vaultResult)
  480. if err != nil {
  481. return "", fmt.Errorf(errVaultResponse, err)
  482. }
  483. token, err := vaultResult.TokenID()
  484. if err != nil {
  485. return "", fmt.Errorf(errVaultToken, err)
  486. }
  487. return token, nil
  488. }
  489. func getJwtString(ctx context.Context, v *client, kubernetesAuth *esv1alpha1.VaultKubernetesAuth) (string, error) {
  490. if kubernetesAuth.ServiceAccountRef != nil {
  491. jwt, err := v.secretKeyRefForServiceAccount(ctx, kubernetesAuth.ServiceAccountRef)
  492. if err != nil {
  493. return "", err
  494. }
  495. return jwt, nil
  496. } else if kubernetesAuth.SecretRef != nil {
  497. tokenRef := kubernetesAuth.SecretRef
  498. if tokenRef.Key == "" {
  499. tokenRef = kubernetesAuth.SecretRef.DeepCopy()
  500. tokenRef.Key = "token"
  501. }
  502. jwt, err := v.secretKeyRef(ctx, tokenRef)
  503. if err != nil {
  504. return "", err
  505. }
  506. return jwt, nil
  507. } else {
  508. // Kubernetes authentication is specified, but without a referenced
  509. // Kubernetes secret. We check if the file path for in-cluster service account
  510. // exists and attempt to use the token for Vault Kubernetes auth.
  511. if _, err := os.Stat(serviceAccTokenPath); err != nil {
  512. return "", fmt.Errorf(errServiceAccount, err)
  513. }
  514. jwtByte, err := ioutil.ReadFile(serviceAccTokenPath)
  515. if err != nil {
  516. return "", fmt.Errorf(errServiceAccount, err)
  517. }
  518. return string(jwtByte), nil
  519. }
  520. }
  521. func (v *client) requestTokenWithLdapAuth(ctx context.Context, client Client, ldapAuth *esv1alpha1.VaultLdapAuth) (string, error) {
  522. username := strings.TrimSpace(ldapAuth.Username)
  523. password, err := v.secretKeyRef(ctx, &ldapAuth.SecretRef)
  524. if err != nil {
  525. return "", err
  526. }
  527. parameters := map[string]string{
  528. "password": password,
  529. }
  530. url := strings.Join([]string{"/v1", "auth", "ldap", "login", username}, "/")
  531. request := client.NewRequest("POST", url)
  532. err = request.SetJSONBody(parameters)
  533. if err != nil {
  534. return "", fmt.Errorf(errVaultReqParams, err)
  535. }
  536. resp, err := client.RawRequestWithContext(ctx, request)
  537. if err != nil {
  538. return "", fmt.Errorf(errVaultRequest, err)
  539. }
  540. defer resp.Body.Close()
  541. vaultResult := vault.Secret{}
  542. if err = resp.DecodeJSON(&vaultResult); err != nil {
  543. return "", fmt.Errorf(errVaultResponse, err)
  544. }
  545. token, err := vaultResult.TokenID()
  546. if err != nil {
  547. return "", fmt.Errorf(errVaultToken, err)
  548. }
  549. return token, nil
  550. }
  551. func (v *client) requestTokenWithJwtAuth(ctx context.Context, client Client, jwtAuth *esv1alpha1.VaultJwtAuth) (string, error) {
  552. role := strings.TrimSpace(jwtAuth.Role)
  553. jwt, err := v.secretKeyRef(ctx, &jwtAuth.SecretRef)
  554. if err != nil {
  555. return "", err
  556. }
  557. parameters := map[string]string{
  558. "role": role,
  559. "jwt": jwt,
  560. }
  561. url := strings.Join([]string{"/v1", "auth", "jwt", "login"}, "/")
  562. request := client.NewRequest("POST", url)
  563. err = request.SetJSONBody(parameters)
  564. if err != nil {
  565. return "", fmt.Errorf(errVaultReqParams, err)
  566. }
  567. resp, err := client.RawRequestWithContext(ctx, request)
  568. if err != nil {
  569. return "", fmt.Errorf(errVaultRequest, err)
  570. }
  571. defer resp.Body.Close()
  572. vaultResult := vault.Secret{}
  573. if err = resp.DecodeJSON(&vaultResult); err != nil {
  574. return "", fmt.Errorf(errVaultResponse, err)
  575. }
  576. token, err := vaultResult.TokenID()
  577. if err != nil {
  578. return "", fmt.Errorf(errVaultToken, err)
  579. }
  580. return token, nil
  581. }
  582. func (v *client) requestTokenWithCertAuth(ctx context.Context, client Client, certAuth *esv1alpha1.VaultCertAuth, cfg *vault.Config) (string, error) {
  583. clientKey, err := v.secretKeyRef(ctx, &certAuth.SecretRef)
  584. if err != nil {
  585. return "", err
  586. }
  587. clientCert, err := v.secretKeyRef(ctx, &certAuth.ClientCert)
  588. if err != nil {
  589. return "", err
  590. }
  591. cert, err := tls.X509KeyPair([]byte(clientCert), []byte(clientKey))
  592. if err != nil {
  593. return "", fmt.Errorf(errClientTLSAuth, err)
  594. }
  595. if transport, ok := cfg.HttpClient.Transport.(*http.Transport); ok {
  596. transport.TLSClientConfig.Certificates = []tls.Certificate{cert}
  597. }
  598. url := strings.Join([]string{"/v1", "auth", "cert", "login"}, "/")
  599. request := client.NewRequest("POST", url)
  600. resp, err := client.RawRequestWithContext(ctx, request)
  601. if err != nil {
  602. return "", fmt.Errorf(errVaultRequest, err)
  603. }
  604. defer resp.Body.Close()
  605. vaultResult := vault.Secret{}
  606. if err = resp.DecodeJSON(&vaultResult); err != nil {
  607. return "", fmt.Errorf(errVaultResponse, err)
  608. }
  609. token, err := vaultResult.TokenID()
  610. if err != nil {
  611. return "", fmt.Errorf(errVaultToken, err)
  612. }
  613. return token, nil
  614. }