Authentication
By default, anyone who can reach the web app can create servers and change or
delete the ones created there. To know who people are, put a proxy that signs them in in
front of the gateway and tell the gateway how to read who they are, with
gateway.auth.mode:
none: the default. Servers have no owners.iap: Google Cloud’s Identity-Aware Proxy. The gateway checks the assertion IAP signs for each request.header: another proxy that signs people in, such as oauth2-proxy, and names them in a header.
The gateway doesn’t sign people in itself, so it works with whatever your cluster already uses.
Owners and admins
With authentication on, a server created from the web app belongs to whoever
created it, which is recorded in its quake.kube/owner annotation. Only they
can change or delete it from the web app, or change it from the game’s pause
menu while playing, along with admins.
Admins are whoever Kubernetes RBAC lets delete QuakeServers in the web app’s
namespace, which the gateway asks the API server about. So anyone who could
already delete servers with kubectl can change and delete them from the web
app too, and
admins can be granted in the same way as other access to the cluster. The chart
has a quake-kube-admin ClusterRole for this, and binds it to the users and
groups in gateway.auth.admins:
gateway:
auth:
admins:
users: [[email protected]]
groups: [quake-admins]
Servers created before authentication was turned on have no owner, so only admins can change or delete them.
gateway.maxServersPerUser limits how many servers each person can have at
once, alongside gateway.maxServers for everyone together. Admins have the same
limit.
Google Cloud’s Identity-Aware Proxy
On GKE, IAP signs people in with their Google accounts before they reach the web app. Who can reach it is managed in IAM, by granting the IAP-secured Web App User role, e.g. to a Google group.
IAP works with GKE’s load balancers, through Gateway API or a GKE Ingress. The
chart creates GKE’s settings for the gateway’s Service with gateway.gke: a
GCPBackendPolicy for an HTTPRoute, and a BackendConfig for an Ingress. With
Gateway API:
gateway:
auth:
mode: iap
iap:
# The project's number, not its ID.
projectNumber: "123456789012"
httpRoute:
enabled: true
parentRefs:
- name: external
namespace: infra
hostnames: [quake.example.com]
gke:
enabled: true
iap:
enabled: true
or with a GKE Ingress, replace httpRoute with:
gateway:
ingress:
enabled: true
className: gce
host: quake.example.com
IAP signs its assertions for the load balancer’s backend service, which GKE
creates and names, so the gateway accepts assertions for any backend service in
the project. Set gateway.auth.iap.audience to the backend service’s audience
instead, /projects/<number>/global/backendServices/<id>, to only accept its
own.
Without an OAuth client, IAP uses a Google-managed one, which only lets in
people in your organization. To use your own, set gateway.gke.iap.clientID
and gateway.gke.iap.clientSecretName.
gateway.gke also keeps GKE’s load balancers from closing browser clients’
WebSockets after 30 seconds, with timeoutSec, so turn it on with GKE’s load
balancers even without IAP.
The gateway’s own Service isn’t behind IAP, so the gateway turns away requests without a valid assertion, e.g. from inside the cluster.
Other proxies
With header, the gateway reads the user’s email address from a header, and
their groups from another, if the proxy sends them. With oauth2-proxy’s
defaults:
gateway:
auth:
mode: header
header:
user: X-Forwarded-Email
groups: X-Forwarded-Groups
The gateway trusts these headers, so it must only be reachable through the proxy, e.g. with a NetworkPolicy that only lets the proxy reach it. Groups from the proxy are what RBAC checks admins’ groups against.
WebTransport
WebTransport sessions reach the gateway over UDP, past the proxy, so the play page gives browsers a ticket for the server they’re joining, which the gateway checks. A ticket works for an hour, and browsers that reconnect later use the WebSocket, which goes through the proxy.
Each gateway replica signs tickets with its own key unless
gateway.auth.ticketSecretName names a Secret with a shared key, so set it
with more than one replica:
kubectl --namespace quake-kube create secret generic quake-kube-tickets \
--from-literal=key="$(head -c 32 /dev/urandom | base64)"
Native clients
Native Quake 3 clients connect to game servers directly, past the proxy. To keep
people from joining, give servers a password (see
Setting A Password), or turn off their external
addresses with gameServers.exposure.type: None, which leaves them to browser
clients.