Ambient networking security and authorization policies

This page shows you how to create authorization policies on ambient networking.

Prerequisites

Before you can complete the steps in this document, you must meet the following conditions:

  • A running GKE cluster with Cloud Service Mesh ambient networking enabled.
  • A namespace enrolled in ambient networking (for example, ambient-test) with sample client and server workloads deployed.
  • Mutual TLS (mTLS) enabled between the client and server workloads by using a GCPServerTLSPolicy (with mtlsMode: Strict) and a GCPClientTLSPolicy. Identity-based GCPAuthzPolicy rules that match CLIENT_CERT_URI_SAN require active mTLS to extract the client's SPIFFE identity.

For a detailed environment setup, see Prepare GKE ambient networking.

Deny-by-default policy

By default, the GKE Ambient Authorization Policy API permits all traffic unless restricted by policy, matching standard Kubernetes NetworkPolicy behavior.

The DENY_BY_DEFAULT action lets you change this default behavior. When applied to a namespace, this policy blocks all traffic to workloads in that namespace unless explicitly allowed by an ALLOW policy.

This page shows you how to configure and use DENY_BY_DEFAULT in Cloud Service Mesh to establish a secure-by-default posture for your workloads.

Limitations

Before applying a DENY_BY_DEFAULT policy, take note of the following limitations:

  • You can only create one DENY_BY_DEFAULT policy per namespace.
  • A policy with the DENY_BY_DEFAULT action cannot have any rules defined.
  • Use this action to set a namespace-wide baseline matchLabels: {} to target all Pods. You can't use DENY_BY_DEFAULT for per-Pod restrictions.

Set up a deny-by-default authorization policy

To establish a deny-by-default baseline across a namespace and selectively allow access to specific workloads, follow these steps:

  1. Create and apply a GCPAuthzPolicy with the action set to DENY_BY_DEFAULT to your namespace.

    cat <<EOF > deny-by-default-policy.yaml && kubectl apply -f deny-by-default-policy.yaml
    apiVersion: networking.gke.io/v1
    kind: GCPAuthzPolicy
    metadata:
      name: deny-by-default-authz
      namespace: ambient-test
    spec:
      action: DENY_BY_DEFAULT
      enforcementLevel: L4
      targetRefs:
      - group: ""
        kind: Pod
        selector:
          matchLabels: {}
    EOF
    

    The output is similar to:

     gcpauthzpolicy.networking.gke.io/deny-by-default-authz created
    

    This policy blocks all inbound (East-West and ingress) traffic to workloads in the ambient-test namespace by default. It does not restrict outbound traffic originating from workloads in the namespace.

  2. To selectively allow traffic, create and apply an ALLOW policy:

    cat <<EOF > allow-policy.yaml && kubectl apply -f allow-policy.yaml
    apiVersion: networking.gke.io/v1
    kind: GCPAuthzPolicy
    metadata:
      name: allow-client-to-server
      namespace: ambient-test
    spec:
      action: ALLOW
      enforcementLevel: L4
      targetRefs:
      - group: ""
        kind: Pod
        selector:
          matchLabels:
            app: server
      rules:
      - from:
          sources:
          - principals:
          - principalSelector: CLIENT_CERT_URI_SAN
            principal:
              type: Exact
              value: spiffe://PROJECT_ID.s3ns.svc.id.goog/ns/ambient-test/sa/client
    EOF
    

    Replace PROJECT_ID with your project ID.

    Policy propagation can take up to three minutes after controller acceptance. Wait three minutes before proceeding.

  3. Test connectivity from the client to the server. It should succeed because it matches the ALLOW policy.

    kubectl exec -it deploy/client -n ambient-test -- /bin/curl -fsLS server.ambient-test.svc.cluster.local
    
  4. Test connectivity from the server to itself (or any other workload without an explicit allow policy). It should fail because of the DENY_BY_DEFAULT policy.

    kubectl exec -it deploy/server -n ambient-test -- /bin/curl -fsLS server.ambient-test.svc.cluster.local
    

    The output is similar to:

    curl: (52) Empty reply from server.
    

Logging

When a request is denied by authorization policy, the GKE Ambient Proxy access logs contain the following fields in the JSON payload:

  • jsonPayload.error_details: Set to - rbac_access_denied_matched_policy[none]

You can use Logs Explorer in Cloud de Confiance console to view the access log entries for denied connections. See Verify traffic is authenticated and authorized.

Egress security policies

To inspect and control outbound traffic from ambient networking workloads to external endpoints or the internet, you can route egress traffic through Secure Web Proxy (SWP).

For instructions on configuring GCPBackend and GCPEgressRouting resources, see Route ambient egress traffic through Secure Web Proxy.