How to deploy Airlock Microgateway?
Doh, what a silly question. It is a Kubernetes application. There is a Helm chart. Easy answer! But seriously, there are multiple options. Learn what to pay attention to and the respective advantages and disadvantages.
The Airlock Microgateway is our Kubernetes-native solution for securing all web applications and APIs. It integrates tightly with the Kubernetes ecosystem, enabling DevSecOps teams to apply a “shift-left” security paradigm – embedding security early in the development lifecycle without adding friction.
YAML manifests described in this article can also be found in a Git repository.
Planning
Data Plane Mode
Use Kubernetes Gateway API mode. Gateway API is the natural successor to Ingress. It separates cluster and application responsibilities, supports centralized setups, and reduces operational overhead.
For for more details see the documentation.
Ingress options
HTTP Traffic must be forwarded from outside the cluster to the internal network to reach the applications (and the Airlock Microgateway). Multiple technologies exist to achieve this. Also, in most clusters, this function has been setup already. Most of the approaches experience multiple drawbacks wich led to the development and standardisation of the Kubernetes Gateway API. Going forward, we expect most installations to adapt it.
In the meantime, you can either:
- Retain existing ingress (Ingress API, Load Balancer, or OpenShift Route) with the Microgateway as an “in-cluster Gateway”, allowing to leverage existing processes and knowledge.
- Use Microgateway as ingress, which reduces components, simplifies administration, and aligns with Kubernetes-official L4/L7 routing.
While our recommendation is to use Microgateway as ingress, both approaches can coexist. For example, legacy apps may still use Ingress, while new apps are protected via Gateway API.
The following diagram outlines the traffic flow for both options:
Selection between the two options is based on the domain name (FQDN) respectively the IP address of the LoadBalancer service.
Supporting multiple versions
While cluster purists may prefer setups where always only one version of any single component is installed, we recommend running multiple Microgateway versions concurrently. This avoids forcing all teams to test and upgrade simultaneously and ensures new business features don’t get blocked by unrelated applications.
Airlock Microgateway comes with a strong set of security rules which are active out-of-the-box, following the “secure by design and default” principle. The advantage of this obviously being that your applications are protected without substantial security analysis through reviews, penetration tests or scans – all of which, by the way, might fail to identify a possible attack vector and, therefore, miss to add relevant protection. The downside is that updates to the rule set, which happens with every new release, may cause false positives and negatively impact the functioning of the application – hence the above recommendation.
Even with a multi-version setup, some components are shared:
- Custom Resource Definitions
- Kubernetes webhooks
- Kubernetes admission policies
To avoid conflicts, we recommend a maximum of two different versions of the Airlock Microgateway to be concurrently installed on a single Kubernetes cluster.
Pay special attention when “downgrading” or installing a previous version. You must make sure the Custom Resource Definitions are not updated in this case. Also, at least up to Airlock Microgateway version 4.7, you should check if webhook conflicts result in errors when changing manifests. If so, remove all ValidatingWebhookConfigurations except those of the current verison. A future release of Airlock Microgateway will migrate to Common Expression Language, avoiding the use of webhooks altogether.
Components
Installing Airlock Microgateway deploys an operator that manages instances. To support multiple versions, use distinct namespaces per version (e.g., microgateway-system-4-7, microgateway-system-4-8). Note that Kubernetes identifiers must not contain dots ‘.’ or underlines ‘_’.
| Resource | Description | Important Properties |
|---|---|---|
| GatewayClass |
|
controllerName: unique identifier per version e.g. microgateway.airlock.com/gatewayclass-controller-4-7 |
| Gateway |
|
gatewayClassName: references controllerName of GatewayClass e.g. airlock-microgateway-4-7 |
| HTTPRoute |
|
parentRefs: references name of Gateway backendRefs: references name of Kubernetes Service of application |
Table 1: Description of resources
The following diagram shows how they relate:
Figure 3: Components
Installation of Airlock Microgateway Operator
1. Create a directory for customisation and required files:
mkdir ~/microgateway/operator
cd ~/microgateway/operator
2. Choose the namespace for this version:
export MGW_SYSTEM_NS=”microgateway-system-4-7”
3. Obtain Airlock Microgateway License. To choose the right edition, head over to the comparison page.
- Community license (free to use)
- Premium license
In any case, save it to the above directory and create a Kubernetes secret from it:
cp <downloaded license> ./microgateway-license.txt
kubectl -n ${MGW_SYSTEM_NS} \
create secret generic \
airlock-microgateway-license \
--from-file=microgateway-license.txt
4. If cert-manager is not already deployed on your cluster, head over to the Airlock Microgateway Running Example where you will find instructions and manifests for an initial Certificate Authority (CA).
5. Deploy the Kubernetes Gateway API CRDs
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.3.0/experimental-install.yaml
6. Create the Airlock Microgateway deployment customisation file, e.g. ~/microgateway/operator/custom.yaml:
operator:
replicaCount: 2
image:
digest: ""
tag: 4.7.1
gatewayAPI:
enabled: true
controllerName: microgateway.airlock.com/gatewayclass-controller-4-7
gatewayClass:
name: airlock-microgateway-4-7
sidecarGateway:
enabled: false
engine:
image:
digest: ""
tag: 4.7.1
sessionAgent:
image:
digest: ""
tag: 4.7.1
commonAnnotations:
source.info.io/chart: https://github.com/<your-org>/airlock-microgateway
7. Finally, deploy Airlock Microgateway:
helm install airlock-microgateway \
-n ${MGW_SYSTEM_NS} \
oci://quay.io/airlockcharts/microgateway \
--wait -f custom.yaml
Designing the deployment
Gateway strategy
Kubernetes Gateway API improves on existing technologies by providing granular control over traffic routing. It features a role-oriented architecture which allows to clearly delineate responsibilities across different personas within an organisation.
Figure 4: Responsibilities for Gateway API resources
The deciding factor how cluster operators plan the Gateway setup is responsibility for the domain name under which the application is accessible.
For setups where the domain name is centrally managed, configure it on the Gateway resource. Use RBAC and namespaces for access control. To resolve conflicts due to ambigous listener selection, make use of section names.
On the other hand, application teams control the domain name via HTTPRoute and attach it to a single Gateway, subject to RBAC.
As Gateway API supports cross-namespace connections, Gateway placement experiences almost no restrictions. However, pay attention to the fact that a domain name must resolve to a single Gateway.
For this article, we place it in a dedicated namespace
export MGW_NS=”airlock-microgateway”
Update all namespace references in the following examples if you change the value.
HTTPS by default
Redirect all HTTP to HTTPS with a global HTTP Listener in your Gateway and a redirecting HTTPRoute. Adjust hostname and certificate reference, if required:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: airlock-microgateway-4-7
namespace: airlock-microgateway
spec:
gatewayClassName: airlock-microgateway-4-7
listeners:
- allowedRoutes:
namespaces:
from: All
name: http
port: 80
protocol: HTTP
- allowedRoutes:
namespaces:
from: All
hostname: '*.example.com'
name: https
port: 443
protocol: HTTPS
tls:
certificateRefs:
- group: ""
kind: Secret
name: example-com-wildcard
namespace: certificates
mode: Terminate
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-redirector
namespace: airlock-microgateway
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: airlock-microgateway-4-7
sectionName: http
rules:
- filters:
- requestRedirect:
scheme: https
statusCode: 301
type: RequestRedirect
matches:
- path:
type: PathPrefix
value: /
TLS certificates
TLS certificates should be managed via cert-manager + Let’s Encrypt.
If the corresponding Kubernetes secret is in a namespace different from the one you place the Gateways in, create a ReferenceGrant to allow access. It must be placed in the namespace of the certificate secret.
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
name: wildcard-certificate
namespace: certificates
spec:
from:
- group: gateway.networking.k8s.io
kind: Gateway
namespace: airlock-microgateway
to:
- group: ""
kind: Secret
name: wildcard-certificate
Use Microgateway as ingress
To forward external traffic into the cluster, the Airlock Microgateway’s service must have an externally accessible IP address, usually of type LoadBalancer. As the service is under control of the operator, use GatewayParameters to tell it the correct setting:
apiVersion: microgateway.airlock.com/v1alpha1
kind: GatewayParameters
metadata:
name: airlock-microgateway
namespace: airlock-microgateway
spec:
kubernetes:
service:
externalTrafficPolicy: Local
type: LoadBalancer
The value of externalTrafficPolicy is only important if the Airlock Microgateway is the first reverse proxy to handle the request. Usually, in cloud and enterprise environments, there are downstream application load balancers forwarding client IP either via the X-Forwarded-Forheader or by making use of the Proxy protocol.
Application deployment
Example application
If you know which application to protect and have it already deployed on your cluster, skip to the next section.
Otherwise, use these manifests to deploy a very simple and small example application:
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
source.info.io/container: https://quay.io/repository/miniboat/cff-clock
labels:
app: cff-clock
app.kubernetes.io/instance: cff-clock
app.kubernetes.io/name: cff-clock
app.kubernetes.io/version: 0.1.0
name: cff-clock
---
apiVersion: v1
kind: Service
metadata:
annotations:
source.info.io/container: https://quay.io/repository/miniboat/cff-clock
labels:
app: cff-clock
app.kubernetes.io/instance: cff-clock
app.kubernetes.io/name: cff-clock
app.kubernetes.io/version: 0.1.0
name: cff-clock
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
selector:
app.kubernetes.io/instance: cff-clock
app.kubernetes.io/name: cff-clock
zuska.marmira.com/environment: eval
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
source.info.io/container: https://quay.io/repository/miniboat/cff-clock
labels:
app: cff-clock
app.kubernetes.io/instance: cff-clock
app.kubernetes.io/name: cff-clock
app.kubernetes.io/version: 0.1.0
name: cff-clock
spec:
replicas: 1
revisionHistoryLimit: 3
selector:
matchLabels:
app.kubernetes.io/instance: cff-clock
app.kubernetes.io/name: cff-clock
app.kubernetes.io/version: 0.1.0
strategy:
type: RollingUpdate
template:
metadata:
annotations:
source.info.io/container: https://quay.io/repository/miniboat/cff-clock
labels:
app: cff-clock
app.kubernetes.io/instance: cff-clock
app.kubernetes.io/name: cff-clock
app.kubernetes.io/version: 0.1.0
spec:
automountServiceAccountToken: true
containers:
- name: cff-clock
image: quay.io/miniboat/cff-clock:0.1.0
env:
- name: TZ
value: Europe/Zurich
ports:
- containerPort: 8123
name: http
protocol: TCP
livenessProbe:
failureThreshold: 3
httpGet:
path: /
port: http
initialDelaySeconds: 1
periodSeconds: 61
timeoutSeconds: 3
readinessProbe:
failureThreshold: 3
httpGet:
path: /
port: http
initialDelaySeconds: 1
periodSeconds: 63
timeoutSeconds: 3
startupProbe:
periodSeconds: 1
timeoutSeconds: 2
failureThreshold: 20
initialDelaySeconds: 1
httpGet:
path: /
port: http
resources:
requests:
cpu: 10m
memory: 5Mi
limits:
cpu: 100m
memory: 5Mi
restartPolicy: Always
serviceAccountName: cff-clock
Save to a file and apply:
kubectl apply -f example-application.yaml
Before you can test the application, it must be exposed – and secured.
Security applications
Now that the Airlock Microgateway is ready, secure the application. Route incoming traffic through the Airlock Microgateway to the application’s service using an HTTPRoute. As example, we use the application deployed above. Before applying the following manifest, you must adaptthe following properties:
- spec.hostnames
Replace cff-clock.example.com with a fully-qualified domain name valid in your environment. You may also have to add a DNS record if it is not picked up auomatically
- spec.parentRefs
The values are valid for the Gateway deployed above (HTTPS by default).
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: cff-clock
spec:
hostnames:
- cff-clock.example.com
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: airlock-microgateway-4-7
namespace: airlock-microgateway
sectionName: https
rules:
- backendRefs:
- group: ""
kind: Service
name: cff-clock
port: 80
weight: 1
matches:
- path:
type: PathPrefix
value: /
On top of HTTPRoute, apply content security and access control policies as well as deny rule exceptions. (This will be the subject of a follow-up post).
Steer your browser to https://cff-clock.example.com (or whatever domain you choose). If all went well, you should be greeted with a well-known sight:
Figure 5: Application protected by Airlock Microgateway
Pitfalls and checks
An Airlock Microgateway setup consists of a considerable number of components and quite a few "moving parts". If traffic does not flow correctly to your application right from the start, check the following:
- Use kubectl describe to check status on Gateway API objects
- Check if the license is correctly installed and available
kubectl -n airlock-microgateway get gateway airlock-microgateway-4-7 -o jsonpath='{.status.conditions}' | jq -r '.[]|select(.reason=="ValidLicense")'
{
"lastTransitionTime": "2025-09-05T07:33:06Z",
"message": "Valid Airlock Microgateway License configured: Premium...",
"observedGeneration": 5,
"reason": "ValidLicense",
"status": "True",
"type": "Licensed"
}
Verify status is true.
- Check the status of the Gateway resource
kubectl -n airlock-microgateway get gateway airlock-microgateway-4-7 -o jsonpath='{.status.listeners[0].conditions}' | jq -r
[
{
"lastTransitionTime": "2025-09-16T18:21:29Z",
"message": "All references are resolved",
"observedGeneration": 5,
"reason": "ResolvedRefs",
"status": "True",
"type": "ResolvedRefs"
},
{
"lastTransitionTime": "2025-09-16T18:21:29Z",
"message": "No conflicts",
"observedGeneration": 5,
"reason": "NoConflicts",
"status": "False",
"type": "Conflicted"
},
{
"lastTransitionTime": "2025-09-16T18:21:29Z",
"message": "Listener is accepted",
"observedGeneration": 5,
"reason": "Accepted",
"status": "True",
"type": "Accepted"
},
{
"lastTransitionTime": "2025-09-19T01:12:15Z",
"message": "Listener is waiting to get programmed, check Gateway status condition Programmed for further details.",
"observedGeneration": 5,
"reason": "Pending",
"status": "False",
"type": "Programmed"
}
]
In particular, the status must be:
- ResolvedRefs: true
- NoConflicts: false
- Accepted: true
If status contains
- Pending: false
there is no appropriate HTTPRoute defined. If there is, you should find:
- Programmed: true
- In case of conflicts, limit to only one listener (yes, also without the HTTP forwarder). With multiple listeners, make sure each is named and referred to in spec.parentRefs.sectionName of the HTTPRoute resource.
- Download and install gwctl – a CLI tool to manage and understand Gateway API resources
It can also produce an image showing the relationships (you will also need ImageMagick or another Dot viewer):
gwctl -n airlock-microgateway get gateway -o graph > layout.dot
magick layout.dot layout.png
- The installation of Airlock Microgateway involves installing the Kubernetes Gateway API CRDs. If you already have them installed – from another product or earlier tests – make sure they are of the right version:
- v1.3/standarf
- v1.3/experimental
(required to use incubating features – see https://docs.airlock.com/microgateway/latest/index/1726159408094.html)
Conclusion
Deploying Airlock Microgateway isn’t just a Helm install – it’s about making the right architectural choices upfront. Using Gateway API, letting Microgateway handle ingress, and a multi-version setup will give your cluster flexible, secure, and future-proof web application and API protection.
With a well-designed Gateway setup and automation-friendly manifests, you can make deployments smooth while ensuring your apps stay protected from day one.
Blognews direkt in Ihr Postfach
Der Airlock Newsletter informiert Sie laufend über neue Blogartikel.