I am experimenting with service accounts. I believe the following should produce an access error (but it doesn't):
apiVersion: v1
kind: ServiceAccount
metadata:
name: test-sa
---
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
serviceAccountName: test-sa
containers:
- image: alpine
name: test-container
command: [sh]
args:
- -ec
- |
apk add curl;
KUBE_NAMESPACE="$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)";
curl \
--cacert "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" \
-H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
"https://kubernetes.default.svc/api/v1/namespaces/$KUBE_NAMESPACE/services";
while true; do sleep 1; done;
kubectl apply -f test.yml
kubectl logs test-pod
What I see is a successful listing of services, but I would expect a permissions error because I never created any RoleBindings or ClusterRoleBindings for test-sa.
I'm struggling to find ways to list the permissions available to a particular SA, but according to Kubernetes check serviceaccount permissions, it should be possible with:
kubectl auth can-i list services --as=system:serviceaccount:default:test-sa
> yes
Though I'm skeptical whether that command is actually working, because I can replace test-sa with any gibberish and it still says "yes".
According to the documentation, service accounts by default have "discovery permissions given to all authenticated users". It doesn't say what that actually means, but from more reading I found this resource which is probably what it's referring to:
kubectl get clusterroles system:discovery -o yaml
> [...]
> rules:
> - nonResourceURLs:
> - /api
> - /api/*
> [...]
> verbs:
> - get
Which would imply that all service accounts have get permissions on all API endpoints, though the "nonResourceURLs" bit implies this wouldn't apply to APIs for resources like services, even though those APIs live under that path… (???)
If I remove the Authorization header entirely, I see an access error as expected. But I don't understand why it's able to get data using this empty service account. What's my misunderstanding and how can I restrict permissions correctly?