Loading Now

Giving the Copilot SDK Agent a "hardware-level helmet" using Kata microVM on AKS

Recently, I was working on creating a service using the GitHub Copilot SDK. Once I had everything set up, I reviewed the execution logs and noticed something surprising:

In one conversation, the Agent executed a shell command, read multiple files, and downloaded a third-party MCP server from npm using npx—all without my intervention.

I hadn’t programmed any of that in advance. The model autonomously decided, in real time, to run those commands, access those files, and install that package.

That’s when it struck me: a large part of the code running in this container was generated dynamically — not by me, but by the model itself.

This is a significant shift compared to a typical web service. In a standard application, every line of code is crafted by a human, carefully reviewed, and tested before deployment. However, with an AI Agent, some behaviours unfold at runtime, meaning you can’t predict exactly what it will do beforehand.

This raises a vital question: does the container housing the AI Agent provide adequate security?

To explain this further, let’s consider an analogy.

Imagine a traditional container as an apartment in a block of flats. Each apartment has its own walls—namespaces and cgroups serve to keep things compartmentalised. Inside, it feels private.

However, all apartments share the same roof—the host Linux kernel.

Generally, this works well. But if a vulnerability is discovered in the roof—think of a kernel flaw—someone could potentially move across the roof and gain access to any other apartment in the block. This is known as a container escape.

In standard web applications, this risk is manageable as the code inside your container is predictable. An AI Agent, however, presents a different scenario: the code executing within the container is fundamentally unpredictable. Your concern isn’t an external intruder; it’s the Agent itself.

Docker clearly articulated this in their blog post Comparing Sandboxing Approaches for AI Agents:

AI Agents require a level of sandboxing that traditional shared-kernel containers simply cannot provide.

So, what is a viable solution?

Returning to the building analogy, if the issue lies with a shared roof, the answer is quite straightforward: ensure each apartment has its own roof.

You still have your apartment (the container), and the building is managed in the same way (Kubernetes). However, now you have your own ceiling above you. Even if you breach it, you would only break through your own roof—your neighbours remain untouched.

This concept encapsulates the essence of a microVM.

Koyeb has a fantastic overview titled What Is a microVM. Here’s a summary:

  1. It functions as a virtual machine—with its own independent guest kernel, completely isolated from the host kernel. This isolation is where the security lies.
  2. But it’s a trimmed-down version—only the essentials: CPU, memory, network, and block storage. No USB ports, no audio devices, no GPU passthrough.
  3. So it’s both fast and lightweight—offering millisecond boot times, a reduced memory footprint, and an experience close to that of containers.

In short: microVM = VM-level isolation + container-like efficiency.

It’s great to understand the advantages of microVMs, but keep in mind, Kubernetes operates with Pods and containers, not VMs. How can we connect these two frameworks?

That’s precisely the role of Kata Containers. Their slogan perfectly captures it:

“The speed of containers, the security of VMs.”

Kata acts as a bridge between Kubernetes and microVMs:

  • From Kubernetes’ viewpoint, it appears as a standard Pod—scheduled, managed, and monitored just like any other.
  • Internally, that Pod runs in a lightweight VM with its own kernel.

You won’t have to tweak your application code or change your CI/CD pipeline. Just instruct Kubernetes: “Run this Pod with Kata’s RuntimeClass,” and Kata will handle the rest.

On Azure Kubernetes Service (AKS), Microsoft has integrated Kata by default under the name Pod Sandboxing. The hypervisor used is Microsoft Hyper-V (not QEMU), and the RuntimeClass is named kata-vm-isolation. You create a specific node pool, and AKS configures it all automatically.

Now, let’s get practical. I developed a demo called AKS_MicroVM that serves one purpose:

To run a GitHub Copilot SDK Agent service on AKS, specifically enforced to operate within the kata-vm-isolation—a microVM sandbox.

Here’s how the architecture looks:

HTTPS request arrives
  └─ AKS Node Pool (KataVmIsolation enabled)
      └─ Pod (runtimeClassName: kata-vm-isolation)
          └─ Dedicated Hyper-V microVM
              └─ FastAPI service (Python / uvicorn)
                  └─ GitHubCopilotAgent
                      └─ Copilot CLI (Node.js)
                          └─ MCP servers / tools
              Isolated guest kernel + seccomp + cgroup
          Egress limited by NetworkPolicy

From an external perspective, it behaves like a standard AKS Pod. Internally, however, the application operates within its own micro virtual machine, accompanied by a dedicated kernel.

The entire sample consists of these files:

app/                       ← Agent service (Python)
  main.py                  ← FastAPI endpoints
  agent.py                 ← Copilot Agent wrapper
  tools.py                 ← Example function tools
  requirements.txt

Dockerfile                 ← Python 3.12 + Node 20 + Copilot CLI

k8s/                       ← Kubernetes configurations
  namespace.yaml
  runtimeclass.yaml        ← Reference (AKS auto-creates this)
  secret.example.yaml      ← Token placeholder
  deployment.yaml          ← The main file: enforces kata-vm-isolation
  service.yaml
  networkpolicy.yaml       ← Secures ingress/egress

infra/                     ← Infrastructure scripts
  01-create-aks.sh         ← Create the cluster
  02-build-push.sh         ← Build image and push to ACR
  03-deploy.sh             ← Deploy everything

Just three shell scripts to set up the infrastructure and six YAML files to deploy the service.

I want to highlight that this sample doesn’t simply impose a microVM and call it a day. It incorporates five layers of security:

ConcernResolution
Malicious code escaping the containerkata-vm-isolation → dedicated microVM with its own kernel
Privilege escalation within the containerrunAsNonRoot + drop ALL caps + read-only filesystem + seccomp
Agent sending data to unauthorised endpointsNetworkPolicy allowlist — only Copilot/GitHub/MCP egress allowed
Token leakageK8s Secret injection (easily upgradeable to Key Vault via CSI)
Model instructing the Agent to execute risky actionson_permission_request defaults to deny; only approved operations are allowed

The microVM serves as the outermost defence—a form of hardware-grade isolation. But inside this barrier, there are still guards, access controls, and surveillance measures. You require all of them.

# ① Create an AKS cluster with Kata support
bash infra/01-create-aks.sh

# ② Check that the RuntimeClass is operational
kubectl get runtimeclass kata-vm-isolation

# ③ Build the image and upload it to ACR (script auto-detects your ACR)
bash infra/02-build-push.sh

# ④ Insert your GitHub Copilot token
#    Edit k8s/secret.example.yaml → rename it to secret.yaml (don’t commit it!)

# ⑤ Implement everything
bash infra/03-deploy.sh

# ⑥ Access via API server proxy
kubectl proxy --port=8001

After that, chat with the Agent:

curl -s -X POST \
  http://localhost:8001/api/v1/namespaces/copilot-agent/services/copilot-agent:80/proxy/chat \
  -H 'content-type: application/json' \
  -d '{"message":"Briefly introduce Kata Containers."}'

Want live output? Try the streaming endpoint:

curl -N -X POST \
  http://localhost:8001/api/v1/namespaces/copilot-agent/services/copilot-agent:80/proxy/chat/stream \
  -H 'content-type: application/json' \
  -d '{"message":"List 3 Linux kernel hardening tips","stream":true}'

Need a quick check?

kubectl -n copilot-agent exec deploy/copilot-agent -- uname -r

If the kernel version differs from that of the node — your Pod is operating under its own guest kernel, keeping it separate from the host’s. That’s your proof.

Note that kubectl port-forward is incompatible with Kata Pods. This is an easy pitfall to stumble into. While the app listener runs inside the microVM, port-forward connects to an empty sandbox netns on the host—resulting in a “connection refused” error. Use kubectl proxy instead.

Environment variable names for tokens. The Copilot CLI requires GH_TOKEN or GITHUB_TOKEN—not a custom designation. The Deployment automatically injects both from the same Secret.

A read-only filesystem necessitates emptyDir mounts. The container operates with a readOnlyRootFilesystem: true setting, but the Copilot CLI needs to write to /home/agent/.cache during startup. The Deployment mounts emptyDir volumes at .cache, .copilot, and /tmp—miss even one and the CLI might fail to launch.

Keep on_permission_request set to deny by default. The tool calls made by the Agent pass through a permission gate that defaults to deny, only allowing specified operations to proceed. Avoid changing this to approve-all in production.

To recap clearly:

① Scenario: AI Agents run model-generated, potentially untrusted code in containers
② Problem: Traditional containers share the host kernel—one escape compromises the entire node
③ Insight: We need stronger isolation than what namespaces provide
④ Solution: microVMs—each Pod gets its own dedicated guest kernel
⑤ Integration: Kata Containers brings microVM functionality to Kubernetes; AKS Pod Sandboxing makes it seamless
⑥ Implementation: The AKS_MicroVM example—six simple steps to deploy, bolstered by five levels of defence

In this era of AI Agents, a container isn’t merely a container for your application—it’s a box for uncertainty. It demands a more robust protective layer. That’s where the microVM comes into play.

Access the complete source code here: https://github.com/kinfey/Multi-AI-Agents-Cloud-Native/tree/main/code/AKS_MicroVM

For more insights, check out:

Share this content:


Discover more from Qureshi

Subscribe to get the latest posts sent to your email.

Discover more from Qureshi

Subscribe now to keep reading and get access to the full archive.

Continue reading