vault.go 21 KB

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