Skip to content

Instantly share code, notes, and snippets.

@ivanthelad
Last active February 25, 2022 10:22
Show Gist options
  • Save ivanthelad/8dfd1c96f7444df22fe4b168d12df3b9 to your computer and use it in GitHub Desktop.
Save ivanthelad/8dfd1c96f7444df22fe4b168d12df3b9 to your computer and use it in GitHub Desktop.
approaches to secure token usage in aks

Recommendation when ensuring a workload adheres to automountServiceAccountToken" policy

if using azure policy on aks you can get tripped up with automountServiceAccountToken been violated by most containers

If container does not need to access API

If i need access to the k8s API and using a version less than 1.21.

  • Ensure service account "automountServiceAccountToken: false" with a dedicated SA
  • Ensure pod spec "automountServiceAccountToken: false"
  • Create a dedicated token Secret of type "kubernetes.io/service-account-token"
  • reference Mount secret under path /var/run/secrets/kubernetes.io/serviceaccount
  • The secrets are placed under this path as kubectl will automatically look under this path when authenicating. in generally you can put them anywhere
  • This approach creates 3 files. a cert, a namespace ref, and token under the above path
  • This approach create a non-expiring token.
  • volumes:
       - name: foo
         secret:
           secretName: nginxtoken
       containers:
       - image: nginx
         imagePullPolicy: Always
         name: nginx
         resources: {}
         terminationMessagePath: /dev/termination-log
         terminationMessagePolicy: File
         volumeMounts:
         - mountPath:  /var/run/secrets/kubernetes.io/serviceaccount
           name: foo ```
    
    
    

If i need access to the k8s API and using a version greater or equal to 1.21.

  • This approach uses bounded service account tokens. a feature since 1.20
  • https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/#bound-service-account-token-volume
  • Ensure service account "automountServiceAccountToken: false" with a dedicated SA
  • Ensure pod spec "automountServiceAccountToken: false"
  • Create projected: volume that uses "serviceAccountToken", "configmap" and "downwardAPI"
  • place the volumes this path "/var/run/secrets/kubernetes.io/serviceaccount" as kubectl will automatically look under this path when authenicating. in generally you can put them anywhere.
  • This approach creates 3 files. a cert, a namespace ref, and token under the above path.
  • This approach create a expiring token for your workload. The tokens will be automically rotated by the TokenControler
  • The dynamic creation and rotation is the difference between just using normal Service account token secret.
  • This token is not available to other workload. The token controller will ensure its not expired too.
  • Note: the certificate and the namespace is only added to allow kubectl to function within a pod. these are not actually required
  •  automountServiceAccountToken: false
     serviceAccountName: nginx-sa
     volumes:
     - name: foo
       projected:
         defaultMode: 420 # 0644
         sources:
           - serviceAccountToken:
               expirationSeconds: 3607
               path: token
           - configMap:
               items:
                 - key: ca.crt
                   path: ca.crt
               name: kube-root-ca.crt
           - downwardAPI:
               items:
                 - fieldRef:
                     apiVersion: v1
                     fieldPath: metadata.namespace
                   path: namespace
     containers:
     - image: nginx
       imagePullPolicy: Always
       name: nginx
       resources: {}
       terminationMessagePath: /dev/termination-log
       terminationMessagePolicy: File
       volumeMounts:
       - mountPath:  /var/run/secrets/kubernetes.io/serviceaccount
         name: foo
         ```
    
    

Notes

https://kubernetes.io/docs/tasks/administer-cluster/access-cluster-api/

Test token

  • Jump into pod
  • Get token from where every you mounted it.
    TOKEN=$(cat /var/run/secrets/tokens/vault-token)
  • or default location

TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)

  • Curl Kuvbernetes API using downward api env variables

curl --header "Authorization: Bearer $TOKEN" https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT_HTTPS/api --insecure

Create SA for a pod to use instead of default

  • This SA has automounting disabled.
  • No token secret get mounted
    kubectl apply -f - <<EOF apiVersion: v1 kind: ServiceAccount metadata: name: nginx-sa automountServiceAccountToken: false EOF

By default the secret is not mounted

Create the token secret for nginx

  • Create a specific token for the SA to use.
  • By default a dynamic SA api token is created.
  • by creating a sa token we can at design time reference the token in our pod instead of the dynamically created one kubectl apply -f - <<EOF apiVersion: v1 kind: Secret metadata: name: nginxtoken annotations: kubernetes.io/service-account.name: nginx-sa type: kubernetes.io/service-account-token EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment