Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

AKSGuard

AKSGuard is a read-only, CLI-first PowerShell assessment tool for Azure Kubernetes Service. It collects Azure management-plane evidence, correlates Microsoft Defender for Cloud and Azure Advisor security recommendations, validates Defender for Containers configuration, and performs direct Kubernetes data-plane checks when connectivity and read-only permissions are available.

Assessment scope

AKSGuard currently evaluates:

  • Defender for Containers subscription pricing
  • AKS Defender security-monitoring profile configuration
  • Agentless discovery for Kubernetes
  • Agentless container vulnerability assessment
  • Azure Policy add-on configuration
  • Microsoft.Security assessments associated with the exact AKS resource
  • Azure Advisor security recommendations associated with the exact AKS resource
  • Cross-source recommendation correlation and provenance
  • Defender-related DaemonSet readiness
  • Kubernetes pod and node visibility for sensor coverage checks
  • Azure Policy and Gatekeeper deployment readiness

AKSGuard keeps successful evidence collection separate from security posture. A successful query does not mean that the target passed the assessed control.

Repository structure

AKSGuard/
|-- Invoke-AKSGuard.ps1
|-- Modules/
|   |-- Test-AKSDefenderForContainers.ps1
|   `-- Test-AKSKubernetesPostureManagement.ps1
|-- .gitignore
`-- README.md

Prerequisites

PowerShell

One of the following:

  • Windows PowerShell 5.1
  • PowerShell 7 or later

Verify:

$PSVersionTable.PSVersion

Azure CLI

Install Azure CLI on Windows with WinGet:

winget install --exact --id Microsoft.AzureCLI `
    --accept-package-agreements `
    --accept-source-agreements

Close and reopen PowerShell, then verify:

az version

Azure Resource Graph extension

AKSGuard uses az graph query to collect management-plane recommendations.

az extension add --name resource-graph --upgrade

az extension show `
    --name resource-graph `
    --query '{Name:name,Version:version}' `
    --output table

kubectl

kubectl is required for direct Kubernetes data-plane validation. It is not required when using -SkipKubernetesDataPlane.

winget install --exact --id Kubernetes.kubectl `
    --accept-package-agreements `
    --accept-source-agreements

Close and reopen PowerShell, then verify:

kubectl version --client

kubelogin

Microsoft Entra-integrated AKS clusters commonly require kubelogin for user authentication.

winget install --exact --id Microsoft.Azure.Kubelogin `
    --accept-package-agreements `
    --accept-source-agreements

Close and reopen PowerShell, then verify:

kubelogin --version

Optional Git client

Git is optional when AKSGuard is downloaded as an archive. Install it when cloning or updating the repository in place:

winget install --exact --id Git.Git `
    --accept-package-agreements `
    --accept-source-agreements

Access requirements

AKSGuard reuses the active Azure CLI identity and does not request Microsoft Graph permissions.

Management-plane collection requires permission to read:

  • The target AKS resource
  • Microsoft Defender for Cloud pricing configuration
  • Microsoft.Security assessments
  • Azure Advisor security recommendations

Direct Kubernetes validation requires:

  • Network and DNS connectivity to the Kubernetes API endpoint
  • A user kubeconfig for the target cluster
  • Microsoft Entra authentication where configured
  • Read permission for nodes, pods, DaemonSets, and deployments

Private AKS clusters require a working private network route and private DNS resolution from the machine running AKSGuard. Retrieving credentials with az aks get-credentials does not prove that the private Kubernetes API is reachable.

Prepare Azure and Kubernetes access

Authenticate and select the target subscription:

az login
az account set --subscription '<subscription-id>'

Retrieve normal user credentials for the cluster:

az aks get-credentials `
    --subscription '<subscription-id>' `
    --resource-group '<resource-group>' `
    --name '<cluster-name>'

Do not use --admin for a normal read-only assessment.

Validate the current context, connectivity, and effective permissions:

$KubeContext = kubectl config current-context

kubectl --context $KubeContext cluster-info --request-timeout=15s
kubectl --context $KubeContext auth can-i get nodes
kubectl --context $KubeContext auth can-i list pods --all-namespaces
kubectl --context $KubeContext auth can-i list daemonsets --all-namespaces
kubectl --context $KubeContext auth can-i list deployments --all-namespaces

Usage

Full assessment

.\Invoke-AKSGuard.ps1 `
    -SubscriptionId '<subscription-id>' `
    -ResourceGroupName '<resource-group>' `
    -ClusterName '<cluster-name>'

Use a specific Kubernetes context

.\Invoke-AKSGuard.ps1 `
    -SubscriptionId '<subscription-id>' `
    -ResourceGroupName '<resource-group>' `
    -ClusterName '<cluster-name>' `
    -KubeContext '<kubernetes-context>'

Azure management-plane assessment only

Use this mode when direct Kubernetes API connectivity or Kubernetes read access is unavailable:

.\Invoke-AKSGuard.ps1 `
    -SubscriptionId '<subscription-id>' `
    -ResourceGroupName '<resource-group>' `
    -ClusterName '<cluster-name>' `
    -SkipKubernetesDataPlane

Skipped data-plane controls are reported as inconclusive. They are not reported as healthy.

Output

Each run creates a timestamped directory under AKSGuard-Results:

AKSGuard-Results/<cluster>-<timestamp>/
|-- Evidence/
|-- Logs/
`-- Report/
    |-- index.html
    |-- defender-for-containers.html
    |-- kubernetes-posture.html
    |-- findings.csv
    `-- summary.json

The HTML report is offline and does not require a web server or internet-hosted JavaScript.

Raw evidence remains separated by source. The report correlates matching Microsoft.Security and Azure Advisor observations into unique recommendations while preserving source provenance.

Interpretation

AKSGuard uses conservative evidence labels:

  • Confirmed healthy
  • Confirmed enabled
  • Confirmed issue
  • Likely issue
  • Inconclusive
  • Not detected
  • Access denied
  • Failed

Important distinctions:

  • Not detected does not mean confirmed absent.
  • An enabled subscription plan does not prove that runtime sensors are deployed and healthy.
  • A successful Azure Resource Graph query does not prove that no recommendations exist.
  • A management-plane recommendation is evidence requiring validation, not automatic proof of exploitability.
  • Missing network access or permissions are reported as coverage limitations.

Safety

AKSGuard is designed for read-only assessment.

The scripts do not:

  • Modify Azure resources
  • Modify Kubernetes resources
  • Request AKS administrative credentials
  • Retrieve Kubernetes Secrets
  • Retrieve service-account token contents
  • Retrieve registry credentials
  • Export kubeconfig contents

Review the scripts and use an appropriately scoped audit identity before running them in any environment.

Troubleshooting

az is not recognized

Close and reopen PowerShell after installing Azure CLI, then run:

az version

az graph is unavailable

az extension add --name resource-graph --upgrade

az aks install-cli reports an SSL certificate verification failure

A TLS-inspecting corporate proxy can be trusted by Windows while remaining untrusted by the Python certificate bundle used by Azure CLI. Do not disable TLS verification. Install kubectl and kubelogin through WinGet, or have the infrastructure team provide the authoritative corporate CA bundle for Azure CLI.

kubectl or kubelogin is not recognized

Close and reopen PowerShell after installation, then verify:

Get-Command kubectl, kubelogin |
    Select-Object Name, Source

Private AKS hostname does not resolve

Errors such as no such host, DNS name does not exist, or NXDOMAIN indicate a DNS or private-network integration problem before Kubernetes authentication and RBAC are evaluated.

$Context = kubectl config current-context
$Server = kubectl config view `
    --context $Context `
    --minify `
    --output 'jsonpath={.clusters[0].cluster.server}'
$HostName = ([uri]$Server).Host

Resolve-DnsName -Name $HostName -Type A
Test-NetConnection -ComputerName $HostName -Port 443

Validate the client VNet, private DNS zone association, custom DNS forwarding, and network route to the private endpoint.

Forbidden or kubectl auth can-i returns no

Network connectivity and authentication may be working, but the identity lacks the required Kubernetes read permission. Request only the minimum missing read access.

About

Read-only, evidence-driven security assessment and validation tooling for Azure Kubernetes Service.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages