Overview
Agones provides multiple security layers to protect your game server infrastructure. This guide covers authentication, authorization, encryption, and best practices for securing your Agones deployment.
mTLS for Allocations
What is mTLS?
Mutual TLS (mTLS) provides two-way authentication between the allocator service and clients. Both the server and client verify each other’s identities using certificates.
Configuring mTLS
By default, mTLS is enabled in the allocator service. The allocator uses certificates for secure communication:
# Allocator deployment with mTLS
apiVersion: apps/v1
kind: Deployment
metadata:
name: agones-allocator
spec:
template:
spec:
containers:
- name: agones-allocator
env:
- name: DISABLE_MTLS
value: "false" # mTLS enabled (default)
- name: DISABLE_TLS
value: "false" # TLS enabled (default)
volumeMounts:
- name: tls-cert
mountPath: /home/allocator/tls/
- name: client-ca
mountPath: /home/allocator/client-ca/
The allocator looks for TLS certificates in /home/allocator/tls/ and client CA certificates in /home/allocator/client-ca/.
Certificate Rotation
Agones automatically watches for certificate changes and reloads them without downtime:
// From cmd/allocator/main.go:331-346
if !h.mTLSDisabled {
cancelCert, err := fswatch.Watch(logger, certDir, time.Second, func() {
h.certMutex.Lock()
defer h.certMutex.Unlock()
caCertPool, err := getCACertPool(certDir)
if err != nil {
logger.WithError(err).Error("could not load CA certs; keeping old ones")
return
}
h.caCertPool = caCertPool
logger.Info("CA certs updated")
})
}
Certificates are monitored and automatically reloaded when updated, ensuring zero-downtime certificate rotation.
Client Configuration
Clients must present valid certificates when mTLS is enabled:
import (
"crypto/tls"
"crypto/x509"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
// Load client certificate
cert, err := tls.LoadX509KeyPair("client.crt", "client.key")
if err != nil {
log.Fatal(err)
}
// Load CA certificate
caCert, err := os.ReadFile("ca.crt")
if err != nil {
log.Fatal(err)
}
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
// Configure TLS
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
RootCAs: caCertPool,
}
// Create gRPC connection
creds := credentials.NewTLS(tlsConfig)
conn, err := grpc.Dial("allocator:443", grpc.WithTransportCredentials(creds))
Disabling mTLS (Not Recommended)
Disabling mTLS removes authentication and should only be done in development environments.
To disable mTLS:
helm install agones agones/agones \
--set agones.allocator.disableMTLS=true
Or via environment variable:
env:
- name: DISABLE_MTLS
value: "true"
RBAC Configuration
Controller Service Account
The Agones controller runs with a dedicated service account with minimal required permissions:
# From install/helm/agones/templates/serviceaccounts/controller.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: agones-controller
namespace: agones-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: agones-controller
rules:
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "patch"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["create", "update", "delete", "list", "watch"]
- apiGroups: [""]
resources: ["nodes", "secrets"]
verbs: ["list", "watch"]
- apiGroups: ["agones.dev"]
resources: ["gameservers", "gameserversets", "fleets"]
verbs: ["create", "delete", "get", "list", "update", "watch"]
- apiGroups: ["agones.dev"]
resources: ["fleets/status", "gameserversets/status"]
verbs: ["update"]
The controller only has permissions for resources it directly manages. It cannot modify cluster-wide resources or access other namespaces’ secrets.
SDK Service Account
GameServer pods run with a minimal service account:
apiVersion: v1
kind: ServiceAccount
metadata:
name: agones-sdk
namespace: agones-system
This service account has no RBAC permissions by default, following the principle of least privilege.
Custom RBAC for Game Servers
If your game servers need to interact with Kubernetes:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: gameserver-reader
namespace: default
rules:
- apiGroups: ["agones.dev"]
resources: ["gameservers"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: gameserver-reader-binding
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: gameserver-reader
subjects:
- kind: ServiceAccount
name: agones-sdk
namespace: agones-system
Security Best Practices
Network Policies
Restrict network access to game servers:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: gameserver-policy
namespace: default
spec:
podSelector:
matchLabels:
agones.dev/role: gameserver
policyTypes:
- Ingress
- Egress
ingress:
# Allow game traffic on configured ports
- from:
- ipBlock:
cidr: 0.0.0.0/0
ports:
- protocol: UDP
port: 7000-8000
# Allow sidecar communication
- from:
- podSelector:
matchLabels:
app: agones-controller
ports:
- protocol: TCP
port: 9357 # SDK gRPC port
- protocol: TCP
port: 9358 # SDK HTTP port
egress:
# Allow DNS
- to:
- namespaceSelector:
matchLabels:
name: kube-system
ports:
- protocol: UDP
port: 53
# Allow external game backend
- to:
- ipBlock:
cidr: 0.0.0.0/0
ports:
- protocol: TCP
port: 443
Pod Security Standards
Apply pod security standards to game server namespaces:
apiVersion: v1
kind: Namespace
metadata:
name: game-servers
labels:
pod-security.kubernetes.io/enforce: baseline
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
Resource Limits
Always set resource limits to prevent resource exhaustion:
apiVersion: agones.dev/v1
kind: GameServer
metadata:
name: secure-gameserver
spec:
template:
spec:
containers:
- name: game-server
image: my-game:latest
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
Secrets Management
Never hardcode credentials in game server containers or ConfigMaps.
Use Kubernetes Secrets for sensitive data:
apiVersion: v1
kind: Secret
metadata:
name: game-credentials
type: Opaque
stringData:
api-key: "your-api-key"
---
apiVersion: agones.dev/v1
kind: GameServer
spec:
template:
spec:
containers:
- name: game-server
env:
- name: API_KEY
valueFrom:
secretKeyRef:
name: game-credentials
key: api-key
For enhanced security, integrate with external secret managers:
Image Security
- Use specific image tags (not
latest):
image: us-docker.pkg.dev/my-project/game-servers/my-game:v1.2.3
- Enable image pull secrets for private registries:
spec:
template:
spec:
imagePullSecrets:
- name: registry-credentials
-
Scan images for vulnerabilities in CI/CD pipeline
-
Use distroless or minimal base images
Allocator Service Security
Restrict access to the allocator service:
apiVersion: v1
kind: Service
metadata:
name: agones-allocator
namespace: agones-system
spec:
type: LoadBalancer
loadBalancerSourceRanges:
- "10.0.0.0/8" # Only allow internal network
ports:
- port: 443
targetPort: 8443
protocol: TCP
Audit Logging
Enable Kubernetes audit logging to track allocation requests:
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: RequestResponse
resources:
- group: "allocation.agones.dev"
resources: ["gameserverallocations"]
- level: Metadata
resources:
- group: "agones.dev"
resources: ["gameservers", "fleets"]
Health Checks
The allocator exposes health endpoints for monitoring:
# Liveness probe
curl http://allocator:8080/live
# Readiness probe
curl http://allocator:8080/ready
From the source code (cmd/allocator/main.go:264-273):
health.AddReadinessCheck("allocator-agones-client", func() error {
if !podReady {
return errors.New("asked to shut down, failed readiness check")
}
_, err := agonesClient.ServerVersion()
if err != nil {
return fmt.Errorf("failed to reach Kubernetes: %w", err)
}
return nil
})
Security Checklist
Enable mTLS
Ensure mTLS is enabled for allocator service (default)
Configure RBAC
Use minimal service accounts with least-privilege permissions
Network Policies
Implement network policies to restrict pod-to-pod communication
Resource Limits
Set CPU and memory limits on all game server pods
Secrets Management
Use Kubernetes Secrets or external secret managers for credentials
Image Security
Use specific tags, private registries, and vulnerability scanning
Audit Logging
Enable Kubernetes audit logging for compliance
Regular Updates
Keep Agones, Kubernetes, and game server images updated