security
10 TopicsHardening OpenClaw on AKS: Mitigating Container Escapes with Kata microVM Isolation
What is OpenClaw, and what security challenges does it pose with container escapes? OpenClaw is an open-source autonomous AI agent designed for power users and developers to automate tasks, such as managing emails, files, and scheduling via chat apps like WhatsApp or Telegram. While OpenClaw functions as a powerful autonomous assistant, its runtime model creates a massive security paradox: to be truly useful, the agent requires broad permissions to your filesystem and APIs, yet this "God Mode" access often lacks the rigorous containerized isolation typical of enterprise workloads. Because many users run the framework natively rather than within a hardened sandbox, the primary security challenge is that a single malicious "Skill" or an indirect prompt injection can escalate into full system compromise. This structural vulnerability, exemplified by high-profile exploits like CVE-2026-25253, transforms the agent from a helpful tool into a high-risk entry point for lateral movement and data exfiltration within a private network. Why container escapes matter in OpenClaw-style deployments: because containers share the host kernel, a successful container escape turns a single compromised container into a host compromise (or at least a compromise of other co-located workloads). This is especially important when OpenClaw runs code from many tenants, many teams, or varying trust levels on the same worker nodes. That soft isolation is often permeable due to the following structural and configuration-based weaknesses: Shared-kernel attack surface: the container boundary is not a hypervisor boundary. Kernel vulnerabilities (e.g., privilege escalation bugs) can allow a process in a container to gain host-level privileges. Excessive privileges / misconfiguration: running with --privileged, broad Linux capabilities, hostPath mounts, access to the Docker socket, or device passthrough (e.g., /dev/kvm, /dev/fuse) can provide direct paths to host control. Filesystem and namespace boundary breaks: mount namespace confusion, writable host mounts, or mistakes in chroot/pivot_root handling can expose host files and credentials. Supply-chain and image risk: a malicious image or dependency can execute within the container and then attempt escalation/escape. Blast radius: once the host is compromised, attackers can access node-level secrets (service account tokens, registry creds), tamper with the runtime, sniff traffic, or pivot to other containers and the broader cluster. In short, OpenClaw’s security challenge is not that containers are inherently insecure, but that the isolation boundary is thinner than a VM boundary. When the threat model includes adversarial code execution, a “container-only” isolation strategy often requires additional hardening or a stronger sandbox. What are MicroVMs and Kata Containers, and how do they help mitigate OpenClaw container-escape risks? MicroVMs are lightweight virtual machines optimized for running short-lived or container-like workloads with much lower overhead than traditional VMs. They use hardware virtualization (via a hypervisor such as KVM) but keep the device model and boot path minimal, reducing startup time and the overall attack surface compared to a full general-purpose VM. Kata Containers is an “OCI-compatible containers in a VM” approach: it runs each container (or pod sandbox) inside a dedicated microVM by default (implementation varies by runtime/config). To the orchestration layer (e.g., Kubernetes), it still looks like a container runtime, but isolation is provided by a hypervisor boundary rather than only namespaces/cgroups. Stronger isolation boundary: a container escape that relies on Linux kernel exploitation is far less likely to directly compromise the host, because the workload’s “host” kernel is typically the guest kernel inside the microVM. Reduced blast radius: compromise is contained to the microVM/pod sandbox; lateral movement to other workloads on the same node becomes significantly harder. Smaller and more controllable attack surface: minimal device models, tighter default privileges, and fewer host mounts/devices exposed to the workload. Defense-in-depth with container controls: you still can (and should) apply seccomp, capabilities dropping, read-only root filesystems, and LSMs inside the guest, but the hypervisor boundary becomes an additional layer. Better fit for hostile multi-tenant workloads: when OpenClaw executes third-party jobs/plugins, Kata-style sandboxing aligns better with an adversarial threat model. Solution overview Figure 1 illustrates a Kubernetes-based sandboxing architecture for running OpenClaw workloads with stronger isolation. The design keeps the developer experience and packaging model of containers (OCI images, Kubernetes scheduling) while ensuring that untrusted agent code executes inside a microVM boundary using Kata Containers. This reduces the likelihood that a container escape can compromise the underlying node or other co-located workloads. Key components: (1) Application gateway for HTTPS traffic to the backend, (2) Kubernetes as the orchestration, scheduling and policy enforcement plane, (3) a container runtime (e.g., containerd) configured with a Kata Containers runtime class, (4) KVM-backed microVMs that provide the isolation boundary for each untrusted workload and (5) Azure files for persistent storage which allows scaling of OpenClaw. Figure 1: Solution architecture diagram End-to-end flow: Traffic Entry via Application Gateway: Incoming user requests (e.g., from WhatsApp or Discord) first hit the Azure Application Gateway. Orchestration in AKS: The traffic is routed into an Azure Kubernetes Service (AKS) cluster, which manages the lifecycle of the OpenClaw agent and its associated "Skills." Hardened Execution via Kata Containers: Instead of running in standard shared-kernel containers, the OpenClaw agent runs inside Kata Containers. This provides a dedicated lightweight VM for the agent, creating a hardware-level isolation boundary that prevents "container escapes" from compromising the host. Stateful Storage in Azure Files: The agent interacts with Azure Files to read and write persistent data, such as conversation history, configuration files, and downloaded assets, ensuring data remains available even if the container is restarted. Security posture: by shifting isolation from “shared-kernel containers” to “containers inside microVMs,” the architecture limits the blast radius of kernel-level exploits and common escape paths. Even if an attacker achieves code execution within an OpenClaw container, they must additionally break the microVM/hypervisor boundary to affect the node or neighboring workloads, providing a strong defense-in-depth improvement over standard container alone. Implement the solution This section describes how to deploy the solution architecture. In this post, you’ll perform the following tasks: Create a Kata VM-isolated AKS node pool Mount a NFS persistent storage Create the application ConfigMap Deploy the OpenClaw gateway Expose the gateway internally Set up TLS termination Route external traffic through the Azure application gateway for containers. Ensure that you have the following prerequisites deployed before moving to the next section: An AKS cluster provisioned in Azure An Azure NFS File Share with private link enabled. An Application gateway for containers managed by ALB controller Kubectl configured and pointing to the cluster Az CLI authenticated with the correct subscription Initialise environment variables In your Linux terminal, export these variables with your own values. They will be used in later commands. export cluster_name=<CLUSTER_NAME> export resource_group=<RESOURCE_GROUP> Create the AKS Node Pool with Kata VM Isolation The OpenClaw gateway pods require Kata VM isolation (runtimeClassName: kata-vm-isolation). You must create a dedicated AKS node pool that supports this runtime before deploying any workloads. Use the Azure CLI to add a node pool with the Kata VM isolation workload runtime to your existing AKS cluster: az aks nodepool add \ --resource-group $resource_group \ --cluster-name $cluster_name \ --name katanp \ --node-count 2 \ --node-vm-size Standard_D4s_v3 \ --os-sku AzureLinux \ --workload-runtime KataMshvVmIsolation \ --labels agentpool=katanp **Important:** The `--workload-runtime KataMshvVmIsolation` flag enables the `kata-vm-isolation` runtime class on the node pool. The VM size must support nested virtualization (D-series v3/v5, E-series v3/v5, etc.). Create NFS Persistent Volume The deployment uses an Azure Files NFS share for persistent workspace storage. The PersistentVolume must exist before the PVC can bind to it. Replace volumeHandle and volumeAttributes with your own Azure Files values. cat <<EOF | kubectl apply -f - apiVersion: v1 kind: PersistentVolume metadata: name: openclaw-nfs-pv spec: capacity: storage: 100Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain mountOptions: - sec=sys - noresvport - actimeo=30 csi: driver: file.csi.azure.com volumeHandle: <resource-group>#<storage-account>#<share-name> volumeAttributes: resourceGroup: <resource-group> shareName: <share-name> protocol: nfs server: <storage-account>.privatelink.file.core.windows.net EOF Verify that the persistent volume is created. kubectl get pv openclaw-nfs-pv Figure 2: Persistent volume Create the NFS PersistentVolumeClaim The PVC binds to the PV created. The deployment references this PVC by name (`pvc-openclaw-nfs`). cat <<EOF | kubectl apply -f - apiVersion: v1 kind: PersistentVolumeClaim metadata: # The name of the PVC name: pvc-openclaw-nfs spec: accessModes: - ReadWriteMany resources: requests: # The real storage capacity in the claim storage: 50Gi # This field must be the same as the storage class name in StorageClass storageClassName: "" volumeName: openclaw-nfs-pv EOF Verify that the persistent volume claim is created successfully. The status should show bound. Figure 3: Persistent Volume Claim Create the ConfigMap The ConfigMap provides the openclaw.json configuration file to the gateway pods. It configures allowed CORS origins for the control UI and the gateway token. Replace the allowed origins with your own ALB frontend URL. The ConfigMap also stores the gateway auth token, so DO NOT hardcode your token here. Always keep it as a variable rather than storing it in plain text so that, if attackers gain access to this file, they cannot see the OpenClaw gateway auth token. cat <<EOF | kubectl apply -f - apiVersion: v1 kind: ConfigMap metadata: name: openclaw-config data: openclaw.json: | { "gateway": { "auth": { "token": "${AUTH_TOKEN}" }, "controlUi": { "allowedOrigins": [ "https://<YOUR ALB FRONTEND URL>.alb.azure.com" ] } } } EOF Create the Auth Token Secret The OpenClaw gateway requires an authentication token to secure access. The deployment references a Kubernetes Secret named openclaw-auth-token and injects it into the container as the AUTH_TOKEN environment variable via secretKeyRef. Generate a random token (or use an existing one) and create the kubernetes secret. # Generate a random 32-byte hex token AUTH_TOKEN=$(openssl rand -hex 32) echo "$AUTH_TOKEN" # save this — you'll need it to authenticate with the gateway kubectl create secret generic openclaw-auth-token \ --from-literal=token="$AUTH_TOKEN" If the secret does not exist when the deployment is applied, pods will fail with `CreateContainerConfigError`. Deploy the OpenClaw Gateway This is the main application deployment. It depends on all previous steps: - Kata node pool (pods require runtimeClassName: kata-vm-isolation and nodeSelector: agentpool=katanp) - PVC (pvc-openclaw-nfs for persistent workspace data) - ConfigMap (openclaw-config for openclaw.json) Key details: - Runs 2 replicas with a rolling update strategy - Uses an init container to copy the config file to a writable volume - Exposes port 18789 - Includes liveness and readiness probes on /health - Resource requests: 500m CPU, 512Mi memory - Resource limits: 2 CPU, 2Gi memory cat <<EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: openclaw-gateway spec: replicas: 2 selector: matchLabels: app: openclaw-gateway strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 maxSurge: 1 template: metadata: labels: app: openclaw-gateway spec: runtimeClassName: kata-vm-isolation nodeSelector: agentpool: katanp securityContext: fsGroup: 1000 initContainers: - name: copy-openclaw-config image: alpine/openclaw:latest env: - name: HOME value: /writable command: - sh - -c - | cp /config/openclaw.json /writable/openclaw.json \ && chown 1000:1000 /writable/openclaw.json \ && echo "--- Config file contents ---" \ && cat /writable/openclaw.json volumeMounts: - name: openclaw-config-volume mountPath: /config - name: openclaw-writable mountPath: /writable containers: - name: gateway image: alpine/openclaw:latest ports: - containerPort: 18789 env: - name: NODE_OPTIONS value: "--max-old-space-size=4096" - name: AUTH_TOKEN valueFrom: secretKeyRef: name: openclaw-auth-token key: token # Start gateway the way the tutorial indicates command: ["openclaw", "gateway"] args: ["run", "--allow-unconfigured", "--bind", "lan"] volumeMounts: - name: openclaw-writable mountPath: /home/node/.openclaw - name: openclaw-data mountPath: /home/node/workspace subPath: workspace resources: requests: cpu: "500m" memory: "2Gi" limits: cpu: "1000m" memory: "4Gi" livenessProbe: httpGet: path: /health port: 18789 initialDelaySeconds: 60 periodSeconds: 15 failureThreshold: 3 readinessProbe: httpGet: path: /health port: 18789 initialDelaySeconds: 10 periodSeconds: 5 volumes: - name: openclaw-data persistentVolumeClaim: claimName: pvc-openclaw-nfs - name: openclaw-config-volume configMap: name: openclaw-config items: - key: openclaw.json path: openclaw.json - name: openclaw-writable emptyDir: {} --- apiVersion: v1 kind: Service metadata: name: openclaw-gateway-service spec: type: ClusterIP selector: app: openclaw-gateway ports: - protocol: TCP port: 18789 targetPort: 18789 EOF Verify that the deployment succeeds. Wait until all pods show `Running` and `READY 2/2`. kubectl get deployment openclaw-gateway kubectl get pods -l app=openclaw-gateway Figure 4: OpenClaw deployment Create the TLS secret (for HTTPS) The Application Gateway for Containers references a TLS secret (gateway-tls-secret) for HTTPS termination. This blog post uses a self-signed certificate; in a production environment, use a certificate signed by a certificate authority. Replace `<path-to-tls-cert>` and `<path-to-tls-key>` with paths to your TLS certificate and private key files. kubectl create secret tls gateway-tls-secret \ --cert=<path-to-tls-cert> \ --key=<path-to-tls-key> Create the Gateway The Gateway resource defines the HTTPS listener on the Azure Application Load Balancer (ALB). Update the `alb.network.azure.com/application-gateway-id` annotation to match your ALB traffic controller resource ID. You will also need to reference the gateway-tls-secret to enable HTTPS. cat <<EOF | kubectl apply -f - apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: https annotations: alb.network.azure.com/application-gateway-id: /subscriptions/<subscription id>/resourceGroups/mc_openclaw_openclaw-cluster_centralus/providers/Microsoft.ServiceNetworking/trafficControllers/<alb id> alb.networking.azure.io/alb-namespace: default alb.networking.azure.io/alb-name: alb-openclaw spec: gatewayClassName: azure-alb-external listeners: - name: https protocol: HTTPS port: 443 allowedRoutes: namespaces: from: All tls: mode: Terminate certificateRefs: - kind: Secret group: "" name: gateway-tls-secret EOF kubectl get gateway https Wait until the Gateway shows a `Programmed=True` condition. Create the HTTPRoute The HTTPRoute connects the Gateway to the backend Service. It routes all traffic (`/` prefix) from the HTTPS Gateway to `openclaw-gateway-service` on port 18789. cat <<EOF | kubectl apply -f - kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1 metadata: name: http-route spec: parentRefs: - name: https rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: openclaw-gateway-service kind: Service namespace: default port: 18789 EOF Test OpenClaw application Get the external endpoint. kubectl get gateway https -o jsonpath='{.status.addresses[0].value}' Paste the endpoint into your browser to reach the OpenClaw application. If you are using a self-signed certificate, you will see a “Not secure” warning; click Advanced to proceed. In a production environment with a certificate signed by a certificate authority, you should not see that warning. Figure 5: OpenClaw Authentication Paste in your Gateway Token (the auth token created earlier). You will notice that even though the token is valid, it throws back a “pairing required” error. Pairing is required in OpenClaw whenever a new device, browser profile, or CLI client attempts to connect to the gateway for the first time, ensuring only authorized clients can control the AI agent. POD=$(kubectl get pod -l app=openclaw-gateway -o jsonpath='{.items[0].metadata.name}') POD2=$(kubectl get pod -l app=openclaw-gateway -o jsonpath='{.items[1].metadata.name}') TOKEN=$(kubectl get secret openclaw-auth-token -o jsonpath='{.data.token}' | base64 -d) kubectl exec "$POD" -c gateway -- openclaw devices approve --latest --token "$TOKEN" kubectl exec "$POD2" -c gateway -- openclaw devices approve --latest --token "$TOKEN" You should see a message like the one in the image below. You can now open the OpenClaw application and start using it. Figure 6: OpenClaw pairing success message Figure 7: OpenClaw Application You have successfully deployed OpenClaw within a microVM hosted on Azure Kubernetes Service. Test microVM kernel isolation From within the OpenClaw pod, try to read the host’s root filesystem via /proc/1/root. You should see an error like: ls: cannot access '/proc/1/root/etc/kubernetes': No such file or directory. kubectl exec -it "$POD" -c gateway -- ls /proc/1/root/etc/kubernetes 2>&1 In a standard container deployment, PID 1 inside the container is still running on the host kernel, so traversing /proc/1/root/ exposes the host's root filesystem — including sensitive paths like /etc/kubernetes (which holds kubelet credentials). With Kata VM isolation, the picture is completely different. When we run ls /proc/1/root/etc/kubernetes from inside the OpenClaw pod, it returns "No such file or directory". This is because PID 1 is no longer a process on the host — it's running inside a dedicated guest VM with its own kernel. The /proc/1/root/ path leads to the microVM's root filesystem, not the host's, and that microVM has no knowledge of the node's Kubernetes configuration or machine identity. The host is simply invisible. This is the core security guarantee of Kata Containers: even if an attacker achieves a full container escape, there is nothing to escape to — they land inside a lightweight VM boundary, not on the shared host, making lateral movement to other pods or the node itself impossible. Conclusion This post discussed why running OpenClaw workloads in standard containers can be risky when the workload includes untrusted or semi-trusted code: containers share the host Linux kernel, so a single container escape or privileged misconfiguration can expand into node-level compromise and a much larger blast radius. To address this, we introduced microVM-based sandboxing with Kata Containers on Azure Kubernetes Service (AKS) and walked through an implementation approach (a node pool with Kata VM isolation, storage, gateway deployment, and ingress). Finally, we validated the isolation properties by demonstrating that common host-visibility techniques (for example, probing /proc/1/root) no longer reveal host paths when the workload runs inside a microVM. Separate kernel boundary: Kata runs the container inside a microVM, so the workload executes against a guest kernel rather than the shared host kernel—kernel exploits and escape attempts don’t directly translate into host control. Host filesystem is no longer “in scope”: paths that often leak host context in standard containers (for example, traversals via /proc) resolve inside the microVM’s filesystem, not the node’s root filesystem. Reduced blast radius per workload: each sandbox has its own VM boundary, making it much harder to pivot from one compromised workload to other pods/containers on the same node. Stronger default device and privilege separation: the hypervisor boundary and minimal virtual device model limit exposure to host devices and privileged interfaces that commonly enable breakouts. Defense-in-depth still applies: you can keep container hardening (seccomp, capability dropping, read-only filesystems, restricted mounts) while gaining an additional isolation layer that is independent of Linux namespaces/cgroups. Overall, this post helps you deploy OpenClaw on AKS with Kata microVM isolation so you can run agent workloads with a significantly reduced risk of host-kernel compromise from container escape techniques.Extracting and Auditing Azure DevOps Permissions at Scale with PowerShell
Managing access in Azure DevOps is easy at small scale — and increasingly opaque as organizations grow. This post introduces ADO Permissions Output, an open-source PowerShell toolset that queries Azure DevOps REST APIs across 30+ security namespaces, decodes bitmask permissions, resolves cryptic GUIDs and tokens into readable names, and produces structured JSON/CSV output ready for Power BI. It also surfaces "ghost" members — users who appear in ADO through nested Entra groups but hold no active entitlement — which the standard Graph API alone cannot detect. Whether you're preparing for a compliance review or just want to know who actually has access to what, this tool closes the gap between the ADO portal and a complete audit picture.OPNsense Firewall as Network Virtual Appliance (NVA) in Azure
This blog is available as a video on YouTube: youtube.com/watch?v=JtnIFiB7jkE Introduction to OPNsense In today’s cloud-driven world, securing your infrastructure is more critical than ever. One powerful solution is OPNsense. OPNsense is a powerful open-source firewall that can be used to secure your virtual networks. Originally forked from pfSense, which itself evolved from m0n0wall. OPNsense could run on Windows, MacOS, Linux including OpenBSD and FreeBSD. It provides a user-friendly web interface for configuration and management. What makes OPNsense Firewall stand out is its rich feature set: VPN Support for point-to-site and site-to-site connections using technologies like WireGuard and OpenVPN. DNS Management with options such as OpenDNS and Unbound DNS. Multi-network handling enabling you to manage different LANs seamlessly. Advanced security features including intrusion detection and forward proxy integration. Plugin ecosystem supporting official and community extensions for third-party integrations. In this guide, you’ll learn how to install and configure OPNsense Firewall on an Azure Virtual Machine, leveraging its capabilities to secure your cloud resources effectively. We'll have three demonstrations: Installing OPNsense on an Azure virtual machine Setting up point-to-site VPN using WireGuard Here is the architecture we want to achieve in this blog, except the Hb and Spoke configuration which is planned for the second part coming soon. 1. Installing OPNsense on an Azure Virtual Machine There are three ways to have OPNsense in a virtual machine. Create a VM from scratch and install OPNsense. Install using the pre-packaged ISO image created by Deciso the company that maintains OPNsense. Use a pre-built VM image from the Azure Marketplace. In this demo, we will use the first approach to have more control over the installation and configuration. We will create an Azure VM with FreeBSD OS and then install OPNsense using a shell script through the Custom Script Extension. All the required files are in this repository: github.com/HoussemDellai/azure-network-course/205_nva_opnsense. The shell script configureopnsense.sh will install OPNsense and apply a predefined configuration file config.xml to set up the firewall rules, VPN, and DNS settings. It will take 4 parameters: GitHub path where the script and config file are hosted, in our case it is /scripts/. OPNsense version to install, currently set to 25.7. Gateway IP address for the trusted subnet. Public IP address of the untrusted subnet. This shell script is executed after the VM creation using the Custom Script Extension in Terraform represented in the file vm_extension_install_opnsense.tf. OPNsense is intended to be used an NVA so it would be good to apply some of the good practices. One of these practices is to have two network interfaces: Trusted Interface: Connected to the internal network (spokes). Untrusted Interface: Connected to the internet (WAN). This setup allows OPNsense to effectively manage and secure traffic between the internal network and the internet. Second good practice is to start with a predefined configuration file config.xml that includes the basic settings for the firewall, VPN, and DNS. This approach saves time and ensures consistency across deployments. It is recommended to start with closed firewall rules and then open them as needed based on your security requirements. But for demo purposes, we will allow all traffic. Third good practice is to use multiple instances of OPNsense in a high-availability setup to ensure redundancy and failover capabilities. However, for simplicity, we will use a single instance in this demo. Let's take a look at the resources that will be created by Terraform using the AzureRM provider: Resource Group Virtual Network (VNET) named vnet-hub with two subnets: Trusted Subnet: Internal traffic between spokes. Untrusted Subnet: Exposes the firewall to the internet. Network Security Group (NSG): attached to the untrusted subnet, with rules allowing traffic to the VPN, OPNsense website and to the internet. Virtual Machine: with the following configuration: FreeBSD OS image using version 14.1. VM size: Standard_D4ads_v6 with NVMe disk for better performance. Admin credentials: feel free to change the username and password with more security. Two NICs (trusted and untrusted) with IP forwarding enabled to allow traffic to pass through the firewall. NAT Gateway: attached to the untrusted subnet for outbound internet connectivity. Apply Terraform configuration To deploy the resources, run the following commands in your terminal from within the 205_nva_opnsense directory: terraform init terraform apply -auto-approve Terraform provisions the infrastructure and outputs resource details. In the Azure portal you should see the newly created resources. Accessing the OPNsense dashboard To access the OPNsense dashboard: Get the VM’s public IP from the Azure portal or from Terraform output. Paste it into your browser. Accept the TLS warning (TLS is not configured yet). Log in with Username: root and Password: opnsense you can change it later in the dashboard. You now have access to the OPNsense dashboard where you can: Monitor traffic and reports. Configure firewall rules for LAN, WAN, and VPN. Set up VPNs (WireGuard, OpenVPN, IPsec). Configure DNS services (OpenDNS, UnboundDNS). Now that the OPNsense firewall is up and running, let's move to the next steps to explore some of its features like VPN. 2. Setting up Point-to-Site VPN using WireGuard We’ll demonstrate how to establish a WireGuard VPN connection to OPNsense firewall. The configuration file config.xml used during installation already includes the necessary settings for WireGuard VPN. For more details on how to set up WireGuard on OPNsense, refer to the official documentation. We will generate a Wireguard peer configuration using the OPNsense dashboard. Navigate to VPN > WireGuard > Peer generator then add a name for the peer, fill in the IP address for the OPNsense which is the public IP of the VM in Azure, use the same IP if you want to use the pre-configured UnboundDNS. Then copy the generated configuration and click on Store and generate next and Apply. Next we'll use that configuration to set up WireGuard on a Windows client. Here you can either use your current machine as a client or create a new Windows VM in Azure. We'll go with this second option for better isolation. We'll deploy the client VM using Terraform file vpn_client_vm_win11.tf. Make sur it is deployed using command terraform apply -auto-approve. Once the VM is ready, connect to it using RDP, download and install WireGuard. Alternatively, you can install WireGuard using the following Winget command: winget install -e --id WireGuard.WireGuard --accept-package-agreements --accept-source-agreements Launch WireGuard application, click on Add Tunnel > Add empty tunnel..., then paste the peer configuration generated from OPNsense and save it. Then click on Activate to start the VPN connection. We should see the data transfer starting. We'll verify the VPN connection by pinging the VM, checking the outbound traffic passes through the Nat Gateway's IPs and also checking the DNS resolution using UnboundDNS configured in OPNsense. ping 10.0.1.4 # this is the trusted IP of OPNsense in Azure # Pinging 10.0.1.4 with 32 bytes of data: # Reply from 10.0.1.4: bytes=32 time=48ms TTL=64 # ... curl ifconfig.me/ip # should display the public IP of the Nat Gateway in Azure # 74.241.132.239 nslookup microsoft.com # should resolve using UnboundDNS configured in OPNsense # Server: UnKnown # Address: 135.225.126.162 # Non-authoritative answer: # Name: microsoft.com # Addresses: 2603:1030:b:3::152 # 13.107.246.53 # 13.107.213.53 # ... The service endpoint ifconfig.me is used to get the public IP address of the client. You can use any other similar service. What's next ? Now that you have OPNsense firewall set up as an NVA in Azure and have successfully established a WireGuard VPN connection, we can explore additional features and configurations such as integrating OPNsense into a Hub and Spoke network topology. That will be covered in the next part of this blog. Special thanks to 'behind the scene' contributors I would like to thank my colleagues Stephan Dechoux thanks to whom I discovered OPNsense and Daniel Mauser who provided a good lab for setting up OPNsense in Azure available here https://github.com/dmauser/opnazure. Disclaimer The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages.Using the Microsoft Defender for Endpoint Files API to Validate Malware Hashes
Introduction Security advisories frequently include file hashes (SHA-1 or SHA-256) as indicators of compromise (IoCs). Microsoft Defender for Endpoint (MDE) exposes a Files API that lets SecOps quickly look up Microsoft’s verdict and metadata for a given hash. This enables rapid assessment—whether a file is classified as Malicious, Suspicious, Clean, or Unknown—and helps analysts decide the next response action without needing to download or execute the sample. What is the Files API in MDE and why is it used in Security Operations? The Files API is part of the Defender for Endpoint REST APIs that returns a file profile by hash identifier. Analysts use it to: • Validate whether Microsoft has a global verdict for a hash named in an advisory. • Retrieve telemetry such as global prevalence and first/last observed times to gauge risk and spread. • Pivot to related alerts and devices when needed. This lookup shortens triage time and avoids unnecessary handling of potentially dangerous samples. Prerequisites To call the Files API using application (client credentials) context, you need: A Microsoft Entra ID App Registration (Web app / service). API permissions on the WindowsDefenderATP resource (Microsoft Defender for Endpoint). Minimum: File.Read.All (Application). Admin consent granted for the permissions. Network access to the MDE API endpoint (region-based base URL) and the Microsoft identity platform (OAuth 2.0). Tip: For interactive testing, you can also use the API Explorer in the Microsoft Defender portal under Partners & APIs, which runs requests under your user context and RBAC scope. How to use the Files API via PowerShell 1) Acquire an OAuth token from the Microsoft identity platform using your app’s client ID and secret with the .default scope for the Defender API. 2) Send an HTTP GET request to the Files endpoint with the hash (SHA-1 or SHA-256) as the identifier. 3) Inspect the JSON response field "fileClassification" and other metadata (globalPrevalence, first/last observed). 4) Use the verdict to decide next actions (e.g., create an Indicator to block, hunt in Advanced Hunting, or open related alerts). Actual Script ===== STEP 1: Get OAuth Token (MDE v1) ===== $tenantId = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" $appId = "xxxxxxxxxxxxxxxxxxxxxxxxxxx" $appSecret = "xxxxxxxxxxxxxxxxxxxxxxxxxxx" # update with your tenant and app values $tokenUri = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" $body = @{ client_id = $appId scope = "https://api.securitycenter.microsoft.com/.default" client_secret = $appSecret grant_type = "client_credentials" } $tokenResponse = Invoke-RestMethod -Uri $tokenUri -Method Post -Body $body -ContentType "application/x-www-form-urlencoded" $token = $tokenResponse.access_token # ===== STEP 2: Call MDE v1 Files API ===== $hash = "97bf5e1a903a978b2281496e0a897688e9d8e6f981238cf91e39bae20390defe" # Replace with your actual hash values. $uri = "https://api.securitycenter.microsoft.com/api/v1.0/files/$hash" try { $response = Invoke-RestMethod -Uri $uri -Headers @{ Authorization = "Bearer $token" Accept = "application/json" } -Method Get } catch { Write-Error "API call failed: $($_.Exception.Message)" if ($_.ErrorDetails.Message) { Write-Host $_.ErrorDetails.Message } return } switch ($response.fileClassification) { "Malicious" { Write-Host "MDE recognises this hash as MALICIOUS. Threat Name: $($response.threatName)" -ForegroundColor Red } "Suspicious" { Write-Host "MDE recognises this hash as SUSPICIOUS." -ForegroundColor Yellow } "Clean" { Write-Host "MDE recognises this hash as CLEAN." -ForegroundColor Green } default { Write-Host "MDE does NOT have a signature for this hash (Unknown)." -ForegroundColor Gray } } $response | ConvertTo-Json -Depth 5 Script Explanation Token acquisition: Uses OAuth 2.0 client credentials flow to obtain an access token; scope targets Defender for Endpoint API. Endpoint call: Builds a GET request to the Files endpoint with the hash identifier. Error handling: Catches HTTP errors and prints server-provided details if available. Verdict mapping: Reads the fileClassification field and prints a color-coded verdict (Malicious, Suspicious, Clean, Unknown). Response output: Prints the full JSON for deeper analysis and logging. Recommended Inputs The Files endpoint accepts SHA-1 or SHA-256 identifiers; ensure you pass the correct hash type. Consider using certificate credentials or managed identity instead of client secrets for production automation. Sample Output API Explorer - Other Option to query File API The Microsoft Defender for Endpoint API Explorer is a tool that helps you explore various Defender for Endpoint APIs interactively. The API Explorer makes it easy to construct and do API queries, test, and send requests for any available Defender for Endpoint API endpoint. Use the API Explorer to take actions or find data that might not yet be available through the user interface. The tool is useful during app development. It allows you to perform API queries that respect your user access settings, reducing the need to generate access tokens. You can also use the tool to explore the gallery of sample queries, copy result code samples, and generate debug information. With the API Explorer, you can: Run requests for any method and see responses in real-time. Quickly browse through the API samples and learn what parameters they support. Make API calls with ease; no need to authenticate beyond the management portal signin. Access API Explorer From the left navigation menu, select Partners & APIs > API Explorer. Supported APIs API Explorer supports all the APIs offered by Defender for Endpoint. The list of supported APIs is available in the APIs documentation. Get started with the API Explorer In the left pane, there's a list of sample requests that you can use. Follow the links and click Run query. Some of the samples may require specifying a parameter in the URL, for example, {File Hash}. Permissions Required You need to log in with an account that has appropriate RBAC roles in Microsoft Defender for Endpoint. API Explorer enforces the same role-based access control (RBAC) as the portal: Security Administrator or Global Administrator for high-privilege actions (e.g., offboarding a device, submitting indicators). Lower roles (e.g., Security Reader) can only run read-only queries like Get file information or Get alerts. No additional API permissions or app registration are needed because requests run under your user context. Conclusion The MDE Files API gives SecOps an immediate way to validate hashes from advisories and threat feeds, reducing time-to-triage and enabling consistent response. When a hash is classified as Malicious or Suspicious, teams can move directly to containment (e.g., creating an Indicator to block). When it is Clean or Unknown, analysts can pivot to hunting, sandboxing, or further intelligence before acting. Integrating this lookup into runbooks helps security operations quickly and safely respond to emerging threats. References Get file information API: https://learn.microsoft.com/en-us/defender-endpoint/api/get-file-information Supported MDE APIs (Endpoint URI & versioning): https://learn.microsoft.com/en-us/defender-endpoint/api/exposed-apis-list Access the Microsoft Defender for Endpoint APIs (intro & app context): https://learn.microsoft.com/en-us/defender-endpoint/api/apis-intro Create an app to access MDE without a user (app registration & permissions): https://learn.microsoft.com/en-us/defender-endpoint/api/exposed-apis-create-app-webapp API Explorer: https://learn.microsoft.com/en-us/defender-endpoint/api/api-explorerTransforming Enterprise AKS: Multi-Tenancy at Scale with Agentic AI and Semantic Kernel
In this post, I’ll show how you can deploy an AI Agent on Azure Kubernetes Service (AKS) using a multi-tenant approach that maximizes both security and cost efficiency. By isolating each tenant’s agent instance within the cluster and ensuring that every agent has access only to its designated Azure Blob Storage container, cross-tenant data leakage risks are eliminated. This model allows you to allocate compute and storage resources per tenant, optimizing usage and spending while maintaining strong data segregation and operational flexibility—key requirements for scalable, enterprise-grade AI applications.Azure Arc and Defender for Servers: Connectivity and Monitoring Script
2. Overview of Defender for Servers Microsoft Defender for Servers is a plan within Microsoft Defender for Cloud that provides advanced threat protection for Windows and Linux servers, whether they are hosted in Azure, on-premises, or in other cloud environments. It includes capabilities such as endpoint detection and response (EDR), vulnerability assessment, file integrity monitoring, and adaptive application controls. Defender for Servers integrates with Microsoft Defender for Endpoint to provide unified security management and threat detection. For more information on Defender for servers visit documentation at the link below. https://learn.microsoft.com/en-us/azure/defender-for-cloud/tutorial-enable-servers-plan 3. Onboarding On-Premises Servers via Azure Arc To onboard on-premises servers to Defender for Servers, Azure Arc is used to project non-Azure machines into Azure. This enables the application of Azure policies, monitoring, and security configurations. The onboarding process involves: - Installing the Azure Connected Machine Agent on the server - Registering the server with Azure Arc - Enabling Defender for Servers in Microsoft Defender for Cloud - Ensuring the server is reporting and compliant with security policies. For more information on connecting on-premises servers to Azure Arc visit documentation in the link below. Connect hybrid machines to Azure using a deployment script - Azure Arc | Microsoft Learn 4. Script Purpose and Details This PowerShell script is designed to help infrastructure administrators verify the health of the HIMDS service (used by Microsoft Defender for Endpoint) and the connectivity status of the Azure Connected Machine Agent (Azure Arc) on multiple servers. It is especially useful in scenarios where administrators do not have access to the Azure portal but need to ensure that servers are properly onboarded and connected. Key functions of the script include: - Reading a list of computer names from a CSV file - Checking the status of the HIMDS service on each machine - Running the 'azcmagent show' command remotely to verify Azure Arc connectivity - Logging and displaying the results with color-coded output 5. PowerShell Script # Path to the CSV file $csvPath = "C:\Path\To\computers.csv" # Import computer names from CSV $computers = Import-Csv -Path $csvPath | Select-Object -ExpandProperty ComputerName # Array to store connected machines $connectedMachines = @() foreach ($computer in $computers) { Write-Host "Checking $computer..." -ForegroundColor Cyan try { # Check HIMDS service $himdsService = Get-Service -ComputerName $computer -Name "himds" -ErrorAction Stop $himdsStatus = $himdsService.Status # Run azcmagent show remotely and parse output $azcmOutput = Invoke-Command -ComputerName $computer -ScriptBlock { try { $output = azcmagent show | Out-String return $output } catch { Write-Error "Failed to run azcmagent: $_" return $null } } if ($azcmOutput -ne $null) { $statusLine = $azcmOutput -split "`n" | Where-Object { $_ -match "Agent Status\s*:\s*Connected" } if ($statusLine) { Write-Host "[$computer] HIMDS Service: $himdsStatus, Azure Arc Status: Connected" -ForegroundColor Green $connectedMachines += $computer } else { Write-Host "[$computer] HIMDS Service: $himdsStatus, Azure Arc Status: Not Connected" -ForegroundColor Yellow } } else { Write-Host "[$computer] HIMDS Service: $himdsStatus, Azure Arc Status: Unknown (command failed)" -ForegroundColor Red } } catch { Write-Host "[$computer] Error: $_" -ForegroundColor Red } } # Output connected machines Write-Host "`nConnected Machines:" -ForegroundColor Cyan $connectedMachines | ForEach-Object { Write-Host $_ -ForegroundColor Green } 6. How It Simplifies Administrative Tasks This script streamlines the process of verifying Azure Arc connectivity across multiple servers. Instead of manually logging into each server and running individual checks, administrators can execute this script to: - Quickly identify which machines are connected to Azure Arc - Detect issues with the HIMDS service - Generate a list of healthy and connected machines - Save time and reduce the risk of human errorToken Protection by using Microsoft Entra ID.
As organizations move to the cloud and adopt SaaS applications, identities are becoming increasingly crucial for accessing resources. Cybercriminals exploit legitimate and authorized identities to steal data and access credentials through methods like phishing, malware, data breaches, brute-force/password spray attacks, and prior compromises. As in past years, password-based attacks on users constitute most identity-related attacks. As MFA blocks most password-based attacks, threat actors are shifting their focus, moving up the cyberattack chain in three ways: 1) attacking infrastructure, 2) bypassing authentication, and 3) exploiting applications. They are leaning more heavily into adversary-in-the-middle (AiTM) phishing attacks and token theft. Over the last year, as Microsoft Digital Defense Report (MDDR 2024) a 146% rise in AiTM phishing attacks. In AiTM attack , the attackers steal tokens instead of passwords. The Frameworks used by attackers go far beyond credential phishing, by inserting malicious infrastructure between the user and the legitimate application the user is trying to access. When the user is phished, the malicious infrastructure captures both the credentials of the user, and the token. By compromising and replaying a token issued to an identity that has already completed multifactor authentication, the threat actor satisfies the validation of MFA and access is granted to organizational resources accordingly. Now it is imperative that tokens must be protected from token theft. Let us understand more on tokens. An Entra identity token is a security token issued by Microsoft Entra ID for authentication and authorization. There are several types: Access Tokens: Grant access to resources on behalf of an authenticated user, containing user and resource information. ID Tokens: Authenticate users, issued in the OpenID Connect flow, containing user identity and authentication details. Refresh Tokens: Obtain new access tokens without re-authentication, usually issued with access tokens and have a longer lifespan. Ensuring Token Security By following best practices, you can significantly enhance the security of your tokens and protect your applications from unauthorized access. Use Secure Transmission: Always transmit tokens over secure channels such as HTTPS to prevent interception by unauthorized parties. Token Binding: Implement Token Protection (formerly known as token binding) to cryptographically tie tokens to client secrets. This prevents token replay attacks from different devices. Conditional Access Policies: Use Conditional Access policies to enforce compliant network checks. This ensures that tokens are only used from trusted networks and devices. Continuous Access Evaluation (CAE): Implement CAE to continuously evaluate the security state of the session. This helps in detecting and revoking tokens if there are changes in the user's security posture, such as network location changes. Short Token Lifetimes: Use short lifetimes for access tokens and refresh tokens to limit the window of opportunity for attackers. Secure Storage: Store tokens securely on the client side, using secure storage mechanisms provided by the operating system, such as Keychain on iOS or Keystore on Android. Regular Audits and Monitoring: Regularly audit token usage and monitor for any unusual activity. This helps in early detection of potential security breaches. Now we will discuss Entra ID new features for Token Protection. Token protection using conditional access : This feature will provide refresh token protection. Compliant network check with Conditional Access: This feature will provide both refresh token and Access token protection. Token protection using conditional access: Token protection (sometimes referred to as token binding in the industry) attempts to reduce attacks using token theft by ensuring a token is usable only from the intended device. When an attacker is able to steal a token, by hijacking or replay, they can impersonate their victim until the token expires or is revoked. Token theft is thought to be a relatively rare event, but the damage from it can be significant. Token protection creates a cryptographically secure tie between the token and the device (client secret) it's issued to. Without the client secret, the bound token is useless. When a user registers a Windows 10 or newer device in Microsoft Entra ID, their primary identity is bound to the device. What this means: A policy can ensure that only bound sign-in session (or refresh) tokens, otherwise known as Primary Refresh Tokens (PRTs) are used by applications when requesting access to a resource. Token protection is currently in public preview Create a Conditional Access policy Users who perform specialized roles like those described in Privileged access security levels are possible targets for this functionality. We recommend piloting with a small subset to begin. The steps that follow help create a Conditional Access policy to require token protection for Exchange Online and SharePoint Online on Windows devices. Sign in to the Microsoft Entra admin center as at least a Conditional Access Administrator. Browse to Protection > Conditional Access > Policies. Select New policy. Give your policy a name. We recommend that organizations create a meaningful standard for the names of their policies. Under Assignments, select Users or workload identities. Under Include, select the users or groups who are testing this policy. Under Exclude, select Users and groups and choose your organization's emergency access or break-glass accounts. 6.Under Target resources > Resources (formerly cloud apps) > Include > Select resources Under Select, select the following applications supported by the preview: Office 365 Exchange Online Office 365 SharePoint Online Choose Select. 7. Under Conditions: Under Device platforms: Set Configure to Yes. Include > Select device platforms > Windows. Select Done. Under Client apps: Set Configure to Yes Under Modern authentication clients, only select Mobile apps and desktop clients. Leave other items unchecked. Select Done. 8. Under Access controls > Session, select Require token protection for sign-in sessions and select Select. 9. Confirm your settings and set Enable policy to Report-only. 10.Select Create to create to enable your policy. After administrators confirm the settings using report-only mode, they can move the Enable policy toggle from Report-only to On. Capture logs and analyze Monitoring Conditional Access enforcement of token protection before and after enforcement. Sign-in logs Use Microsoft Entra sign-in log to verify the outcome of a token protection enforcement policy in report only mode or in enabled mode. Sign in to the Microsoft Entra admin center as at least a Conditional Access Administrator. Browse to Identity > Monitoring & health > Sign-in logs. Select a specific request to determine if the policy is applied or not. Go to the Conditional Access or Report-Only pane depending on its state and select the name of your policy requiring token protection. Under Session Controls check to see if the policy requirements were satisfied or not. You can refer below link to know more about license requirements, prerequisites & limitations. Token protection in Microsoft Entra Conditional Access - Microsoft Entra ID | Microsoft Learn Enable compliant network check with Conditional Access Organizations who use Conditional Access along with the Global Secure Access, can prevent malicious access to Microsoft apps, third-party SaaS apps, and private line-of-business (LoB) apps using multiple conditions to provide defense-in-depth. These conditions might include device compliance, location, and more to provide protection against user identity or token theft. Global Secure Access introduces the concept of a compliant network within Microsoft Entra ID Conditional Access. This compliant network check ensures users connect from a verified network connectivity model for their specific tenant and are compliant with security policies enforced by administrators. The Global Secure Access Client installed on devices or users behind configured remote networks allows administrators to secure resources behind a compliant network with advanced Conditional Access controls. This compliant network feature makes it easier for administrators to manage access policies, without having to maintain a list of egress IP addresses. This removes the requirement to hairpin traffic through organization's VPN. Compliant network check enforcement Compliant network enforcement reduces the risk of token theft/replay attacks. Compliant network enforcement happens at the authentication plane (generally available) and at the data plane (preview). Authentication plane enforcement is performed by Microsoft Entra ID at the time of user authentication. If an adversary has stolen a session token and attempts to replay it from a device that is not connected to your organization’s compliant network (for example, requesting an access token with a stolen refresh token), Entra ID will immediately deny the request and further access will be blocked. Data plane enforcement works with services that support Continuous Access Evaluation (CAE) - currently, only SharePoint & Exchange Online. With apps that support CAE, stolen access tokens that are replayed outside your tenant’s compliant network will be rejected by the application in near-real time. Without CAE, a stolen access token will last up to its full lifetime (default 60-90 minutes). This compliant network check is specific to each tenant. Using this check, you can ensure that other organizations using Microsoft's Global Secure Access services can't access your resources. For example: Contoso can protect their services like Exchange Online and SharePoint Online behind their compliant network check to ensure only Contoso users can access these resources. If another organization like Fabrikam was using a compliant network check, they wouldn't pass Contoso's compliant network check. The compliant network is different than IPv4, IPv6, or geographic locations you might configure in Microsoft Entra. Administrators are not required to review and maintain compliant network IP addresses/ranges, strengthening the security posture and minimizing the ongoing administrative overhead. Enable Global Secure Access signaling for Conditional Access To enable the required setting to allow the compliant network check, an administrator must take the following steps. Sign in to the Microsoft Entra admin center as a Global Secure Access Administrator. Browse to Global Secure Access > Settings > Session management > Adaptive access. Select the toggle to Enable CA Signaling for Entra ID (covering all cloud apps). This will automatically enable CAE signaling for Office 365 (preview). Browse to Protection > Conditional Access > Named locations. a. Confirm you have a location called All Compliant Network locationswith location type Network Access. Organizations can optionally mark this location as trusted. You can refer below link to know more about license requirements, prerequisites & limitations Protect your resources behind the compliant network The compliant network Conditional Access policy can be used to protect your Microsoft and third-party applications. A typical policy will have a 'Block' grant for all network locations except Compliant Network. The following example demonstrates the steps to configure this type of policy: Sign in to the Microsoft Entra admin center as at least a Conditional Access Administrator. Browse to Protection > Conditional Access. Select Create new policy. Give your policy a name. We recommend that organizations create a meaningful standard for the names of their policies. Under Assignments, select Users or workload identities. Under Include, select All users. Under Exclude, select Users and groupsand choose your organization's emergency access or break-glass accounts. 6. Under Target resources > Include and select All resources (formerly 'All cloud apps'). If your organization is enrolling devices into Microsoft Intune, it is recommended to exclude the applications Microsoft Intune Enrollmentand Microsoft Intune from your Conditional Access policy to avoid a circular dependency. 7. Under Network. Set Configureto Yes. Under Include, select Any location. Under Exclude, select the All Compliant Network locationslocation. 8. Under Access controls: Grant, select Block Access, and select Select. 9. Confirm your settings and set Enable policy to On. 10. Select the Create button to create to enable your policy. User exclusions Conditional Access policies are powerful tools, we recommend excluding the following accounts from your policies: Emergency access or break-glass accounts to prevent lockout due to policy misconfiguration. In the unlikely scenario all administrators are locked out, your emergency-access administrative account can be used to log in and take steps to recover access. More information can be found in the article, Manage emergency access accounts in Microsoft Entra ID. Service accounts and Service principals, such as the Microsoft Entra Connect Sync Account. Service accounts are non-interactive accounts that aren't tied to any particular user. They're normally used by back-end services allowing programmatic access to applications but are also used to sign in to systems for administrative purposes. Calls made by service principals won't be blocked by Conditional Access policies scoped to users. Use Conditional Access for workload identities to define policies targeting service principals. If your organization has these accounts in use in scripts or code, consider replacing them with managed identities. Try your compliant network policy On an end-user device with the Global Secure Access client installed and running, browse to https://outlook.office.com/mail/ or https://yourcompanyname.sharepoint.com/, you have access to resources. Pause the Global Secure Access client by right-clicking the application in the Windows tray and selecting Pause. Browse to https://outlook.office.com/mail/ or https://yourcompanyname.sharepoint.com/, you're blocked from accessing resources with an error message that says You cannot access this right now. You can refer below link to know more about license requirements, prerequisites & limitations Enable compliant network check with Conditional Access - Global Secure Access | Microsoft LearnBest Practices for Investigating Phishing Incidents in Microsoft Defender for Office 365
Discover best practices for investigating phishing incidents with Microsoft Defender for Office 365. Learn how to use the Incidents tab, analyze threats, and accelerate response with Security Copilot’s AI-powered guidance.How to easily apply DISA STIGs with Intune
Introduction In today's digital landscape, ensuring the security and compliance of IT infrastructure is paramount. The Defense Information Systems Agency (DISA) provides Security Technical Implementation Guides (STIGs) to optimize security for various software and systems. Utilizing Microsoft Intune, administrators can create configuration profiles that adhere to these STIGs, thereby enhancing their organization's security posture. This blog will walk you through the process of creating Intune Configuration Profiles for DISA STIGs, complete with screenshots and detailed steps. Prerequisites Before diving into the configuration process, ensure you have the following: Access to the Intune admin center. Appropriate administrative privileges to create and manage configuration profiles. Familiarity with DISA STIGs and their requirements. Step-by-Step Guide Step 1: Access Intune Acquire DISA STIG Files: The first step in this process is to acquire the DISA STIG files from their official website (Group Policy Objects – DoD Cyber Exchange). These files contain the specific security guidelines and requirements you need to implement. Visit the DISA website, locate the relevant STIG files for your systems, and download them to your local machine. Prep files: Unzip the file you just downloaded then inside you should find another zipped file named like “Intune STIG Policy Baselines.” Unzip this file as well. Login to Intune with proper permissions: To begin, navigate to the Intune admin center at https://intune.microsoft.com or https://Intune.microsoft.us for Intune Government GCC-H/DoD (I am using a GCC-H instance of Intune, but these steps should be the same no matter what impact level you are using). Sign in with your administrator credentials: If you are using RBAC and least privilege you will need to have at least the “Policy and Profile Manager” role. Step 2: Create a New Configuration Profile Once logged in, follow these steps to create a new configuration profile: In the left-hand menu, select Devices -> Configuration profiles. Click on the Create profile button at the top, select “import policy” Select “Browse for files” and browse to the location where you unzipped the Intune STIG Policy Baselines, inside that folder go to the Intune Policies folder then Settings Catalog. Select your STIG of choice and provide a meaningful name and description for the profile and select save. Step 3: Configure Profile Settings Next, verify the profile settings align with the DISA STIG requirements: Once the profile has been created select view policy. Navigate through the settings and ensure every setting is meticulously configured to meet the STIG compliance guidelines. This may include settings such as password policies, encryption, and network security configurations. Ensure every setting meets the compliance standards of your organization. For example, Windows Spotlight is a feature that rotates the wallpaper and screensaver randomly if your organization uses custom wallpaper or screensavers you may want to have this completely disabled. Step 4: Assign the Profile and TEST, TEST, and TEST Again!! After configuring the profile settings, assign the profile to the appropriate groups: Next to Assignments select edit. Select the user or device groups that the profile should apply to, this should be a small but diverse group of devices or users that can provide feedback on the user experience of the settings being applied and or issues they cause because STIGS never break anything right!? Once you have assigned your groups click Review & Save then Save. Conclusion Creating Intune Configuration Profiles for DISA STIGs is a crucial step in maintaining robust security and compliance within your organization. By following this step-by-step guide, you can effectively configure and deploy profiles that adhere to stringent security standards, safeguarding your IT infrastructure. Stay vigilant and periodically review your profiles to ensure they remain compliant with evolving STIG requirements. Disclaimer While DISA has made this a fairly easy process with Microsoft Intune there are some caveats. In the folder where we found the Intune policies is a “Support files” folder which hold an excel spreadsheet with valuable information. There are still several STIG settings that are not natively set by Intune for various reasons (Not in Windows CSP, organization specific settings, etc.) They have also provided the Desired State Configuration (DSC) files to set a lot of these settings that will need to be deployed as a Win32_APP. This is outside the scope of this blog but stay tuned! Lastly, the spreadsheet provides STIG settings that will be a false positive when you use the Security Content Automation Protocol (SCAP) tool. This is due to the settings being set now through the Configuration Service Providers (CSP) and the tool is looking at the legacy registry locations. Unfortunately, until that tool gets updated to look in the new locations we will need to provide that to prove the settings have been configured. All screenshots and folder paths are from a non-production lab environment and can/will vary per environment. All processes and directions are of my own opinion and not of Microsoft and are from my years of experience with the Intune product in multiple customer environments Additional Resources Microsoft Intune Documentation: Microsoft Intune documentation | Microsoft Learn DISA STIGs: Security Technical Implementation Guides (STIGs) – DoD Cyber Exchange Intune Admin Center: intune.microsoft.com (Commercial/GCC) or Intune.microsoft.us for government (GCC-High/DoD) Stay tuned for future posts where we delve deeper into advanced configurations and best practices. Happy securing!