vault.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
  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. switch t := v.(type) {
  186. case string:
  187. byteMap[k] = []byte(t)
  188. case []byte:
  189. byteMap[k] = t
  190. case nil:
  191. byteMap[k] = []byte(nil)
  192. default:
  193. return nil, errors.New(errSecretFormat)
  194. }
  195. }
  196. return byteMap, nil
  197. }
  198. func (v *client) newConfig() (*vault.Config, error) {
  199. cfg := vault.DefaultConfig()
  200. cfg.Address = v.store.Server
  201. if len(v.store.CABundle) == 0 && v.store.CAProvider == nil {
  202. return cfg, nil
  203. }
  204. caCertPool := x509.NewCertPool()
  205. if len(v.store.CABundle) > 0 {
  206. ok := caCertPool.AppendCertsFromPEM(v.store.CABundle)
  207. if !ok {
  208. return nil, errors.New(errVaultCert)
  209. }
  210. }
  211. if v.store.CAProvider != nil {
  212. var cert []byte
  213. var err error
  214. switch v.store.CAProvider.Type {
  215. case esv1alpha1.CAProviderTypeSecret:
  216. cert, err = getCertFromSecret(v)
  217. case esv1alpha1.CAProviderTypeConfigMap:
  218. cert, err = getCertFromConfigMap(v)
  219. default:
  220. return nil, errors.New(errUnknownCAProvider)
  221. }
  222. if err != nil {
  223. return nil, err
  224. }
  225. ok := caCertPool.AppendCertsFromPEM(cert)
  226. if !ok {
  227. return nil, errors.New(errVaultCert)
  228. }
  229. }
  230. if transport, ok := cfg.HttpClient.Transport.(*http.Transport); ok {
  231. transport.TLSClientConfig.RootCAs = caCertPool
  232. }
  233. return cfg, nil
  234. }
  235. func getCertFromSecret(v *client) ([]byte, error) {
  236. secretRef := esmeta.SecretKeySelector{
  237. Name: v.store.CAProvider.Name,
  238. Namespace: &v.store.CAProvider.Namespace,
  239. Key: v.store.CAProvider.Key,
  240. }
  241. ctx := context.Background()
  242. res, err := v.secretKeyRef(ctx, &secretRef)
  243. if err != nil {
  244. return nil, fmt.Errorf(errVaultCert, err)
  245. }
  246. return []byte(res), nil
  247. }
  248. func getCertFromConfigMap(v *client) ([]byte, error) {
  249. objKey := types.NamespacedName{
  250. Namespace: v.store.CAProvider.Namespace,
  251. Name: v.store.CAProvider.Name,
  252. }
  253. configMapRef := &corev1.ConfigMap{}
  254. ctx := context.Background()
  255. err := v.kube.Get(ctx, objKey, configMapRef)
  256. if err != nil {
  257. return nil, fmt.Errorf(errVaultCert, err)
  258. }
  259. val, ok := configMapRef.Data[v.store.CAProvider.Key]
  260. if !ok {
  261. return nil, fmt.Errorf(errConfigMapFmt, v.store.CAProvider.Key)
  262. }
  263. return []byte(val), nil
  264. }
  265. func (v *client) setAuth(ctx context.Context, client Client, cfg *vault.Config) error {
  266. tokenExists, err := setSecretKeyToken(ctx, v, client)
  267. if tokenExists {
  268. return err
  269. }
  270. tokenExists, err = setAppRoleToken(ctx, v, client)
  271. if tokenExists {
  272. return err
  273. }
  274. tokenExists, err = setKubernetesAuthToken(ctx, v, client)
  275. if tokenExists {
  276. return err
  277. }
  278. tokenExists, err = setLdapAuthToken(ctx, v, client)
  279. if tokenExists {
  280. return err
  281. }
  282. tokenExists, err = setJwtAuthToken(ctx, v, client)
  283. if tokenExists {
  284. return err
  285. }
  286. tokenExists, err = setCertAuthToken(ctx, v, client, cfg)
  287. if tokenExists {
  288. return err
  289. }
  290. return errors.New(errAuthFormat)
  291. }
  292. func setAppRoleToken(ctx context.Context, v *client, client Client) (bool, error) {
  293. tokenRef := v.store.Auth.TokenSecretRef
  294. if tokenRef != nil {
  295. token, err := v.secretKeyRef(ctx, tokenRef)
  296. if err != nil {
  297. return true, err
  298. }
  299. client.SetToken(token)
  300. return true, nil
  301. }
  302. return false, nil
  303. }
  304. func setSecretKeyToken(ctx context.Context, v *client, client Client) (bool, error) {
  305. appRole := v.store.Auth.AppRole
  306. if appRole != nil {
  307. token, err := v.requestTokenWithAppRoleRef(ctx, client, appRole)
  308. if err != nil {
  309. return true, err
  310. }
  311. client.SetToken(token)
  312. return true, nil
  313. }
  314. return false, nil
  315. }
  316. func setKubernetesAuthToken(ctx context.Context, v *client, client Client) (bool, error) {
  317. kubernetesAuth := v.store.Auth.Kubernetes
  318. if kubernetesAuth != nil {
  319. token, err := v.requestTokenWithKubernetesAuth(ctx, client, kubernetesAuth)
  320. if err != nil {
  321. return true, err
  322. }
  323. client.SetToken(token)
  324. return true, nil
  325. }
  326. return false, nil
  327. }
  328. func setLdapAuthToken(ctx context.Context, v *client, client Client) (bool, error) {
  329. ldapAuth := v.store.Auth.Ldap
  330. if ldapAuth != nil {
  331. token, err := v.requestTokenWithLdapAuth(ctx, client, ldapAuth)
  332. if err != nil {
  333. return true, err
  334. }
  335. client.SetToken(token)
  336. return true, nil
  337. }
  338. return false, nil
  339. }
  340. func setJwtAuthToken(ctx context.Context, v *client, client Client) (bool, error) {
  341. jwtAuth := v.store.Auth.Jwt
  342. if jwtAuth != nil {
  343. token, err := v.requestTokenWithJwtAuth(ctx, client, jwtAuth)
  344. if err != nil {
  345. return true, err
  346. }
  347. client.SetToken(token)
  348. return true, nil
  349. }
  350. return false, nil
  351. }
  352. func setCertAuthToken(ctx context.Context, v *client, client Client, cfg *vault.Config) (bool, error) {
  353. certAuth := v.store.Auth.Cert
  354. if certAuth != nil {
  355. token, err := v.requestTokenWithCertAuth(ctx, client, certAuth, cfg)
  356. if err != nil {
  357. return true, err
  358. }
  359. client.SetToken(token)
  360. return true, nil
  361. }
  362. return false, nil
  363. }
  364. func (v *client) secretKeyRefForServiceAccount(ctx context.Context, serviceAccountRef *esmeta.ServiceAccountSelector) (string, error) {
  365. serviceAccount := &corev1.ServiceAccount{}
  366. ref := types.NamespacedName{
  367. Namespace: v.namespace,
  368. Name: serviceAccountRef.Name,
  369. }
  370. if (v.storeKind == esv1alpha1.ClusterSecretStoreKind) &&
  371. (serviceAccountRef.Namespace != nil) {
  372. ref.Namespace = *serviceAccountRef.Namespace
  373. }
  374. err := v.kube.Get(ctx, ref, serviceAccount)
  375. if err != nil {
  376. return "", fmt.Errorf(errGetKubeSA, ref.Name, err)
  377. }
  378. if len(serviceAccount.Secrets) == 0 {
  379. return "", fmt.Errorf(errGetKubeSASecrets, ref.Name)
  380. }
  381. for _, tokenRef := range serviceAccount.Secrets {
  382. retval, err := v.secretKeyRef(ctx, &esmeta.SecretKeySelector{
  383. Name: tokenRef.Name,
  384. Namespace: &ref.Namespace,
  385. Key: "token",
  386. })
  387. if err != nil {
  388. continue
  389. }
  390. return retval, nil
  391. }
  392. return "", fmt.Errorf(errGetKubeSANoToken, ref.Name)
  393. }
  394. func (v *client) secretKeyRef(ctx context.Context, secretRef *esmeta.SecretKeySelector) (string, error) {
  395. secret := &corev1.Secret{}
  396. ref := types.NamespacedName{
  397. Namespace: v.namespace,
  398. Name: secretRef.Name,
  399. }
  400. if (v.storeKind == esv1alpha1.ClusterSecretStoreKind) &&
  401. (secretRef.Namespace != nil) {
  402. ref.Namespace = *secretRef.Namespace
  403. }
  404. err := v.kube.Get(ctx, ref, secret)
  405. if err != nil {
  406. return "", fmt.Errorf(errGetKubeSecret, ref.Name, err)
  407. }
  408. keyBytes, ok := secret.Data[secretRef.Key]
  409. if !ok {
  410. return "", fmt.Errorf(errSecretKeyFmt, secretRef.Key)
  411. }
  412. value := string(keyBytes)
  413. valueStr := strings.TrimSpace(value)
  414. return valueStr, nil
  415. }
  416. // appRoleParameters creates the required body for Vault AppRole Auth.
  417. // Reference - https://www.vaultproject.io/api-docs/auth/approle#login-with-approle
  418. func appRoleParameters(role, secret string) map[string]string {
  419. return map[string]string{
  420. "role_id": role,
  421. "secret_id": secret,
  422. }
  423. }
  424. func (v *client) requestTokenWithAppRoleRef(ctx context.Context, client Client, appRole *esv1alpha1.VaultAppRole) (string, error) {
  425. roleID := strings.TrimSpace(appRole.RoleID)
  426. secretID, err := v.secretKeyRef(ctx, &appRole.SecretRef)
  427. if err != nil {
  428. return "", err
  429. }
  430. parameters := appRoleParameters(roleID, secretID)
  431. url := strings.Join([]string{"/v1", "auth", appRole.Path, "login"}, "/")
  432. request := client.NewRequest("POST", url)
  433. err = request.SetJSONBody(parameters)
  434. if err != nil {
  435. return "", fmt.Errorf(errVaultReqParams, err)
  436. }
  437. resp, err := client.RawRequestWithContext(ctx, request)
  438. if err != nil {
  439. return "", fmt.Errorf(errVaultRequest, err)
  440. }
  441. defer resp.Body.Close()
  442. vaultResult := vault.Secret{}
  443. if err = resp.DecodeJSON(&vaultResult); err != nil {
  444. return "", fmt.Errorf(errVaultResponse, err)
  445. }
  446. token, err := vaultResult.TokenID()
  447. if err != nil {
  448. return "", fmt.Errorf(errVaultToken, err)
  449. }
  450. return token, nil
  451. }
  452. // kubeParameters creates the required body for Vault Kubernetes auth.
  453. // Reference - https://www.vaultproject.io/api/auth/kubernetes#login
  454. func kubeParameters(role, jwt string) map[string]string {
  455. return map[string]string{
  456. "role": role,
  457. "jwt": jwt,
  458. }
  459. }
  460. func (v *client) requestTokenWithKubernetesAuth(ctx context.Context, client Client, kubernetesAuth *esv1alpha1.VaultKubernetesAuth) (string, error) {
  461. jwtString, err := getJwtString(ctx, v, kubernetesAuth)
  462. if err != nil {
  463. return "", err
  464. }
  465. parameters := kubeParameters(kubernetesAuth.Role, jwtString)
  466. url := strings.Join([]string{"/v1", "auth", kubernetesAuth.Path, "login"}, "/")
  467. request := client.NewRequest("POST", url)
  468. err = request.SetJSONBody(parameters)
  469. if err != nil {
  470. return "", fmt.Errorf(errVaultReqParams, err)
  471. }
  472. resp, err := client.RawRequestWithContext(ctx, request)
  473. if err != nil {
  474. return "", fmt.Errorf(errVaultRequest, err)
  475. }
  476. defer resp.Body.Close()
  477. vaultResult := vault.Secret{}
  478. err = resp.DecodeJSON(&vaultResult)
  479. if err != nil {
  480. return "", fmt.Errorf(errVaultResponse, err)
  481. }
  482. token, err := vaultResult.TokenID()
  483. if err != nil {
  484. return "", fmt.Errorf(errVaultToken, err)
  485. }
  486. return token, nil
  487. }
  488. func getJwtString(ctx context.Context, v *client, kubernetesAuth *esv1alpha1.VaultKubernetesAuth) (string, error) {
  489. if kubernetesAuth.ServiceAccountRef != nil {
  490. jwt, err := v.secretKeyRefForServiceAccount(ctx, kubernetesAuth.ServiceAccountRef)
  491. if err != nil {
  492. return "", err
  493. }
  494. return jwt, nil
  495. } else if kubernetesAuth.SecretRef != nil {
  496. tokenRef := kubernetesAuth.SecretRef
  497. if tokenRef.Key == "" {
  498. tokenRef = kubernetesAuth.SecretRef.DeepCopy()
  499. tokenRef.Key = "token"
  500. }
  501. jwt, err := v.secretKeyRef(ctx, tokenRef)
  502. if err != nil {
  503. return "", err
  504. }
  505. return jwt, nil
  506. } else {
  507. // Kubernetes authentication is specified, but without a referenced
  508. // Kubernetes secret. We check if the file path for in-cluster service account
  509. // exists and attempt to use the token for Vault Kubernetes auth.
  510. if _, err := os.Stat(serviceAccTokenPath); err != nil {
  511. return "", fmt.Errorf(errServiceAccount, err)
  512. }
  513. jwtByte, err := ioutil.ReadFile(serviceAccTokenPath)
  514. if err != nil {
  515. return "", fmt.Errorf(errServiceAccount, err)
  516. }
  517. return string(jwtByte), nil
  518. }
  519. }
  520. func (v *client) requestTokenWithLdapAuth(ctx context.Context, client Client, ldapAuth *esv1alpha1.VaultLdapAuth) (string, error) {
  521. username := strings.TrimSpace(ldapAuth.Username)
  522. password, err := v.secretKeyRef(ctx, &ldapAuth.SecretRef)
  523. if err != nil {
  524. return "", err
  525. }
  526. parameters := map[string]string{
  527. "password": password,
  528. }
  529. url := strings.Join([]string{"/v1", "auth", "ldap", "login", username}, "/")
  530. request := client.NewRequest("POST", url)
  531. err = request.SetJSONBody(parameters)
  532. if err != nil {
  533. return "", fmt.Errorf(errVaultReqParams, err)
  534. }
  535. resp, err := client.RawRequestWithContext(ctx, request)
  536. if err != nil {
  537. return "", fmt.Errorf(errVaultRequest, err)
  538. }
  539. defer resp.Body.Close()
  540. vaultResult := vault.Secret{}
  541. if err = resp.DecodeJSON(&vaultResult); err != nil {
  542. return "", fmt.Errorf(errVaultResponse, err)
  543. }
  544. token, err := vaultResult.TokenID()
  545. if err != nil {
  546. return "", fmt.Errorf(errVaultToken, err)
  547. }
  548. return token, nil
  549. }
  550. func (v *client) requestTokenWithJwtAuth(ctx context.Context, client Client, jwtAuth *esv1alpha1.VaultJwtAuth) (string, error) {
  551. role := strings.TrimSpace(jwtAuth.Role)
  552. jwt, err := v.secretKeyRef(ctx, &jwtAuth.SecretRef)
  553. if err != nil {
  554. return "", err
  555. }
  556. parameters := map[string]string{
  557. "role": role,
  558. "jwt": jwt,
  559. }
  560. url := strings.Join([]string{"/v1", "auth", "jwt", "login"}, "/")
  561. request := client.NewRequest("POST", url)
  562. err = request.SetJSONBody(parameters)
  563. if err != nil {
  564. return "", fmt.Errorf(errVaultReqParams, err)
  565. }
  566. resp, err := client.RawRequestWithContext(ctx, request)
  567. if err != nil {
  568. return "", fmt.Errorf(errVaultRequest, err)
  569. }
  570. defer resp.Body.Close()
  571. vaultResult := vault.Secret{}
  572. if err = resp.DecodeJSON(&vaultResult); err != nil {
  573. return "", fmt.Errorf(errVaultResponse, err)
  574. }
  575. token, err := vaultResult.TokenID()
  576. if err != nil {
  577. return "", fmt.Errorf(errVaultToken, err)
  578. }
  579. return token, nil
  580. }
  581. func (v *client) requestTokenWithCertAuth(ctx context.Context, client Client, certAuth *esv1alpha1.VaultCertAuth, cfg *vault.Config) (string, error) {
  582. clientKey, err := v.secretKeyRef(ctx, &certAuth.SecretRef)
  583. if err != nil {
  584. return "", err
  585. }
  586. clientCert, err := v.secretKeyRef(ctx, &certAuth.ClientCert)
  587. if err != nil {
  588. return "", err
  589. }
  590. cert, err := tls.X509KeyPair([]byte(clientCert), []byte(clientKey))
  591. if err != nil {
  592. return "", fmt.Errorf(errClientTLSAuth, err)
  593. }
  594. if transport, ok := cfg.HttpClient.Transport.(*http.Transport); ok {
  595. transport.TLSClientConfig.Certificates = []tls.Certificate{cert}
  596. }
  597. url := strings.Join([]string{"/v1", "auth", "cert", "login"}, "/")
  598. request := client.NewRequest("POST", url)
  599. resp, err := client.RawRequestWithContext(ctx, request)
  600. if err != nil {
  601. return "", fmt.Errorf(errVaultRequest, err)
  602. }
  603. defer resp.Body.Close()
  604. vaultResult := vault.Secret{}
  605. if err = resp.DecodeJSON(&vaultResult); err != nil {
  606. return "", fmt.Errorf(errVaultResponse, err)
  607. }
  608. token, err := vaultResult.TokenID()
  609. if err != nil {
  610. return "", fmt.Errorf(errVaultToken, err)
  611. }
  612. return token, nil
  613. }