spring-cloud / spring-cloud-vault

Configuration Integration with HashiCorp Vault
http://cloud.spring.io/spring-cloud-vault/
Apache License 2.0
273 stars 152 forks source link

Support for bound service account tokens in Kubernetes Auth method #491

Closed kawsark closed 3 years ago

kawsark commented 3 years ago

Is your feature request related to a problem? Please describe.

Kubernetes 1.12 introduced Service Account Token Volume Projection into Pods as Beta capability. This allows for periodic rotation of the JWT Token of a Service account which is a security requirement in many organizations.

This feature request is to ensure that Spring Cloud Vault can properly Authenticate to Vault when using the Kubernetes Auth method.

HashiCorp Vault added support for this by having issuer and iss validation as part of the Kubernetes Auth Method configuration

Describe the solution you'd like Spring Cloud Vault should read the JWT token prior to Kubernetes Authentication, or reload the JWT token periodically. The above documentation says:

The application is responsible for reloading the token when it rotates. Periodic reloading (e.g. once every 5 minutes) is sufficient for most use cases.

Describe alternatives you've considered The application could use REST APIs instead of Spring Cloud Vault to login via Kubernetes Auth. This is problematic because it introduces additional complexity for developers to implement authentication and renewal logic.

Additional context Service Account Token Volume Projection is an important security capability introduced in Kubernetes 1.12. Prior to Service Account Token Volume Projection, Service Account tokens were static. This was a major issue as most organizations have a requirement to rotate credentials. Additional orchestration was needed to delete a Service Account secret and allow Kubernetes to create a new one.

The Service Account Token Volume Projection solves for this challenge elegantly as described above:

The kubelet will request and store the token on behalf of the pod, make the token available to the pod at a configurable file path, and refresh the token as it approaches expiration. Kubelet proactively rotates the token if it is older than 80% of its total TTL, or if the token is older than 24 hours.

mp911de commented 3 years ago

If I understand correctly, the only thing to do is to re-read the token file when the session token expires to re-login into Vault?

If so, then this is already the case for all non-reactive arrangements.

kawsark commented 3 years ago

Hello Mark,

That is correct, the token file needs to be re-read prior to re-logging into Vault. Could you please elaborate on non-reactive? We will be specifying Kubernetes Authentication properties in Bootstrap.yml as documented under Kubernetes Authentication

mp911de commented 3 years ago

Non-reactive basically means each application that does not use WebFlux or RSocket.

Using the reactive stack imposes limitations in terms of avoiding blocking calls. Reading a file uses blocking I/O. In Spring Vault, we don't support non-blocking File I/O yet.

By enabling the reactive Vault support, the selected authentication mechanism returns a descriptor (AuthenticationSteps) of activities that are required to log into Vault. These are typically HTTP calls and how to transform the outcome of HTTP calls to form a login request.

Since we have the limitation of avoiding blocking calls when running the application, what happens is that the Kubernetes token is read once and is reused for subsequent login calls, see KubernetesAuthentication.createAuthenticationSteps(…).

AuthenticationSteps is reused until application shutdown. It captures the JWT.

mp911de commented 3 years ago

That limitation is now addressed by spring-projects/spring-vault#586.

kawsark commented 3 years ago

Hello @mp911de , sorry to bother you again but do you have an estimate when this limitation will be lifted for Reactive Stack applications? Issue GH-586 says its targeted for Milestone 2.3 RC1 but it does not have an ETA. Thank you for your help.