Setup authorization policies on sidecars on GKE

This page provides instructions for setting up different kinds of authorization policies on Cloud Service Mesh sidecars on GKE.

Before you begin

You should be familiar with Gateway API and Authorization Extensions.

Before you create authorization policy, you must perform the following steps:

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. Enable the Network Security, Network Services APIs.

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.

    Enable the APIs

  5. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  6. Verify that billing is enabled for your Google Cloud project.

  7. Enable the Network Security, Network Services APIs.

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.

    Enable the APIs

Namespace-wide AuthzPolicy

If you want to deny an expected traffic pattern for the whole namespace, configure an authorization policy to deny any incoming HTTP requests to all the workloads in a namespace:

$ cat >ns-authz-policy-deny.yaml <<EOF
apiVersion: networking.gke.io/v1
kind: GCPAuthzPolicy
metadata:
  name: ns-authz
  namespace: NAMESPACE
spec:
  targetRefs:
  - kind: Pod
    selector: {}
  rules:
  - to:
      operations:
      - paths:
        - type: Prefix
          value: "/bad_token"
  action: DENY
EOF
$ kubectl apply -f ns-authz-policy-deny.yaml

Note that that the empty selector: {} targets all Pods in the namespace.

If you want to allow an expected traffic pattern for the whole namespace, configure an authorization policy to allow any incoming HTTP requests to all the workloads in a namespace:

$ cat >ns-authz-policy-allow.yaml <<EOF
apiVersion: networking.gke.io/v1
kind: GCPAuthzPolicy
metadata:
  name: ns-authz
  namespace: NAMESPACE
spec:
  targetRefs:
  - kind: Pod
    selector: {}
  rules:
  - to:
      operations:
      - paths:
        - type: Prefix
          value: "/headers"
        methods: ["GET"]
  action: ALLOW
EOF
$ kubectl apply -f ns-authz-policy-allow.yaml

Note that that the empty selector: {} targets all Pods in the namespace.

Deny inbound requests to a workload

If you have a workload that is supposed to make only outbound calls, like a cron job, configure an authorization policy to deny any incoming HTTP requests to the workload:

$ cat >deny-path-authz-policy.yaml <<EOF
apiVersion: networking.gke.io/v1
kind: GCPAuthzPolicy
metadata:
  name: my-workload-authz
  namespace: NAMESPACE
spec:
 targetRefs:
 - kind: Pod
   selector:
matchLabels:
      app: EXAMPLE_APP
  rules:
  - to:
      operations:
      - paths:
        - type: Prefix
          value: "/deny_path"
  action: DENY
EOF
$ kubectl apply -f deny-path-authz-policy.yaml

The output is similar to:

gcpauthzpolicy.networking.gke.io/my-workload-authz created

After this policy is applied, any incoming HTTP request to the path /deny_path on the Pods matching app: EXAMPLE_APP will be rejected and the caller will receive an HTTP 403 Forbidden response code.

Allow specific inbound requests to a workload

You can also configure an ALLOW policy that allows only requests that match a specific criteria while rejecting the rest.

The following example configures an authorization policy on the example-app Deployment to allow only mTLS requests from Pods with identity spiffe://cluster.local/namespace/pod1.

$ cat >allow-authz-policy.yaml <<EOF
apiVersion: networking.gke.io/v1
kind: GCPAuthzPolicy
metadata:
  name: my-workload-authz
  namespace: NAMESPACE
spec:
 targetRefs:
 - kind: Pod
   selector:
matchLabels:
      app: EXAMPLE_APP
  rules:
  - from:
      sources:
      - principals:
        - principal:
          exact: "spiffe://cluster.local/NAMESPACE/pod1"
  action: ALLOW
EOF
$ kubectl apply -f allow-authz-policy.yaml

The output is similar to:

gcpauthzpolicy.networking.gke.io/my-workload-authz created

Only incoming requests authenticated using mTLS presenting the exact SPIFFE identity spiffe://cluster.local/NAMESPACE/pod1 will receive an HTTP 200 OK. Any other request will be rejected by the proxy with an HTTP 403 Forbidden.

Delegate to an external authorization engine

You can bring your own authorization engine and configure Cloud Service Mesh to delegate all authorization decisions for a workload to the configured engine.

  1. Deploy a callout based authorization extension workload in Kubernetes supporting the ext_proc gRPC protocol and configure an authorization extension resource:

    $ cat >authz-extension.yaml <<EOF
    apiVersion: networking.gke.io/v1
    kind: GCPAuthzExtension
    metadata:
      name: my-authz-ext
      namespace: ns1
    spec:
      backendRef:
        kind: Service
        name: authz-service
      loadBalancingScheme: INTERNAL_SELF_MANAGED
      forwardHeaders:
      - Authorization
      failOpen: false
      timeout: "0.1s"
      wireFormat: EXT_PROC_GRPC
    EOF
    $ kubectl apply -f authz-extension.yaml
    

    This command creates a callout-based authorization extension that runs as a Kubernetes service authz-service.

    The output is similar to:

    gcpauthzextension.networking.gke.io/my-authz-ext created
    
  2. Set up the authorization policy to delegate authorization decisions for the workload to the authorization extension previously configured:

    $ cat >authz-policy.yaml <<EOF
    apiVersion: networking.gke.io/v1
    kind: GCPAuthzPolicy
    metadata:
      name: my-workload-authz
      namespace: NAMESPACE
    spec:
      targetRefs:
      - kind: Pod
        selector:
          matchLabels:
            app: EXAMPLE_APP
      rules:
      - from:
          sources:
          - principals:
            - principal:
                exact: "spiffe://cluster.local/NAMESPACE/pod1"
        to:
          operations:
          - paths:
            - type: Exact
              value: "/api/payments-schedule"
      action: CUSTOM
      customProvider:
        authzExtension:
          targetRefs:
          - kind: GCPAuthzExtension
            name: my-authz-ext
    EOF
    $ kubectl apply -f authz-policy.yaml
    

    The output is similar to:

    gcpauthzpolicy.networking.gke.io/my-workload-authz created
    

    The proxy will wait for your custom service to return an OK or DENY response before forwarding the request to the application or returning an HTTP 403 to the caller.