Gateway API
The Pomerium Ingress Controller now includes experimental support for the Kubernetes Gateway API.
Overview
Gateway API is an alternative to the Ingress API, aimed at standardizing more of the common functionality between different ingress implementations, and with a focus on role-based resource management.
Whether you already use the Gateway API for service networking in Kubernetes or are interested in using it for the first time with Pomerium, we'd love to hear from you! Please don't hesitate to reach out to support@pomerium.com or on the discussion forum.
To learn more about the Gateway API in general, see the official Gateway API documentation.
Supported features
Ingress Controller now includes partial support for "Core" features from the Gateway API v1.2, for the "Gateway" and "HTTP" conformance profiles.
Some features are not supported:
- 
Gateway listeners must use the HTTPS protocol, not plain HTTP. (Plaintext HTTP is not supported because Pomerium uses session cookies for authentication, and it is not safe to transmit session cookies using unencrypted HTTP.) 
- 
Currently HTTPRoute is the only supported route type (GRPCRoute is not supported yet). 
- 
HTTPHeaderMatch is not supported yet. 
- 
The HTTPHeaderFilter addfield is not supported. (You can overwrite a header value with thesetfield, but you cannot append to an existing header value.)
Pomerium-specific extensions
Pomerium defines a PolicyFilter CRD for setting the authorization policy for a particular route. For example:
apiVersion: gateway.pomerium.io/v1alpha1
kind: PolicyFilter
metadata:
  name: allow-internal
spec:
  ppl: |
    allow:
      and:
        - domain:
            is: your-company-domain.com
See Pomerium Policy Language for complete details about policy syntax.
Pomerium will deny access to any route without an explicit authorization, so you must set a PolicyFilter on every route you define for use with Pomerium.
Installation
To install the Pomerium Ingress Controller with support for Gateway API:
- 
First install the Gateway API CRDs: kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/standard-install.yaml
- 
Then install the Pomerium Ingress Controller using the gateway-apikustomization:kubectl apply -k github.com/pomerium/ingress-controller/config/gateway-api\?ref=v0.31.0This installs and configures the Ingress Controller, and adds a GatewayClass named pomerium-gatewayfor use with the Gateway API.
- 
You will also need to set up a global Pomerium configuration. This is a minimal example for use with Gateway API: pomerium-global.yamlapiVersion: ingress.pomerium.io/v1
 kind: Pomerium
 metadata:
 name: global
 spec:
 secrets: pomerium/bootstrapDeploy with kubectl apply -f pomerium-global.yaml.infoYou don't need to include any certificates in this global configuration when usnig the Gateway API, as certificates are instead defined on individual Gateway listeners. 
Example usage
Let's look at how you can configure a route and policy using the Gateway API.
- 
We'll need a TLS certificate for the domain to be used with this route. (For testing purposes you could generate a certificate using mkcert. In production you may want to use a solution like cert-manager.) For this example we'll assume we have a wildcard certificate for *.localhost.pomerium.io, and we'll create a Secret to store this certificate:kubectl create secret tls pomerium-wildcard-tls \
 --cert=_wildcard.localhost.pomerium.io.pem \
 --key=_wildcard.localhost.pomerium.io-key.pem
- 
Next we'll set up a Gateway that uses this certificate: pomerium-gateway.yamlapiVersion: gateway.networking.k8s.io/v1
 kind: Gateway
 metadata:
 name: localhost-pomerium-io
 spec:
 gatewayClassName: pomerium-gateway
 listeners:
 - name: https
 hostname: '*.localhost.pomerium.io'
 protocol: HTTPS
 port: 443
 tls:
 mode: Terminate
 certificateRefs:
 - name: pomerium-wildcard-tlsDeploy with kubectl apply -f pomerium-gateway.yaml.
- 
We'll also need a service. Here we'll use httpbin as an example: httpbin-service.yamlapiVersion: v1
 kind: Service
 metadata:
 name: httpbin
 spec:
 selector:
 app: httpbin
 ports:
 - port: 80
 targetPort: 80
 name: http
 ---
 apiVersion: apps/v1
 kind: Deployment
 metadata:
 name: httpbin-deployment
 labels:
 app: httpbin
 spec:
 replicas: 1
 selector:
 matchLabels:
 app: httpbin
 template:
 metadata:
 labels:
 app: httpbin
 spec:
 containers:
 - name: httpbin
 image: docker.io/kennethreitz/httpbin
 ports:
 - containerPort: 80Deploy with kubectl apply -f httpbin-service.yaml.
- 
For Pomerium to grant access to this service we'll also need to define an authorization policy: allow-by-email.yamlapiVersion: gateway.pomerium.io/v1alpha1
 kind: PolicyFilter
 metadata:
 name: allow-by-email
 spec:
 ppl: |
 allow:
 and:
 - email:
 is: your-email-here@example.comBe sure to replace your-email-here@example.comwith your actual email address, and then runkubectl apply -f allow-by-email.yaml.
- 
Finally, we can define a route to the example service using the gateway and policy: httpbin-route.yamlapiVersion: gateway.networking.k8s.io/v1
 kind: HTTPRoute
 metadata:
 name: httpbin-route
 spec:
 parentRefs:
 - name: localhost-pomerium-io
 hostnames:
 - 'httpbin.localhost.pomerium.io'
 rules:
 - backendRefs:
 - name: httpbin
 port: 80
 filters:
 - type: ExtensionRef
 extensionRef:
 group: gateway.pomerium.io
 kind: PolicyFilter
 name: allow-by-emailDeploy with kubectl apply -f httpbin-route.yaml.
Now, if you navigate to the route hostname in your browser (https://httpbin.localhost.pomerium.io in the example above), you should be prompted to sign in to access the route. If you sign in, and the account you use matches the email address from the policy spec, you should be granted access to the httpbin service:
