-
Notifications
You must be signed in to change notification settings - Fork 63
Prevent authentication into Vault without an audience #300
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Hi @jaireddjawed 👋 Could this be made optional, so that admins can opt out if they need? Without such an option, upgrade of Vault could cause serious issues for existing users, since reconfiguring roles can be tricky, especially when considering it needs to be coordinated with multiple clients at once, which might be developed by different teams, and they might use different types of tokens. Here are some scenarios that illustrate the complexity: 1. Clients can use the default audience Some clients don’t set an audience explicitly and instead use whatever Kubernetes provides by default: $ kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-sa
---
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
serviceAccountName: my-sa
containers:
- name: my-container
image: alpine:3
command: ["sleep", "9999999"]
EOF On a default Kind cluster, decoding the token shows: $ kubectl exec my-pod -- cat /var/run/secrets/kubernetes.io/serviceaccount/token | jq -R 'split(".") | .[1] | @base64d | fromjson'
{
"aud": [
"https://kubernetes.default.svc.cluster.local"
],
...
} Vault admins or even Kubernetes cluster admins may not know this value. It comes from the kube-apiserver 2. Clients can use ServiceAccount token Secrets Tokens created as $ kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
name: my-sa-token
annotations:
kubernetes.io/service-account.name: my-sa
type: kubernetes.io/service-account-token
EOF $ kubectl get secret my-sa-token -o jsonpath='{.data.token}' | base64 --decode | jq -R 'split(".") | .[1] | @base64d | fromjson'
{
... there is no "aud" claim at all
} These tokens would not be usable at all after Vault upgrade. 3. Clients can use projected volume tokens or token request API with a custom audience Here, the audience is explicitly set by whoever deploys the workload: $ kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: my-pod-projected
spec:
serviceAccountName: my-sa
containers:
- name: my-container
image: alpine:3
command: ["sleep", "9999999"]
volumeMounts:
- name: token-volume
mountPath: /var/run/secrets/kubernetes.io/my-projected-serviceaccount
volumes:
- name: token-volume
projected:
sources:
- serviceAccountToken:
path: token
audience: bar
EOF Audience in this case: $ kubectl exec my-pod-projected -- cat /var/run/secrets/kubernetes.io/my-projected-serviceaccount/token | jq -R 'split(".") | .[1] | @base64d | fromjson'
{
"aud": [
"bar"
],
...
} While audience validation is the correct approach, it would be great to clarify threat scenario
If an attacker controls the cluster, they can already create tokens with any $ kubectl create token my-sa --audience=whatever-i-want | jq -R 'split(".") | .[1] | @base64d | fromjson'
{
"aud": [
"whatever-i-want"
],
...
} Perhaps the intended risk is that an attacker could steal a token never meant for Vault and still use it if the service account name and namespace match an existing Vault role? |
Overview
Currently, Vault's Kubernetes authentication method does not require roles to specify an audience. As a result, an attacker could potentially craft a malicious JWT from a compromised or rogue Kubernetes cluster and use it to authenticate against Vault, especially if the associated cluster does not validate the
aud
claim.This pull request introduces a change that requires the
audience
field to be specified when creating or updating a Kubernetes role. Additionally, authentication attempts will fail if they use a role that lacks a configured audience.Since this is a breaking change, it will be included in Vault v1.21+. However, another PR will be backported into older Vault versions that logs a warning when a role does not have an audience.
Impact on users
"role does not have an audience defined, please update the role to include an audience"
.Manual Testing
Testing was similar to the testing done in PR 301. However, errors are expected instead of warnings.