This page provides instructions to configure intra-project traffic network policies in Google Distributed Cloud (GDC) air-gapped.
Project network policies define either ingress or egress rules. You can define policies that allow communication within projects, between projects, and to external IP addresses.
By default, these policies apply globally across all zones. For more information on global resources in a GDC universe, see Multi-zone overview.
If intra-project traffic enforcement is needed within a single zone, see Create a single zone workload-level intra-project policy.
Before you begin
To configure intra-project traffic network policies, you must have the following:
- The necessary identity and access roles. To manage traffic network policies, you need the Project Network Policy Admin (
global-project-networkpolicy-admin) role. For more information, see Prepare predefined roles and access. - An existing project. For more information, see Create a project.
- For egress network policies, you must also disable data exfiltration protection for the project.
Create an intra-project policy
For traffic within a project, GDC applies a predefined project network policy, the default intra-project policy, to each project. By default, workloads in a project namespace have the ability to communicate with each other without exposing anything to external resources.
By default, there is no egress policy, so outbound traffic is allowed for all intra-project traffic. However, after you apply an egress policy, the workloads that it selects can send only the traffic that your egress policies allow. To keep connectivity to other workloads and services in the same project, create an egress intra-project policy before you apply the egress policy. If data exfiltration protection is still enabled, create the egress intra-project policy before data exfiltration protection is disabled, because existing egress policies take effect at that point. For more information, see Default intra-project policy.
Create an ingress intra-project policy
When you create a project, GDC automatically creates a
default ProjectNetworkPolicy resource named
base-policy-allow-intra-project-traffic in the project namespace. This
Ingress policy selects all user workloads in the project and allows inbound
traffic to them from other workloads in the same project.
GDC creates this policy only once and doesn't restore
it if you change or delete it.
To remove the default policy, use the kubectl delete command:
kubectl --kubeconfig GLOBAL_API_SERVER delete pnp base-policy-allow-intra-project-traffic -n PROJECT
You can add the default policy back by applying the following manifest:
kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF
apiVersion: networking.global.gdc.goog/v1
kind: ProjectNetworkPolicy
metadata:
namespace: PROJECT
name: base-policy-allow-intra-project-traffic
spec:
policyType: Ingress
ingress:
- from:
- projectSelector:
projects:
matchNames:
- PROJECT
EOF
The manifest omits spec.subject, so the policy applies to all user workloads
in the project, like the original default policy.
Replace the following:
GLOBAL_API_SERVER: the global API server's kubeconfig path. For more information, see Global and zonal API servers. If you have not yet generated a kubeconfig file for the API server, see Sign in for details.PROJECT: the name of your project.
To verify the policy is ready, see Verify policy readiness.
Create an egress intra-project policy
When you disable data exfiltration prevention
and apply a ProjectNetworkPolicy egress policy to the project, such as
preventing access to an external resource, use the following required policy to allow
intra-project outbound traffic:
kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF
apiVersion: networking.global.gdc.goog/v1
kind: ProjectNetworkPolicy
metadata:
namespace: PROJECT
name: allow-intra-project-outbound-traffic
spec:
policyType: Egress
egress:
- to:
- projectSelector:
projects:
matchNames:
- PROJECT
EOF
Replace the following:
GLOBAL_API_SERVER: the global API server's kubeconfig path. For more information, see Global and zonal API servers. If you have not yet generated a kubeconfig file for the API server, see Sign in for details.PROJECT: the name of your project.
To verify the policy is ready, see Verify policy readiness.
Create a workload-level intra-project policy
Workload-level network policies offer granular control over communication between individual workloads within a project. This granularity allows stricter control of network access, improving security and resource use.
Create an ingress workload-level intra-project policy
When you create a project, GDC automatically creates a
default ProjectNetworkPolicy resource named
base-policy-allow-intra-project-traffic that allows inbound traffic between
all workloads in the project.
A workload-level intra-project policy restricts traffic only after you delete the default base policy. To avoid an interruption, create the policy and verify that it's ready, and then delete the default base policy:
To create an ingress workload-level intra-project policy, create and apply the following custom resource:
kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF apiVersion: networking.global.gdc.goog/v1 kind: ProjectNetworkPolicy metadata: namespace: PROJECT name: allow-workload-level-intra-project-inbound-traffic spec: policyType: Ingress subject: subjectType: UserWorkload userWorkloadSelector: labelSelector: workloads: matchLabels: SUBJECT_LABEL_KEY: SUBJECT_LABEL_VALUE ingress: - from: - projectSelector: projects: matchNames: - PROJECT workloadSelector: labelSelector: workloads: matchLabels: PEER_LABEL_KEY: PEER_LABEL_VALUE EOFReplace the following:
GLOBAL_API_SERVER: the global API server's kubeconfig path. For more information, see Global and zonal API servers. If you have not yet generated a kubeconfig file for the API server, see Sign in for details.PROJECT: the name of your project.SUBJECT_LABEL_KEY: the key of the label used to select the subject workloads. For example,app,tier, orrole. If you are referencing VM labels, you must add a prefix to this key; see the warning that follows this list.SUBJECT_LABEL_VALUE: the value associated with theSUBJECT_LABEL_KEY. For example, ifSUBJECT_LABEL_KEYisapp, andSUBJECT_LABEL_VALUEisbackend, then workloads with the labelapp: backendare receiving the traffic.PEER_LABEL_KEY: the key of the label used to select the peer workloads. If you are referencing VM labels, you must add a prefix to this key; see the warning that follows this list.PEER_LABEL_VALUE: the value associated with thePEER_LABEL_KEY.
To verify the policy is ready, see Verify policy readiness.
After the policy is ready, delete the default base policy so that the policy takes effect:
kubectl --kubeconfig GLOBAL_API_SERVER delete pnp base-policy-allow-intra-project-traffic -n PROJECT
Create an egress workload-level intra-project policy
To create an egress workload-level intra-project policy, create and apply the following custom resource:
kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF apiVersion: networking.global.gdc.goog/v1 kind: ProjectNetworkPolicy metadata: namespace: PROJECT name: allow-workload-level-intra-project-outbound-traffic spec: policyType: Egress subject: subjectType: UserWorkload userWorkloadSelector: labelSelector: workloads: matchLabels: SUBJECT_LABEL_KEY: SUBJECT_LABEL_VALUE egress: - to: - projectSelector: projects: matchNames: - PROJECT workloadSelector: labelSelector: workloads: matchLabels: PEER_LABEL_KEY: PEER_LABEL_VALUE EOFReplace the following:
GLOBAL_API_SERVER: the global API server's kubeconfig path. For more information, see Global and zonal API servers. If you have not yet generated a kubeconfig file for the API server, see Sign in for details.PROJECT: the name of your project.SUBJECT_LABEL_KEY: the key of the label used to select the subject workloads. For example,app,tier, orrole. If you are referencing VM labels, you must add a prefix to this key; see the warning that follows this list.SUBJECT_LABEL_VALUE: the value associated with theSUBJECT_LABEL_KEY. For example, ifSUBJECT_LABEL_KEYisapp, andSUBJECT_LABEL_VALUEisbackend, then workloads with the labelapp: backendare sending the traffic.PEER_LABEL_KEY: the key of the label used to select the peer workloads. If you are referencing VM labels, you must add a prefix to this key; see the warning that follows this list.PEER_LABEL_VALUE: the value associated with thePEER_LABEL_KEY.
To verify the policy is ready, see Verify policy readiness.
Create a single zone workload-level intra-project policy
Workload-level network policies can enforce PNP along a single zone. Specific labels can be added to workloads within a single zone, allowing you to control communication between individual workloads within a project or in different projects for that zone.
Create a single zone ingress workload-level intra-project policy
When you create a project, GDC automatically creates a
default ProjectNetworkPolicy resource named
base-policy-allow-intra-project-traffic that allows inbound traffic between
all workloads in the project.
A single zone workload-level intra-project policy restricts traffic only after you delete the default base policy. To avoid an interruption, create the policy and verify that it's ready, and then delete the default base policy:
To create a single zone ingress workload-level intra-project traffic network policy, create and apply the following custom resource:
kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF apiVersion: networking.global.gdc.goog/v1 kind: ProjectNetworkPolicy metadata: namespace: PROJECT name: allow-single-zone-intra-project-inbound-traffic spec: policyType: Ingress subject: subjectType: UserWorkload userWorkloadSelector: labelSelector: workloads: matchLabels: SUBJECT_LABEL_KEY: SUBJECT_LABEL_VALUE ZONE_SUBJECT_LABEL_KEY: ZONE_SUBJECT_LABEL_VALUE ingress: - from: - projectSelector: projects: matchNames: - PROJECT workloadSelector: labelSelector: workloads: matchLabels: PEER_LABEL_KEY: PEER_LABEL_VALUE ZONE_PEER_LABEL_KEY: ZONE_PEER_LABEL_VALUE EOFReplace the following:
GLOBAL_API_SERVER: the global API server's kubeconfig path. For more information, see Global and zonal API servers. If you have not yet generated a kubeconfig file for the API server, see Sign in for details.PROJECT: the name of your project.SUBJECT_LABEL_KEY: the key of the label used to select the subject workloads. For example,app,tier, orrole. If you are referencing VM labels, you must add a prefix to this key; see the warning that follows this list.SUBJECT_LABEL_VALUE: the value associated with theSUBJECT_LABEL_KEY. For example, ifSUBJECT_LABEL_KEYisapp, andSUBJECT_LABEL_VALUEisbackend, then workloads with the labelapp: backendare receiving the traffic.PEER_LABEL_KEY: the key of the label used to select the peer workloads. If you are referencing VM labels, you must add a prefix to this key; see the warning that follows this list.PEER_LABEL_VALUE: the value associated with thePEER_LABEL_KEY.ZONE_SUBJECT_LABEL_KEY: the key of the label used to select the subject zone. For example,zone, orregion. If you are referencing VM labels, you must add a prefix to this key; see the warning that follows this list.ZONE_SUBJECT_LABEL_VALUE: the value associated with theZONE_SUBJECT_LABEL_KEY. For example, ifZONE_SUBJECT_LABEL_KEYiszone, andZONE_SUBJECT_LABEL_VALUEisus-central1-a, then workloads with the labelzone: us-central1-aare receiving the traffic.ZONE_PEER_LABEL_KEY: the key of the label used to select the zone associated with the peer. If you are referencing VM labels, you must add a prefix to this key; see the warning that follows this list.ZONE_PEER_LABEL_VALUE: the value associated with theZONE_PEER_LABEL_KEY.
To verify the policy is ready, see Verify policy readiness.
After the policy is ready, delete the default base policy so that the policy takes effect:
kubectl --kubeconfig GLOBAL_API_SERVER delete pnp base-policy-allow-intra-project-traffic -n PROJECT
Create a single zone egress workload-level intra-project policy
To create a single zone egress workload-level intra-project policy, create and apply the following custom resource:
kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF apiVersion: networking.global.gdc.goog/v1 kind: ProjectNetworkPolicy metadata: namespace: PROJECT name: allow-single-zone-intra-project-outbound-traffic spec: policyType: Egress subject: subjectType: UserWorkload userWorkloadSelector: labelSelector: workloads: matchLabels: SUBJECT_LABEL_KEY: SUBJECT_LABEL_VALUE ZONE_SUBJECT_LABEL_KEY: ZONE_SUBJECT_LABEL_VALUE egress: - to: - projectSelector: projects: matchNames: - PROJECT workloadSelector: labelSelector: workloads: matchLabels: PEER_LABEL_KEY: PEER_LABEL_VALUE ZONE_PEER_LABEL_KEY: ZONE_PEER_LABEL_VALUE EOFReplace the following:
GLOBAL_API_SERVER: the global API server's kubeconfig path. For more information, see Global and zonal API servers. If you have not yet generated a kubeconfig file for the API server, see Sign in for details.PROJECT: the name of your project.SUBJECT_LABEL_KEY: the key of the label used to select the subject workloads. For example,app,tier, orrole. If you are referencing VM labels, you must add a prefix to this key; see the warning that follows this list.SUBJECT_LABEL_VALUE: the value associated with theSUBJECT_LABEL_KEY. For example, ifSUBJECT_LABEL_KEYisapp, andSUBJECT_LABEL_VALUEisbackend, then workloads with the labelapp: backendare receiving the traffic.PEER_LABEL_KEY: the key of the label used to select the peer workloads. If you are referencing VM labels, you must add a prefix to this key; see the warning that follows this list.PEER_LABEL_VALUE: the value associated with thePEER_LABEL_KEY.ZONE_SUBJECT_LABEL_KEY: the key of the label used to select the subject zone. For example,zone, orregion. If you are referencing VM labels, you must add a prefix to this key; see the warning that follows this list.ZONE_SUBJECT_LABEL_VALUE: the value associated with theZONE_SUBJECT_LABEL_KEY. For example, ifZONE_SUBJECT_LABEL_KEYiszone, andZONE_SUBJECT_LABEL_VALUEisus-central1-a, then workloads with the labelzone: us-central1-aare receiving the traffic.ZONE_PEER_LABEL_KEY: the key of the label used to select the zone associated with the peer. If you are referencing VM labels, you must add a prefix to this key; see the warning that follows this list.ZONE_PEER_LABEL_VALUE: the value associated with theZONE_PEER_LABEL_KEY.
To verify the policy is ready, see Verify policy readiness.
Create an intra-project policy for standard clusters
Standard Clusters are project-scoped Kubernetes clusters that provide greater control, flexibility, and cluster-admin permissions. When you create an intra-project policy, it is inherited by standard clusters by default. This policy allows all communication within the standard clusters that reside in the same project.
Create an ingress intra-project policy for standard clusters
When you create a project, GDC automatically creates a
default ProjectNetworkPolicy resource named
base-policy-allow-intra-project-traffic that allows inbound traffic between
all workloads in the project, including intra-cluster communication between
all workloads in the standard clusters within the project.
An ingress intra-project policy for standard clusters restricts traffic only after you delete the default base policy. To avoid an interruption, create the policies in the following steps and verify that they're ready, and then delete the default base policy:
To create an ingress intra-cluster pod-to-pod policy in standard clusters, create and apply the following custom resource
kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF apiVersion: networking.global.gdc.goog/v1 kind: ProjectNetworkPolicy metadata: namespace: STANDARD_CLUSTER_PROJECT name: allow-ingress-from-intra-cluster-traffic spec: policyType: Ingress subject: subjectType: UserWorkload userWorkloadSelector: labelSelector: clusters: matchLabels: kubernetes.io/metadata.name: STANDARD_CLUSTER_NAME namespaces: matchLabels: kubernetes.io/metadata.name: SUBJECT_NAMESPACE workloads: matchLabels: SUBJECT_LABEL_KEY: SUBJECT_LABEL_VALUE ingress: - from: - projectSelector: projects: matchNames: - STANDARD_CLUSTER_PROJECT workloadSelector: labelSelector: clusters: matchLabels: kubernetes.io/metadata.name: STANDARD_CLUSTER_NAME namespaces: matchLabels: kubernetes.io/metadata.name: PEER_NAMESPACE workloads: matchLabels: PEER_LABEL_KEY: PEER_LABEL_VALUE EOFReplace the following:
GLOBAL_API_SERVER: the global API server's kubeconfig path. For more information, see Global and zonal API servers. If you have not yet generated a kubeconfig file for the API server, see Sign in for details.STANDARD_CLUSTER_PROJECT: the name of the standard cluster project.STANDARD_CLUSTER_NAME: the name of the standard cluster.SUBJECT_NAMESPACE: the subject namespace in the standard cluster.PEER_NAMESPACE: the peer namespace in the standard cluster.SUBJECT_LABEL_KEY: the key of the label used to select the subject workloads. For example,app,tier, orrole. If you are referencing VM labels, you must add a prefix to this key; see the warning that follows this list.SUBJECT_LABEL_VALUE: the value associated with theSUBJECT_LABEL_KEY. For example, ifSUBJECT_LABEL_KEYisapp, andSUBJECT_LABEL_VALUEisbackend, then workloads with the labelapp: backendare receiving the traffic.PEER_LABEL_KEY: the key of the label used to select the peer workloads. If you are referencing VM labels, you must add a prefix to this key; see the warning that follows this list.PEER_LABEL_VALUE: the value associated with thePEER_LABEL_KEY.
To verify the policy is ready, see Verify policy readiness.
Controlling traffic between pods and specific cluster nodes using the
ipBlocksfield is a Preview feature. For details and scale considerations, see Target cluster nodes using IP blocks. To create an ingress intra-cluster node-to-pod policy in standard clusters, create and apply the following custom resource:kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF apiVersion: networking.global.gdc.goog/v1 kind: ProjectNetworkPolicy metadata: namespace: STANDARD_CLUSTER_PROJECT name: allow-ingress-from-node-to-pod-traffic spec: policyType: Ingress subject: subjectType: UserWorkload userWorkloadSelector: labelSelector: clusters: matchLabels: kubernetes.io/metadata.name: STANDARD_CLUSTER_NAME namespaces: matchLabels: kubernetes.io/metadata.name: SUBJECT_NAMESPACE workloads: matchLabels: SUBJECT_LABEL_KEY: SUBJECT_LABEL_VALUE ingress: - from: - ipBlocks: - cidr: NODE_IP ports: - protocol: TCP port: PORT EOFReplace the following:
GLOBAL_API_SERVER: the global API server's kubeconfig path. For more information, see Global and zonal API servers. If you have not yet generated a kubeconfig file for the API server, see Sign in for details.STANDARD_CLUSTER_PROJECT: the name of the standard cluster project.STANDARD_CLUSTER_NAME: the name of the standard cluster.SUBJECT_NAMESPACE: the subject namespace in the standard cluster.SUBJECT_LABEL_KEY: the key of the label used to select the subject workloads. For example,app,tier, orrole.SUBJECT_LABEL_VALUE: the value associated with theSUBJECT_LABEL_KEY. For example, ifSUBJECT_LABEL_KEYisapp, andSUBJECT_LABEL_VALUEiswebhook, then workloads with the labelapp: webhookreceive the traffic.NODE_IP: the IP address (in/32notation) or CIDR range of the source cluster node from which traffic is allowed.PORT: the port on the subject workload where traffic is allowed (for example,8443or443).
To verify the policy is ready, see Verify policy readiness.
After the policies are ready, delete the default base policy so that they take effect:
kubectl --kubeconfig GLOBAL_API_SERVER delete pnp base-policy-allow-intra-project-traffic -n PROJECT
Restore the default policy
If your new policies cause issues with your services, you can restore the default policy while you investigate and develop your solution. To restore the default policy, apply the following manifest:
kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF
apiVersion: networking.global.gdc.goog/v1
kind: ProjectNetworkPolicy
metadata:
namespace: PROJECT
name: base-policy-allow-intra-project-traffic
spec:
policyType: Ingress
ingress:
- from:
- projectSelector:
projects:
matchNames:
- PROJECT
EOF
Replace the following:
GLOBAL_API_SERVER: the global API server's kubeconfig path. For more information, see Global and zonal API servers. If you have not yet generated a kubeconfig file for the API server, see Sign in for details.PROJECT: the name of your project.
To verify the policy is ready, see Verify policy readiness.
Create an egress intra-project policy for standard clusters
To create an egress intra-cluster pod-to-pod policy in standard clusters, create and apply the following custom resource:
kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF apiVersion: networking.global.gdc.goog/v1 kind: ProjectNetworkPolicy metadata: namespace: STANDARD_CLUSTER_PROJECT name: allow-egress-to-intra-cluster-traffic spec: policyType: Egress subject: subjectType: UserWorkload userWorkloadSelector: labelSelector: clusters: matchLabels: kubernetes.io/metadata.name: STANDARD_CLUSTER_NAME namespaces: matchLabels: kubernetes.io/metadata.name: SUBJECT_NAMESPACE workloads: matchLabels: SUBJECT_LABEL_KEY: SUBJECT_LABEL_VALUE egress: - to: - projectSelector: projects: matchNames: - STANDARD_CLUSTER_PROJECT workloadSelector: labelSelector: clusters: matchLabels: kubernetes.io/metadata.name: STANDARD_CLUSTER_NAME namespaces: matchLabels: kubernetes.io/metadata.name: PEER_NAMESPACE workloads: matchLabels: PEER_LABEL_KEY: PEER_LABEL_VALUE EOFReplace the following:
GLOBAL_API_SERVER: the global API server's kubeconfig path. For more information, see Global and zonal API servers. If you have not yet generated a kubeconfig file for the API server, see Sign in for details.STANDARD_CLUSTER_PROJECT: the name of the standard cluster project.STANDARD_CLUSTER_NAME: the name of the standard cluster.SUBJECT_NAMESPACE: the subject namespace in the standard cluster.PEER_NAMESPACE: the peer namespace in the standard cluster.SUBJECT_LABEL_KEY: the key of the label used to select the subject workloads. For example,app,tier, orrole. If you are referencing VM labels, you must add a prefix to this key; see the warning that follows this list.SUBJECT_LABEL_VALUE: the value associated with theSUBJECT_LABEL_KEY. For example, ifSUBJECT_LABEL_KEYisapp, andSUBJECT_LABEL_VALUEisbackend, then workloads with the labelapp: backendare sending the traffic.PEER_LABEL_KEY: the key of the label used to select the peer workloads. If you are referencing VM labels, you must add a prefix to this key; see the warning that follows this list.PEER_LABEL_VALUE: the value associated with thePEER_LABEL_KEY.
To verify the policy is ready, see Verify policy readiness.
Controlling traffic between pods and specific cluster nodes using the
ipBlocksfield is a Preview feature. For details and scale considerations, see Target cluster nodes using IP blocks. To create an egress intra-cluster pod-to-node policy in standard clusters, create and apply the following custom resource:kubectl --kubeconfig GLOBAL_API_SERVER apply -f - <<EOF apiVersion: networking.global.gdc.goog/v1 kind: ProjectNetworkPolicy metadata: namespace: STANDARD_CLUSTER_PROJECT name: allow-egress-from-pod-to-node-traffic spec: policyType: Egress subject: subjectType: UserWorkload userWorkloadSelector: labelSelector: clusters: matchLabels: kubernetes.io/metadata.name: STANDARD_CLUSTER_NAME namespaces: matchLabels: kubernetes.io/metadata.name: SUBJECT_NAMESPACE workloads: matchLabels: SUBJECT_LABEL_KEY: SUBJECT_LABEL_VALUE egress: - to: - ipBlocks: - cidr: NODE_IP ports: - protocol: TCP port: PORT EOFReplace the following:
GLOBAL_API_SERVER: the global API server's kubeconfig path. For more information, see Global and zonal API servers. If you have not yet generated a kubeconfig file for the API server, see Sign in for details.STANDARD_CLUSTER_PROJECT: the name of the standard cluster project.STANDARD_CLUSTER_NAME: the name of the standard cluster.SUBJECT_NAMESPACE: the subject namespace in the standard cluster.SUBJECT_LABEL_KEY: the key of the label used to select the subject workloads. For example,app,tier, orrole.SUBJECT_LABEL_VALUE: the value associated with theSUBJECT_LABEL_KEY. For example, ifSUBJECT_LABEL_KEYisapp, andSUBJECT_LABEL_VALUEiscontroller, then workloads with the labelapp: controllersend the traffic.NODE_IP: the IP address (in/32notation) or CIDR range of the destination cluster node to which traffic is allowed.PORT: the port on the destination node to which traffic is allowed (for example,6444or443).
To verify the policy is ready, see Verify policy readiness.
Verify policy readiness
To verify that the project network policy is ready, run the following command:
kubectl --kubeconfig GLOBAL_API_SERVER get pnp POLICY_NAME -n PROJECT -oyaml
Replace POLICY_NAME with the name of the policy you want to verify, and PROJECT with the project name where the policy was created.
Look for status: "True" in the Ready condition of the output:
...
status:
...
conditions:
- lastTransitionTime: "2026-03-24T10:55:25Z"
message: ProjectNetworkPolicy propagated to remote clusters
observedGeneration: 1
reason: Propagated
status: "True"
type: Ready
...