How does the GitLab Kubernetes Agent (KAS) work, and how does it replace the deprecated certificate-based Kubernetes integration?
Quick Answer
The GitLab Kubernetes Agent (KAS) establishes a secure, pull-based connection from a Kubernetes cluster to GitLab using an agent pod that maintains an outbound WebSocket tunnel. Unlike the deprecated certificate-based integration (which required exposing the cluster API), KAS does not require inbound network access, supports GitOps workflows with manifest synchronization, and provides granular RBAC-based access control.
Detailed Answer
Think of the GitLab Kubernetes Agent like a diplomatic embassy. In the old model (certificate-based integration), your country (GitLab) needed direct access to the foreign country's government building (Kubernetes API), requiring special passports (certificates) and open borders (firewall rules). With KAS, the foreign country (Kubernetes cluster) sends an ambassador (agent pod) to your country, who maintains a secure communication channel (WebSocket tunnel) back home. The ambassador relays messages between the two governments without either side needing to open their borders. The ambassador lives within the foreign country's jurisdiction and follows its laws (RBAC), making the arrangement both secure and sovereign.
The GitLab Kubernetes Agent consists of two components: agentk (the agent that runs as a pod inside the Kubernetes cluster) and KAS (Kubernetes Agent Server, a GitLab-side component that manages agent connections). The agent is registered in a GitLab project by creating a configuration file at .gitlab/agents/<agent-name>/config.yaml. After registration, GitLab provides a token that the agent uses to authenticate. The agent pod establishes an outbound gRPC/WebSocket connection to KAS, creating a persistent bidirectional tunnel. This tunnel is used for two purposes: CI/CD access (allowing CI/CD jobs to run kubectl commands against the cluster through the tunnel without exposing the Kubernetes API) and GitOps synchronization (the agent watches a GitLab repository for Kubernetes manifests and automatically applies changes when files are updated, similar to Flux or ArgoCD).
Internally, when a CI/CD job needs to interact with a Kubernetes cluster via the agent, the job uses the kubeconfig provided by the agent integration. The job's kubectl commands are sent through the Runner to KAS, which routes them through the WebSocket tunnel to the agentk pod in the target cluster. The agentk pod executes the kubectl commands using its own service account's RBAC permissions. For GitOps mode, the agentk pod runs a reconciliation loop: it periodically pulls the configured GitLab repository, compares the manifest files against the cluster's current state, and applies any differences. This pull-based model means the cluster never needs to accept inbound connections, and changes are applied through the agent's service account with its RBAC constraints. The agent also supports inventory management, tracking which resources it has created and cleaning up resources that are removed from the manifests.
In production, a company with clusters in multiple environments would deploy agents strategically. The staging cluster has an agent named staging-agent with CI/CD access enabled, allowing deploy jobs to run kubectl and helm commands against staging. The production cluster has a production-agent with GitOps mode enabled: the agent watches the k8s/production/ directory in the deployment-manifests repository and automatically applies changes when merge requests are merged to main. This GitOps workflow means no one (not even CI/CD pipelines) runs kubectl commands against production directly. All changes go through merge requests in the manifests repository, providing a complete audit trail. Access is controlled through the agent's configuration file, which specifies which projects and groups are authorized to use the agent. A team managing order-processing-service would configure their agent to allow CI/CD access from the services/order-processing group and GitOps sync from the deployments/production project.
A critical gotcha is the RBAC scoping of the agent's service account. If the agent runs with cluster-admin privileges, any CI/CD job that uses the agent effectively has unrestricted access to the entire cluster. Always create a dedicated service account for the agent with the minimum required permissions: for CI/CD access, limit it to specific namespaces; for GitOps, limit it to the resources it needs to manage. Another common issue is the agent configuration file location: it must be at exactly .gitlab/agents/<agent-name>/config.yaml in the project where the agent is registered. If the file is missing or in the wrong location, the agent will connect but have no configuration. Also, be aware that GitOps mode and CI/CD access are independent features that can be enabled separately; many teams use CI/CD access for staging (where they want flexibility) and GitOps for production (where they want strict auditability).