Search code examples
kubernetesgoogle-cloud-platformgoogle-kubernetes-enginegoogle-cloud-iam

Why this legacy SA has access to resources


I am failing to understand why a particular Google Cloud service account has access to resources in a specific namespace inside GKE.

There seem to be no evidence it should have access. Alternatively, it could be me who's misinterpreting IAM / RBAC integration.

Is there any logs I could check to see what access policies are in use inside Kubernetes when this SA attempts to access specific resources in it?

For context, I have this service account:

github@my-project.iam.gserviceaccount.com

The account is assigned the following:

  • on Google Cloud IAM level, I have roles/container.developer assigned to the said Service Account,

  • on Kubernetes (GKE) level, I have a role + role binding created:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: ci-cd
      namespace: default
    rules:
    - apiGroups:
      - apps
      resourceNames:
      - my-backend
      resources:
      - deployments
      verbs:
      - list
      - watch
      - patch
      - get
    
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: ci-cd
      namespace: default
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: Role
      name: ci-cd
    subjects:
    - apiGroup: rbac.authorization.k8s.io
      kind: User
      name: github@my-project.iam.gserviceaccount.com
      namespace: default
    

This SA can perform patch on deployment as expected:

kubectl auth can-i patch deployment/my-backend \
  --namespace default \
  --as github@my-project.iam.gserviceaccount.com
yes

What's confusing, and what I am failing to explain to myself, is why this account's attempts to patch a deployment with a different name in different namespace are successful (as observed), which I am able to cross-check by confirming with Cloud Audit Logs:

insertId: 10f277c5-041c-4e61-afa6-5ca669393a50
labels:
  authorization.k8s.io/decision: allow
  authorization.k8s.io/reason: access granted by IAM permissions.
logName: projects/my-project/logs/cloudaudit.googleapis.com%2Factivity
operation:
  first: true
  id: 10fc17c5-041c-4e61-afa6-5ca661793a50
  last: true
  producer: k8s.io
protoPayload:
  '@type': type.googleapis.com/google.cloud.audit.AuditLog
  authenticationInfo:
    principalEmail: github@my-project.iam.gserviceaccount.com
  authorizationInfo:
  - granted: true
    permission: io.k8s.apps.v1.deployments.patch
    resource: apps/v1/namespaces/review-apps/deployments/my-backend-5005
  methodName: io.k8s.apps.v1.deployments.patch
  request:
# ...

...all the while this returns no:

kubectl auth can-i patch deployment/my-backend-5005 \
  --namespace review-apps \
  --as github@my-project.iam.gserviceaccount.com
no

I am at a loss here. Send help.


Solution

  • The problem was me misinterpreting a item 2 from "Applications within Google Cloud" section of "Authenticating to the Kubernetes API server" article.

    Particularly, I found this wording to be confusing:

    You can also use RBAC to grant the IAM...

    My mistake was that I've implemented suggestions from the item entirely, e.g. both granted an IAM permission AND added a Kubernetes-level RBAC. Because of this, I observed the following:

    • due to IAM permission, the Service Account can effectively perform actions to most objects across namespaces, disregarding any kubernetes-level RBAC rules,

    • due to RBAC policy I have, I had results coming from kubectl auth can-i that contradicted previous item,

    I wish the You can also use RBAC to grant the IAM... could be reworded to *Alternatively, use RBAC to grant the IAM...". Filed a documentation update request for Google Cloud for that page.