Configure Cross-Namespace References
Cross-namespace references let platform teams operate shared Gateways, backends, and Secrets while application teams manage their own Routes and Consumers. Gateway API requires an explicit authorization at each namespace boundary so that creating a resource in one namespace does not grant access to resources owned by another team.
The required authorization depends on the relationship:
| Relationship | Authorization |
|---|---|
| Route to a Gateway in another namespace | The Gateway listener selects the Route namespace with allowedRoutes. |
| Route to a backend in another namespace | A ReferenceGrant in the backend namespace permits the Route reference. |
| Gateway to a TLS Secret in another namespace | A ReferenceGrant in the Secret namespace permits the Gateway reference. |
Consumer to a credential Secret in another namespace | A ReferenceGrant in the Secret namespace permits the Consumer reference. |
Cross-namespace traffic references are supported through Gateway API resources. The Ingress resource and APISIX routing CRDs do not support cross-namespace traffic references. The Consumer credential reference is an implementation-specific use of ReferenceGrant.
These mechanisms authorize relationships between resources; they do not grant users permission to create or modify those resources. Use Kubernetes RBAC to delegate Gateway API access before configuring cross-namespace references.
Prerequisites
Complete the following prerequisites:
- Set up the Ingress Controller and gateway with Gateway API resources.
- Install the Gateway API CRDs supported by this version of the Ingress Controller.
- Use an account with permission to create the namespaces and resources in each example.
The examples use a Gateway named apisix and a GatewayProxy named apisix-config in the aic namespace. These are the names created by the APISIX setup tutorial.
Allow a Route to Use a Backend in Another Namespace
The following example creates an HTTPRoute in tenant-a, attaches it to the Gateway in aic, and forwards requests to a Service in backend-ns:
The Gateway owner authorizes attachment from tenant-a, while the backend owner separately authorizes access to the httpbin Service.
Create the Namespaces
Create the Route and backend namespaces:
kubectl create namespace tenant-a
kubectl create namespace backend-ns
Kubernetes automatically adds the immutable kubernetes.io/metadata.name label to every namespace. The Gateway listener will use that label to select tenant-a; no custom namespace label is required.
Create the Backend Service
Create a deployment and Service in backend-ns:
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin
namespace: backend-ns
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
template:
metadata:
labels:
app: httpbin
spec:
containers:
- name: httpbin
image: kennethreitz/httpbin
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: httpbin
namespace: backend-ns
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
app: httpbin
Apply the manifest:
kubectl apply -f httpbin-deployment.yaml
Authorize the Backend Reference
A ReferenceGrant must be created in the namespace containing the referenced object. Create the following grant in backend-ns to allow HTTPRoute resources in tenant-a to reference the httpbin Service:
apiVersion: gateway.networking.k8s.io/v1
kind: ReferenceGrant
metadata:
name: allow-httpbin-from-tenant-a
namespace: backend-ns
spec:
from:
- group: gateway.networking.k8s.io
kind: HTTPRoute
namespace: tenant-a
to:
- group: ""
kind: Service
name: httpbin
The from entry trusts HTTPRoute resources in tenant-a. The to entry limits that trust to the httpbin Service in the ReferenceGrant's namespace. The to.name field is optional, but omitting it would permit references to every Service in backend-ns that is covered by a matching grant.
Apply the grant before creating the Route:
kubectl apply -f backend-referencegrant.yaml
Create the Route
Create an HTTPRoute in tenant-a that attaches to the Gateway in aic and references the Service in backend-ns:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: httpbin-route
namespace: tenant-a
spec:
parentRefs:
- name: apisix
namespace: aic
rules:
- matches:
- path:
type: PathPrefix
value: /ip
backendRefs:
- kind: Service
name: httpbin
namespace: backend-ns
port: 80
weight: 1
Apply the Route:
kubectl apply -f httpbin-route.yaml
Authorize the Route Attachment
By default, a Gateway listener accepts Routes only from the Gateway's namespace. Configure allowedRoutes on the listener to select the tenant-a namespace. Preserve any other listeners or settings required by your existing Gateway:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: apisix
namespace: aic
spec:
gatewayClassName: apisix
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
kubernetes.io/metadata.name: tenant-a
infrastructure:
parametersRef:
group: apisix.apache.org
kind: GatewayProxy
name: apisix-config
Using the immutable namespace-name label prevents users who can modify ordinary namespace labels from changing which namespaces may attach Routes to the Gateway.
Apply the updated Gateway:
kubectl apply -f gateway.yaml
To accept Routes from every namespace, set from: All instead:
allowedRoutes:
namespaces:
from: All
Using from: All in a multi-tenant or untrusted cluster lets any namespace attach HTTPRoute resources to this listener. A Route may claim a hostname before an authorized Route or expose backends through the shared Gateway. Prefer an explicit namespace selector.
Verify the Route
Forward the gateway Service port to your local machine. In the APISIX setup tutorial, both the Gateway and Service are in aic:
kubectl port-forward -n <gateway-service-namespace> \
svc/<gateway-service-name> 9080:80 &
Send a request to the Route:
curl -i "http://127.0.0.1:9080/ip"
You should receive an HTTP/1.1 200 OK response similar to the following:
{
"origin": "127.0.0.1"
}
If the request fails, inspect the Route's parent conditions. Accepted and ResolvedRefs should both be True:
kubectl describe httproute httpbin-route -n tenant-a
Allow a Gateway to Reference a TLS Secret
When a Gateway listener uses a certificate Secret in another namespace, the Secret owner must authorize the reference. For example, if the apisix Gateway is in aic and the Secret is named test-tls-secret in certificates, create this grant in certificates:
apiVersion: gateway.networking.k8s.io/v1
kind: ReferenceGrant
metadata:
name: allow-gateway-from-aic
namespace: certificates
spec:
from:
- group: gateway.networking.k8s.io
kind: Gateway
namespace: aic
to:
- group: ""
kind: Secret
name: test-tls-secret
Apply the grant before updating the Gateway:
kubectl apply -f certificate-referencegrant.yaml
Then include the Secret namespace in the listener's certificateRefs entry:
listeners:
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- group: ""
kind: Secret
name: test-tls-secret
namespace: certificates
After applying the Gateway, verify that the HTTPS listener reports ResolvedRefs=True:
kubectl describe gateway apisix -n aic
See Configure TLS Between Client and Gateway for the complete certificate and HTTPS Route configuration.
Allow a Consumer to Reference a Credential Secret
When a Consumer and its credential Secret are in different namespaces, the Secret owner must authorize the reference. Create the ReferenceGrant before applying or upgrading the Consumer. Without a matching grant, the admission webhook rejects the Consumer when the webhook is enabled. If the Consumer is admitted without a grant, the controller reports Available=False and does not program the credential.
Create the Consumer and Secret namespaces:
kubectl create namespace consumer-ns
kubectl create namespace secret-ns
Create a key-auth credential Secret in secret-ns:
apiVersion: v1
kind: Secret
metadata:
name: consumer-credentials
namespace: secret-ns
type: Opaque
stringData:
key: example-api-key
Create a ReferenceGrant in secret-ns that allows Consumer resources in consumer-ns to reference this Secret:
apiVersion: gateway.networking.k8s.io/v1
kind: ReferenceGrant
metadata:
name: allow-consumers-from-consumer-ns
namespace: secret-ns
spec:
from:
- group: apisix.apache.org
kind: Consumer
namespace: consumer-ns
to:
- group: ""
kind: Secret
name: consumer-credentials
Create the Consumer in consumer-ns. The gatewayRef identifies the Gateway for which the credential should be programmed:
apiVersion: apisix.apache.org/v1alpha1
kind: Consumer
metadata:
name: example-consumer
namespace: consumer-ns
spec:
gatewayRef:
name: apisix
namespace: aic
credentials:
- type: key-auth
name: primary-key
secretRef:
name: consumer-credentials
namespace: secret-ns
Apply the Secret and grant before the Consumer:
kubectl apply -f consumer-credential.yaml
kubectl apply -f consumer-referencegrant.yaml
kubectl apply -f consumer.yaml
Wait for the Consumer to report that the credential was programmed successfully:
kubectl wait --for=condition=Available \
consumers.apisix.apache.org/example-consumer \
-n consumer-ns \
--timeout=60s
If the condition remains False, inspect its message and confirm that the grant's from.namespace, to.name, and metadata namespace match the Consumer and Secret:
kubectl describe consumer example-consumer -n consumer-ns