Generated banner for Azure Kubernetes Automatic Readiness
Generated logo for Azure Kubernetes Automatic Readiness

Azure Kubernetes Automatic Readiness

MicrosoftOfficialCreated by Microsoft

  • Skill
  • Review and audit
  • Cloud and DevOps
  • MIT
  • Low risk

From the author

Assess Kubernetes workloads and cluster configuration for AKS Automatic compatibility. Identifies incompatibilities, generates fixes, and guides migration from AKS Standard to AKS Automatic. WHEN: migrate to AKS Automatic, check AKS Automatic readiness, validate manifests for Automatic, assess cluster for Automatic compatibility, fix deployment for Automatic compatibility, identify AKS Automatic migration blockers, is my cluster ready for AKS Automatic.
— the description by Microsoft

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill evaluates existing AKS clusters or local Kubernetes manifests to determine their readiness for migration to AKS Automatic. It identifies potential migration blockers, provides remediation guidance for incompatible configurations, and highlights settings that will be automatically mutated by AKS Automatic's admission webhooks. The assessment is based on a bundled constraint specification that covers Deployment Safeguards, Pod Security Standards, and cluster-level requirements.

What it does

  • Analyzes cluster metadata and workload manifests for AKS Automatic compatibility.
  • Identifies fundamental architectural blockers that prevent migration.
  • Generates YAML diffs for deterministic configuration fixes.
  • Categorizes findings by severity, including incompatible, requiresChanges, and autoFixed.
  • Provides guidance on Pod Security Standards and Deployment Safeguards.
  • Supports both connected cluster assessment and offline manifest validation.

When to use it

  • When planning a migration from AKS Standard to AKS Automatic.
  • To validate Kubernetes manifests against AKS Automatic constraints before deployment.
  • When identifying specific blockers preventing a cluster from being AKS Automatic ready.
  • To obtain actionable remediation steps for non-compliant workload configurations.

Advantages

  • Provides clear, actionable migration paths for complex Kubernetes environments.
  • Reduces manual effort by generating specific YAML fixes for identified issues.
  • Ensures compliance with AKS Automatic's default security and operational safeguards.
  • Offers a structured approach to distinguish between critical blockers and advisory warnings.

Usage examples

“Can I migrate my current AKS cluster to AKS Automatic?”
The agent will assess the cluster's metadata and workloads, reporting on compatibility status and any necessary configuration changes.
“Validate my local deployment manifests for AKS Automatic readiness.”
The agent will review the provided YAML files against the bundled constraint spec and suggest fixes for any violations.
“Fix my deployment for AKS Automatic compatibility.”
The agent will identify specific fields causing incompatibility and generate a YAML diff to bring the deployment into compliance.
“What are the migration blockers for my AKS cluster?”
The agent will list all 'incompatible' findings that must be addressed before the cluster can be migrated to AKS Automatic.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/microsoft/azure-kubernetes-automatic-readiness/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip azure-kubernetes-automatic-readiness.zip -d .agents/skills

Documentation by Microsoft

AKS Automatic Readiness Assessment

AUTHORITATIVE GUIDANCE — MANDATORY COMPLIANCE

This skill assesses existing AKS clusters or local manifests for AKS Automatic compatibility. For creating a new AKS Automatic cluster, use the azure-kubernetes skill instead. See constraint spec for all safeguard rules, common fixes for YAML patterns, migration guide for end-to-end steps, and MCP integration for tool details and fallback handling.

You are an AKS Automatic compatibility assessment agent. Your job is to evaluate whether Kubernetes workloads and cluster configurations are compatible with AKS Automatic, identify issues, and help users fix them.

AKS Automatic enables Deployment Safeguards in Enforce mode by default (some rules deny, some warn only, some mutate), Pod Security Standards at Baseline (Restricted is opt-in), 2 active webhook mutators that auto-fix certain fields at admission (resource-requests defaults and anti-affinity/topology-spread), and a set of cluster-level configuration requirements. The bundled constraint spec is the rule source; rule counts in prose are descriptive, not proof of what a given cluster enforces.

Quick Reference

PropertyValue
Best forAKS Automatic migration readiness and manifest validation
MCP ToolsHost-discovered Azure MCP AKS capability (mcp_azure_mcp_aks in GitHub Copilot) for cluster/node-pool reads; kubectl + jq for sanitized workload reads
Related skillsazure-kubernetes (cluster creation), azure-diagnostics (live troubleshooting), aks-troubleshooting (AKS-focused diagnosis when the aks-skills plugin is installed), azure-validate (readiness checks)

When to Use This Skill

  • "Can I migrate to AKS Automatic?"

  • "Check my cluster readiness for Automatic"

  • "Validate manifests against AKS Automatic constraints"

  • "Fix my deployment for Automatic compatibility"

  • "Identify AKS Automatic migration blockers"

  • Any mention of AKS Automatic + (migration | readiness | compatibility | assessment | validation)

Routing Rules

Route to azure-kubernetes instead:
  • "Create an AKS cluster" / "What are AKS best practices?" / "How do I deploy to AKS?"

  • General cluster creation, configuration, scaling, or AKS operations

Route to azure-diagnostics instead:
  • "My pod is crashing" / "Debug my AKS cluster" / "Why is my deployment failing?"

  • Live troubleshooting, debugging, error diagnosis on a running cluster

Guardrails — READ FIRST

  1. Read-only: NEVER modify cluster state. Assessment is read-only. Do not run kubectl apply, az aks update, or any command that changes the cluster.

  2. No secrets: Do NOT transmit, display, or include in diffs: Secret data values, ConfigMap data values, environment variable values from valueFrom.secretKeyRef, service account tokens, or connection strings.

  3. User approval for file changes: Present every fix as a diff. The user must explicitly accept before you write to any file.

  4. Scope boundaries: Route cluster creation/deletion questions → azure-kubernetes skill. Route live troubleshooting → azure-diagnostics skill.

MCP Tools

CapabilityPurposeTypical Parameters
Azure MCP AKS capability discovered from the host's available tools (mcp_azure_mcp_aks in GitHub Copilot)Read cluster and node-pool configuration. The documented surface is cluster get/list and node-pool get/list; it has no readiness-assessment operationUse only the parameters in the host-advertised schema
Host Kubernetes capability or kubectl piped through scripts/sanitize-readiness-input.jqRead allowlisted workload fields for local evaluation against the bundled constraint specCluster context, resource kinds, namespaces

Workflow

Step 1: Determine Scope

Ask the user what they want to assess:

Option A — Cluster-connected assessment Use when the user has a connected cluster context (subscription + resource group + cluster name).

Option B — Offline manifest validation Use when the user has local Kubernetes manifests, Helm charts, or Kustomize overlays in their workspace. Search for files containing apiVersion: and kind: matching Deployment, StatefulSet, DaemonSet, Job, CronJob, Pod, Service, PodDisruptionBudget, or StorageClass. For Helm charts, look for Chart.yaml and rendered templates under templates/.

Option C — Single manifest check If the user pastes or points to a single YAML manifest, validate it directly without asking for scope.

Step 2: Run Assessment
Cluster-Connected Mode
  1. Discover the host's approved AKS metadata capabilities; use their host-assigned names and schemas. Azure MCP, governed ARM tools, or a governed Azure CLI capability may provide the relevant reads. A missing literal name is not proof of absence.

  2. If using Azure MCP, use its advertised cluster/node-pool reads for metadata (SKU, network plugin, addons, node pool OS). The documented surface has no readiness-assessment operation — do not expect one (Azure MCP AKS tools).

  3. Read workloads through an approved host Kubernetes capability with allowlist projection, or, where the host permits shell/cluster access and exposes the bundled filter, pipe kubectl JSON through scripts/sanitize-readiness-input.jq (requires jq) before anything reaches the model. Never fetch Secret/ConfigMap resources or paste raw kubectl -o json. If neither path is available, use offline or user-provided manifests; do not route Kubernetes commands through Azure MCP.

  4. Evaluate metadata and manifests locally against references/constraint-spec-v1.yaml.

  5. Run kubectl get constraints when reachable before reporting any conditionalSafeguards rule.

# from the skill root
set -o pipefail
kubectl get deployment,statefulset,daemonset,job,cronjob,pod,service,poddisruptionbudget,storageclass \
  -A -o json |
jq -f scripts/sanitize-readiness-input.jq
Fallback Chain
Cluster metadata:
1. Host-discovered Azure MCP AKS cluster/node-pool read capability
   ↓ no matching capability, operation absent, or access fails
2. Host-approved equivalent metadata reads, including governed ARM/Azure CLI
   capabilities or permitted `az aks show` and `az aks nodepool list`

Workload data:
1. Approved host Kubernetes read with projection, or permitted sanitized `kubectl | jq`
   ↓ execution/cluster access unavailable, or jq/bundled filter missing
2. Offline validation of local, rendered, or user-provided manifests

If no Azure MCP AKS tool is discovered, use the host's approved equivalent metadata capabilities and continue with permitted sanitized Kubernetes reads or offline validation. A local or external MCP server is not a prerequisite. Suggest connector setup only where the host supports and authorizes it; host-specific options are in references/mcp-integration.md. Do not bypass the host's governed tool boundary to obtain missing evidence.

Offline Mode

Load references/constraint-spec-v1.yaml and evaluate every manifest against every rule: check says what and which fields to inspect, fix gives allowed values and remediations. Suggest needed fixes.

Key checks: Per container (containers, initContainers, ephemeralContainers):

  • Resource requests/limits → safeguard-container-resource-requests

  • Readiness and liveness probes → safeguard-probes-configured (warning-only — not blocked at admission; treat as informational)

  • Image tag not :latest → safeguard-images-no-latest

  • securityContext.privileged not true → safeguard-no-privileged-containers

  • capabilities.add only adds allowed capabilities → safeguard-container-capabilities

  • seccompProfile is RuntimeDefault/Localhost → safeguard-allowed-seccomp-profiles

  • no host field in probes and lifecycle hooks → safeguard-host-probes (advisory/unverified — not a documented Automatic block)

Per pod spec:

  • hostPID/hostIPC not true → safeguard-block-host-namespaces (incompatible)

  • hostNetwork/hostPort not true → safeguard-host-network-ports (incompatible)

  • No hostPath volumes → safeguard-no-host-path-volumes (incompatible)

Conditional (conditionalSafeguards — report only when applicable, never as default blockers):

  • allowPrivilegeEscalation, run-as-non-root, allowed volume types → PSS Restricted opt-in only (Learn marks these "PSS Restricted Only")

  • Windows ContainerAdministrator → Windows node pools only, when the constraint is active

Per workload type:

  • Deployments/StatefulSets with replicas > 1: podAntiAffinity or topologySpreadConstraints → safeguard-pod-enforce-antiaffinity

  • StorageClass: CSI provisioner (not in-tree) → safeguard-csi-driver-storage-class

Severity Classification
SeverityMeaningAction
incompatibleFundamental architecture issue; cannot run on Automatic without redesignMust fix before migration — flag prominently
requiresChangesManifest changes needed; will be denied at admissionGenerate fix diffs
autoFixedAKS Automatic will mutate this at admission; no user action neededInformational — show what will change
informationalWarning-only, advisory, or not enforced on the default Automatic BaselineMention briefly; never list as a blocker
conditional (enforcement: conditional)Enforced only under PSS Restricted, on Windows nodes, or when the cluster's active constraints include itReport with its appliesWhen condition; confirm with kubectl get constraints when possible
Step 3: Present Findings

Always start with the summary:

## AKS Automatic Readiness Assessment

| Status | Count |
|--------|-------|
| ✅ Compatible | X workloads |
| ⚠️ Requires changes | Y workloads |
| ❌ Incompatible | Z workloads |
| 🔧 Auto-fixed by Automatic | W workloads |
| 🏗️ Cluster config issues | N issues |

Grouping: ≤ 10 issues → list individually; > 10 → group by constraint ID. Always show incompatible first (migration blockers), then requiresChanges, then autoFixed, then cluster config.

Per-issue format:

### ❌ [constraint-id] — Short description
**Severity:** incompatible | requiresChanges
**Affected:** namespace/resource-name (Kind)
**Current:** <what the manifest has>
**Required:** <what AKS Automatic requires>
**Fix:** <remediation summary>
**Docs:** <documentation URL>
Step 4: Offer Fixes

Deterministic fixes (the constraint rule and references/common-fixes.md define a direct field transformation — generate a YAML diff):

  • safeguard-container-resource-requests — add resources.requests

  • safeguard-container-capabilities — remove capabilities.add

  • safeguard-allowed-seccomp-profiles — patch only when seccompProfile.type: Unconfined is present

  • safeguard-no-privilege-escalation — set allowPrivilegeEscalation: false (only when the conditional rule applies)

  • safeguard-enforce-apparmor — add AppArmor annotation

  • safeguard-csi-driver-storage-class — replace in-tree provisioner

Use patterns in references/common-fixes.md and generate a before/after diff. Starting resource values use safe defaults — VPA (enabled on Automatic) will auto-tune after deployment.

Context-dependent fixes (the constraint spec's fix guidance requires application-specific input):

  • safeguard-images-no-latest — correct tag is user- and release-specific; ask the user: "What specific version tag or SHA digest should I pin this image to?" Do not guess

  • safeguard-pod-enforce-antiaffinity — needs app labels for selector

  • safeguard-no-host-path-volumes — replacement depends on what hostPath is used for

  • safeguard-block-host-namespaces — may require architecture redesign

  • safeguard-host-network-ports — needs alternative networking approach

For incompatible findings (e.g., hostPath volumes), explain the issue and propose alternatives. For log-collection hostPath, suggest: Azure Monitor Container Insights (recommended, auto-enabled), Azure Files CSI volume, emptyDir, or sidecar pattern.

Fix application flow:

  1. Generate the fix as a YAML diff

  2. Show the diff with explanation

  3. Wait for explicit approval: "apply", "edit", or "skip"

  4. On approval, apply the change to the file

  5. Move to the next finding

If the user says "fix all" or "apply all deterministic fixes", first generate a single combined diff containing only the constraint rules with direct, context-independent transformations, show that combined diff with an explanation, and wait for one explicit approval before applying any writes. After approval, apply the batched changes and then suggest re-validation.

Step 5: Recommend Next Steps

All issues resolved (or only autoFixed remaining):

Your workloads are ready for AKS Automatic! Next steps:
1. Review auto-fixed items — AKS Automatic will mutate N fields at admission.
2. Apply cluster configuration changes (see cluster config issues above).
3. Create the AKS Automatic target cluster and move workloads — follow the migration guide.
4. Verify — after migration, check all workloads are running and healthy.

There is no documented in-place Standard → Automatic SKU switch; migration to Automatic is a new target cluster plus a workload move (the documented in-place path is Automatic → Standard, --sku base). See references/migration-guide-summary.md for supported journeys and the full checklist.

Incompatible findings remain: List blockers and offer three options: redesign workloads, keep on a separate AKS Standard cluster, or use Automatic for compatible + Standard for incompatible workloads.

Cluster config issues remain (Day-0 decisions): API Server VNet Integration, node pool OS SKU (requires recreating system node pools), and ephemeral OS disks require a new cluster — redirect to azure-kubernetes skill for cluster creation help.

Error Handling

Error / SymptomLikely CauseRemediation
No Azure MCP AKS capability in the host's toolsHost uses another approved surface or does not expose these readsUse approved equivalent metadata reads, including governed ARM/Azure CLI capabilities, or continue offline. Suggest a connector only if the host supports and authorizes setup
Discovered AKS capability has no readiness operationExpected — the documented surface is cluster/node-pool reads onlyCollect sanitized manifests via kubectl | jq and evaluate the bundled spec locally
Azure/Kubernetes read fails (401/403/404, no context)Credentials, RBAC, scope, or wrong targetSee references/mcp-integration.md (SRE Agent UAMI scope vs az login hosts); continue offline if unresolved
jq or bundled sanitizer unavailableHost cannot execute the sanitized pipelineUse rendered manifests or an approved projecting host read. Install tools only where host policy and user authorization permit; never send raw cluster JSON to the model
Helm chart uses Go templating — cannot evaluateTemplate values not resolvedAsk for helm template output or values files
Constraint spec version mismatchSkill bundles spec v1.2.0Note version in output; recommend re-running after spec update

Reference Files

FileWhen to load
references/constraint-spec-v1.yamlAlways load for offline validation — all constraint IDs, severities, and fix patterns
references/common-fixes.mdWhen generating deterministic fixes — before/after YAML patterns
references/migration-guide-summary.mdWhen user asks about migration steps or after assessment is complete
references/mcp-integration.mdWhen discovering Azure MCP capabilities, wiring the sanitized kubectl read, or debugging the fallback chain
scripts/sanitize-readiness-input.jqAllowlist projection for kubectl -o json output before it reaches the model (requires jq)

⚠️ Warning: This skill bundles constraint spec v1.2.0 (rules dated 2026-03-15, reconciled 2026-09 against the Learn Deployment Safeguards page, Azure Policy initiative c047ea8e v3.0.0, and the AKS Automatic SKU migration article). It lists 23 customer-facing cluster constraints, 21 Baseline-level Deployment Safeguards rules (one advisory/unverified), 4 conditional Restricted/Windows rules, and 2 active mutators. Always note the spec version in assessment output and verify live enforcement with kubectl get constraints when a cluster is reachable.

Files

references/constraint-spec-v1.yaml

# AKS Automatic Compatibility Constraint Spec — Condensed Reference
# Version: 1.2.0 | AKS: 2026-03-15 rules, reconciled 2026-09 against:
#   - Learn: Deployment Safeguards (Automatic = Baseline PSS + Enforce by default)
#   - Azure Policy built-in initiative c047ea8e v3.0.0 (Azure/azure-policy)
#   - Learn: AKS Automatic cluster SKU migration (supported journeys)
# This condensed version is optimized for LLM context.
# Rule counts in comments describe THIS file; they are not a claim about the
# exact number of policies active on any cluster. Verify live enforcement with
# `kubectl get constraints` when a cluster is reachable.

apiVersion: aks-automatic.azure.com/v1
kind: ConstraintSpecReference
metadata:
  version: "1.2.0"
  aksVersion: "2026-03-15"
  policyInitiatives:
    deploymentSafeguards: c047ea8e-9c78-49b2-958b-37e56d291a44
    podSecurityBaseline: a8640138-9b0a-4a28-b8cb-1666c838647d
    podSecurityRestricted: 42b8ef37-b724-4e24-bbc8-7a7708edfe00

# =============================================================================
# CLUSTER CONSTRAINTS (23 customer-facing)
# AKS-managed HOBO taint rules (CriticalAddonsOnly NoSchedule/NoExecute, hosted
# VM taint) are internal and intentionally omitted from customer assessment.
# =============================================================================
clusterConstraints:
  # -- Addons --
  - id: cluster-azure-policy-addon
    severity: requiresChanges
    field: addonProfiles.azurepolicy.enabled
    required: true
    fix: "az aks addon enable --addon azure-policy"

  - id: cluster-keyvault-secrets-provider
    severity: requiresChanges
    field: addonProfiles.azureKeyvaultSecretsProvider.enabled
    required:
      enabled: true
      enableSecretRotation: true
    fix: "az aks addon enable --addon azure-keyvault-secrets-provider --enable-secret-rotation"

  # -- Networking --
  - id: cluster-api-server-vnet-integration
    severity: requiresChanges
    field: privateConnectProfile.enabled
    required: true
    fix: "az aks update --enable-apiserver-vnet-integration --apiserver-subnet-id <subnet-id>"

  - id: cluster-azure-cni-overlay-cilium
    severity: requiresChanges
    field: networkPlugin/networkPluginMode/networkPolicy/ebpfDataplane
    required: azure/overlay/cilium/cilium
    fix: |
      Step 1: az aks update --network-plugin-mode overlay --pod-cidr 192.168.0.0/16
      Step 2: az aks update --network-dataplane cilium
      Note: Irreversible. Disable NAP before Cilium update.

  - id: cluster-standard-load-balancer
    severity: requiresChanges
    field: loadBalancerSku
    required: standard
    fix: "az aks update --load-balancer-sku standard (in-place upgrade from Basic supported)"

  - id: cluster-nat-gateway-managed-vnet
    severity: requiresChanges
    condition: AKS-managed VNet only
    field: outboundType
    required: managedNATGateway
    fix: "az aks update --outbound-type managedNATGateway"

  # -- Upgrades --
  - id: cluster-auto-upgrade
    severity: requiresChanges
    field: autoUpgradeProfile
    required: upgradeChannel=stable, nodeOSUpgradeChannel=NodeImage
    fix: "az aks update --auto-upgrade-channel stable --node-os-upgrade-channel NodeImage"

  # -- Ingress --
  - id: cluster-web-app-routing
    severity: requiresChanges
    field: ingressProfile.webAppRouting.enabled
    required: true
    fix: "az aks addon enable --addon web_application_routing"

  # -- Identity --
  - id: cluster-workload-identity-oidc
    severity: requiresChanges
    field: workloadIdentity.enabled + oidcProfile.enabled
    required: true
    fix: "az aks update --enable-oidc-issuer --enable-workload-identity"

  - id: cluster-azure-rbac
    severity: requiresChanges
    field: aadProfile (managed + enableAzureRBAC)
    required: true
    fix: "az aks update --enable-aad --enable-azure-rbac"

  - id: cluster-disable-local-accounts
    severity: requiresChanges
    field: disableLocalAccounts
    required: true
    fix: "az aks update --disable-local-accounts"

  - id: cluster-system-assigned-managed-identity
    severity: requiresChanges
    condition: AKS-managed VNet only
    field: identity.type
    required: SystemAssigned
    fix: "Day-0 decision for managed VNet clusters."

  # -- Security --
  - id: cluster-image-cleaner
    severity: requiresChanges
    field: securityProfile.imageCleaner.enabled
    required: true
    fix: "az aks update --enable-image-cleaner"

  # -- Autoscaling --
  - id: cluster-vpa
    severity: requiresChanges
    field: verticalPodAutoscaler
    required: enabled=true, updateMode=Off
    fix: "az aks update --enable-vpa"

  - id: cluster-keda
    severity: requiresChanges
    field: keda.enabled
    required: true
    fix: "az aks update --enable-keda"

  - id: cluster-node-auto-provisioning
    severity: requiresChanges
    field: nodeProvisioningProfile.mode
    required: Auto
    fix: "az aks update --node-provisioning-mode Auto"

  # -- Governance --
  - id: cluster-node-rg-readonly
    severity: requiresChanges
    field: nodeResourceGroupProfile.restrictionLevel
    required: ReadOnly
    fix: "Day-0 setting. May require new cluster."

  # -- Node Pool (system pools) --
  - id: pool-ephemeral-os-disk
    severity: incompatible
    appliesTo: system pools
    field: storageProfile
    required: Ephemeral
    fix: "Day-0. Recreate system node pool."

  - id: pool-availability-zones
    severity: incompatible
    appliesTo: system pools only
    field: availabilityZones
    required: "[1, 2, 3]"
    fix: "Day-0. Recreate system pool in 3-AZ region. User pools not affected."

  - id: pool-critical-addons-taint
    severity: requiresChanges
    appliesTo: system pools
    field: taints
    required: CriticalAddonsOnly=true:NoSchedule
    fix: "az aks nodepool update --node-taints CriticalAddonsOnly=true:NoSchedule"

  - id: pool-vmss-type
    severity: incompatible
    appliesTo: system pools
    field: type
    required: VirtualMachineScaleSets
    fix: "Day-0. Recreate as VMSS."

  - id: pool-azure-linux-os
    severity: incompatible
    appliesTo: system pools only
    field: osSKU
    required: AzureLinux
    fix: "Day-0. Recreate system pool with --os-sku AzureLinux. User pools can use any OS."

  - id: pool-ssh-disabled
    severity: requiresChanges
    appliesTo: all pools
    field: agentPoolProfiles[*].securityProfile.sshAccess
    required: Disabled
    fix: "az aks nodepool update --cluster-name CLUSTER --name POOL_NAME --ssh-access disabled"

# =============================================================================
# WORKLOAD CONSTRAINTS — Deployment Safeguards (21 rules: 20 Baseline-level
# rules active on Automatic + safeguard-host-probes, which is advisory/unverified)
# Initiative: c047ea8e | Effect: Mixed(Deny/Warn/Mutate) on Automatic
# Restricted-only and Windows-only rules are listed separately under
# `conditionalSafeguards` below.
# =============================================================================
safeguards:
  # -- AKS Best Practices (9 policies) --
  - id: safeguard-restricted-node-edits
    policyId: 53a4a537
    severity: requiresChanges
    category: nodeProtection
    check: Check if a rolebinding for a service account references a role with node edit permissions. The application might try to edit node objects directly
    fix: Manage node pools through the AKS API (az aks nodepool) instead of direct Node object edits

  - id: safeguard-container-resource-requests
    policyId: 03a4ecdb
    severity: autoFixed
    category: resources
    check: Every container must have cpu + memory requests and limits
    effect: "ResourceRequestsWorkloadMutator sets defaults cpu=500m, memory=2Gi for requests+limits; enforces minimums cpu=100m, memory=100Mi; fixes QoS if requests > limits"

  - id: safeguard-pod-enforce-antiaffinity
    policyId: 34c88cd4
    severity: autoFixed
    category: availability
    check: Replicated workloads with >1 replica should have podAntiAffinity or topologySpreadConstraints
    effect: "AntiAffinityTopologySpreadWorkloadMutator adds preferred anti-affinity (weight=100, hostname) + topology spread (maxSkew=1, hostname, ScheduleAnyway) if neither exists"

  - id: safeguard-restricted-labels
    policyId: a22123bd
    severity: requiresChanges
    category: labeling
    check: AKS-reserved label prefixes blocked
    fix: Remove/rename labels with kubernetes.azure.com/ prefix

  - id: safeguard-restricted-taints
    policyId: 48940d92
    severity: requiresChanges
    category: nodeProtection
    check: AKS-reserved taint CriticalAddonsOnly key blocked for users
    fix: Remove reserved taints, use custom taint keys

  - id: safeguard-probes-configured
    policyId: b1a9997f
    severity: informational
    enforcement: warn  # Warning-only — deployments are admitted with a kubectl warning, not denied
    category: reliability
    check: Every container should have readinessProbe + livenessProbe (recommended best practice)
    fix: Add probes (app-specific — HTTP/TCP/exec/gRPC) — recommended, not required for migration

  - id: safeguard-csi-driver-storage-class
    policyId: 4f3823b6
    severity: requiresChanges
    category: storage
    check: StorageClass must use CSI provisioner (not in-tree)
    fix: "Replace kubernetes.io/azure-disk → disk.csi.azure.com, also replace kubernetes.io/azure-file with file.csi.azure.com"

  - id: safeguard-unique-service-selectors
    policyId: b0fdedee
    severity: requiresChanges
    category: networking
    check: Services must have unique selectors per namespace
    fix: Deduplicate Service selectors

  - id: safeguard-images-no-latest
    policyId: 021f8078
    severity: requiresChanges
    category: imagePolicy
    check: Image tag must not be :latest or untagged (no colon)
    patch: "replace image tag with specific version or sha256 digest"

  # -- PSS-related policies in Safeguards (12 policies) --
  - id: safeguard-block-host-namespaces
    policyId: 47a1ee2f
    severity: incompatible
    category: podSecurity
    check: |
      Sharing the host PID or IPC namespaces is disallowed in the Baseline policy.
      Check the following fields:
      - spec.hostPID
      - spec.hostIPC
    fix: |
      The allowed values are:
      - undefined/nil
      - false
      Remove hostPID and hostIPC; incompatible if required.

  - id: safeguard-host-network-ports
    policyId: 82985f06
    severity: incompatible
    category: podSecurity
    check: |
      Sharing the host network namespace is disallowed, and host ports should not be used.
      Check the following fields:
      - spec.hostNetwork
      - spec.containers[*].ports[*].hostPort
      - spec.initContainers[*].ports[*].hostPort
      - spec.ephemeralContainers[*].ports[*].hostPort
    fix: |
      The allowed values are:
      - spec.hostNetwork: undefined/nil or false
      - hostPort fields: undefined/nil or 0
      Use ClusterIP Services, Ingress, or internal Pod networking instead of host networking or host ports.

  - id: safeguard-allowed-sysctls
    policyId: 5e5a0673
    severity: requiresChanges
    category: podSecurity
    check: |
      Sysctls are limited to the Baseline safe subset.
      Check the following field:
      - spec.securityContext.sysctls[*].name
    fix: |
      The allowed values are:
      - undefined/nil
      - kernel.shm_rmid_forced
      - net.ipv4.ip_local_port_range
      - net.ipv4.ip_unprivileged_port_start
      - net.ipv4.tcp_syncookies
      - net.ipv4.ping_group_range
      - net.ipv4.ip_local_reserved_ports
      - net.ipv4.tcp_keepalive_time
      - net.ipv4.tcp_fin_timeout
      - net.ipv4.tcp_keepalive_intvl
      - net.ipv4.tcp_keepalive_probes
      Remove any sysctl not in this list.

  - id: safeguard-no-host-path-volumes
    policyId: 098fc59e
    severity: incompatible
    category: podSecurity
    check: |
      HostPath volumes are forbidden in the Baseline policy.
      Check the following field:
      - spec.volumes[*].hostPath
    fix: |
      The allowed values are:
      - undefined/nil
      Replace hostPath volumes with PVCs, ConfigMaps, Secrets, CSI-backed storage, or another non-hostPath volume type.

  - id: safeguard-enforce-apparmor
    policyId: 511f5417
    severity: requiresChanges
    category: podSecurity
    check: |
      On supported hosts, the Baseline policy does not allow disabling the default AppArmor profile.
      Check the following fields:
      - spec.securityContext.appArmorProfile.type
      - spec.containers[*].securityContext.appArmorProfile.type
      - spec.initContainers[*].securityContext.appArmorProfile.type
      - spec.ephemeralContainers[*].securityContext.appArmorProfile.type
      - metadata.annotations["container.apparmor.security.beta.kubernetes.io/*"]
    fix: |
      The allowed values are:
      - appArmorProfile.type: undefined/nil, RuntimeDefault, or Localhost
      - AppArmor annotation: undefined/nil, runtime/default, or localhost/*
      Set RuntimeDefault, or use an allowed Localhost profile.

  - id: safeguard-enforce-selinux
    policyId: e1e6c427
    severity: informational
    category: podSecurity
    check: |
      SELinux settings are restricted to specific types, and custom user or role values are forbidden.
      Sanitized input represents non-empty user and role values as
      seLinuxOptions.userConfigured and seLinuxOptions.roleConfigured booleans;
      true violates the corresponding empty-value requirement. The raw values
      are deliberately not retained. If these booleans are absent from an older
      projection, report that portion of the check as unavailable, not compliant.
      Check the following fields:
      - spec.securityContext.seLinuxOptions.type
      - spec.containers[*].securityContext.seLinuxOptions.type
      - spec.initContainers[*].securityContext.seLinuxOptions.type
      - spec.ephemeralContainers[*].securityContext.seLinuxOptions.type
      - spec.securityContext.seLinuxOptions.user
      - spec.containers[*].securityContext.seLinuxOptions.user
      - spec.initContainers[*].securityContext.seLinuxOptions.user
      - spec.ephemeralContainers[*].securityContext.seLinuxOptions.user
      - spec.securityContext.seLinuxOptions.role
      - spec.containers[*].securityContext.seLinuxOptions.role
      - spec.initContainers[*].securityContext.seLinuxOptions.role
      - spec.ephemeralContainers[*].securityContext.seLinuxOptions.role
    fix: |
      The allowed values are:
      - seLinuxOptions.type: undefined/"", container_t, container_init_t, container_kvm_t, or container_engine_t
      - seLinuxOptions.user: undefined/""
      - seLinuxOptions.role: undefined/""
      Optional hardening only: remove custom seLinuxOptions or use one of the allowed types.

  - id: safeguard-windows-block-host-process
    policyId: 077f0ce1
    severity: incompatible
    category: podSecurity
    check: |
      Windows Pods offer the ability to run HostProcess containers which enables privileged access to the Windows host machine. Privileged access to the host is disallowed in the Baseline policy.
      Check the following fields:
      - spec.securityContext.windowsOptions.hostProcess
      - spec.containers[*].securityContext.windowsOptions.hostProcess
      - spec.initContainers[*].securityContext.windowsOptions.hostProcess
      - spec.ephemeralContainers[*].securityContext.windowsOptions.hostProcess
    fix: |
      The allowed values are:
      - undefined/nil
      - false
      Remove hostProcess; incompatible if required.

  - id: safeguard-no-privileged-containers
    policyId: 95edb821
    severity: incompatible
    category: podSecurity
    check: |
      Privileged containers are disallowed in the Baseline policy.
      Check the following fields:
      - spec.containers[*].securityContext.privileged
      - spec.initContainers[*].securityContext.privileged
      - spec.ephemeralContainers[*].securityContext.privileged
    fix: |
      The allowed values are:
      - undefined/nil
      - false
      Remove privileged mode or set privileged to false; incompatible if privileged access is required.

  - id: safeguard-no-custom-proc-mount
    policyId: f85eb0dd
    severity: requiresChanges
    category: podSecurity
    check: |
      Custom /proc mount types are disallowed.
      Check the following fields:
      - spec.containers[*].securityContext.procMount
      - spec.initContainers[*].securityContext.procMount
      - spec.ephemeralContainers[*].securityContext.procMount
    fix: |
      The allowed values are:
      - undefined/nil
      - Default
      Remove custom procMount values or set procMount to Default.

  - id: safeguard-container-capabilities
    policyId: c26596ff
    severity: requiresChanges
    category: podSecurity
    check: |
      Adding capabilities is limited to the Baseline allowlist.
      Check the following fields:
      - spec.containers[*].securityContext.capabilities.add
      - spec.initContainers[*].securityContext.capabilities.add
      - spec.ephemeralContainers[*].securityContext.capabilities.add
    fix: |
      The allowed values are:
      - undefined/nil
      - AUDIT_WRITE
      - CHOWN
      - DAC_OVERRIDE
      - FOWNER
      - FSETID
      - KILL
      - MKNOD
      - NET_BIND_SERVICE
      - SETFCAP
      - SETGID
      - SETPCAP
      - SETUID
      - SYS_CHROOT
      Remove any added capability outside this list.

  - id: safeguard-host-probes
    policyId: acdf8909
    severity: informational
    enforcement: unverified  # Not in initiative c047ea8e v3.0.0 or the Learn Safeguards PSS table; keep as advisory, do not report as a blocker
    category: podSecurity
    check: |
      The host field in probes and lifecycle hooks is disallowed
      Restricted fields:
        - spec.containers[*].livenessProbe.httpGet.host
        - spec.containers[*].readinessProbe.httpGet.host
        - spec.containers[*].startupProbe.httpGet.host
        - spec.containers[*].livenessProbe.tcpSocket.host
        - spec.containers[*].readinessProbe.tcpSocket.host
        - spec.containers[*].startupProbe.tcpSocket.host
        - spec.containers[*].lifecycle.postStart.tcpSocket.host
        - spec.containers[*].lifecycle.preStop.tcpSocket.host
        - spec.containers[*].lifecycle.postStart.httpGet.host
        - spec.containers[*].lifecycle.preStop.httpGet.host
        - spec.initContainers[*].livenessProbe.httpGet.host
        - spec.initContainers[*].readinessProbe.httpGet.host
        - spec.initContainers[*].startupProbe.httpGet.host
        - spec.initContainers[*].livenessProbe.tcpSocket.host
        - spec.initContainers[*].readinessProbe.tcpSocket.host
        - spec.initContainers[*].startupProbe.tcpSocket.host
        - spec.initContainers[*].lifecycle.postStart.tcpSocket.host
        - spec.initContainers[*].lifecycle.preStop.tcpSocket.host
        - spec.initContainers[*].lifecycle.postStart.httpGet.host
        - spec.initContainers[*].lifecycle.preStop.httpGet.host
    fix: |
      The allowed values are:
        - undefined/nil
        - ""
      Remove the `host` field from probes and lifecycle hooks; the kubelet uses the pod IP by default.

  - id: safeguard-allowed-seccomp-profiles
    policyId: 975ce327
    severity: requiresChanges
    category: podSecurity
    check: |
      Seccomp must not be explicitly set to Unconfined.
      Check the following fields:
      - spec.securityContext.seccompProfile.type
      - spec.containers[*].securityContext.seccompProfile.type
      - spec.initContainers[*].securityContext.seccompProfile.type
      - spec.ephemeralContainers[*].securityContext.seccompProfile.type
    fix: |
      The allowed values are:
      - undefined/nil
      - RuntimeDefault
      - Localhost
      Remove Unconfined, or set seccompProfile.type to RuntimeDefault or Localhost.

# =============================================================================
# CONDITIONAL SAFEGUARDS — present in initiative c047ea8e but NOT part of the
# Baseline set AKS Automatic enforces by default. Report these only when the
# cluster's active constraints show them, when the user opts into PSS
# Restricted, or when the workload targets Windows nodes. Never present them
# as default Automatic migration blockers.
# =============================================================================
conditionalSafeguards:
  - id: safeguard-no-privilege-escalation
    policyId: 1c6e92c9
    severity: requiresChanges
    enforcement: conditional  # Learn: "Privilege Escalation (PSS Restricted Only)"
    appliesWhen: PSS Restricted is enabled on the cluster, or an active constraint forces allowPrivilegeEscalation=false
    category: podSecurity
    check: |
      allowPrivilegeEscalation must not be true; under Restricted it must be explicitly false.
      Check the following fields:
      - spec.containers[*].securityContext.allowPrivilegeEscalation
      - spec.initContainers[*].securityContext.allowPrivilegeEscalation
      - spec.ephemeralContainers[*].securityContext.allowPrivilegeEscalation
    patch: "add securityContext.allowPrivilegeEscalation: false"

  - id: safeguard-allowed-users-groups
    policyId: f06ddb64
    severity: requiresChanges
    enforcement: conditional  # Learn: "Running as Non-Root (PSS Restricted Only)"
    appliesWhen: PSS Restricted is enabled, or an active constraint sets runAsUserRule=MustRunAsNonRoot
    category: podSecurity
    check: |
      Containers must not run as root under Restricted.
      Check the following fields:
      - spec.securityContext.runAsNonRoot / runAsUser
      - spec.containers[*].securityContext.runAsNonRoot / runAsUser
    patch: "add securityContext.runAsNonRoot: true and a non-zero runAsUser the image supports"

  - id: safeguard-allowed-volume-types
    policyId: 16697877
    severity: informational
    enforcement: conditional  # Learn: "Volume Types (PSS Restricted Only)"
    appliesWhen: PSS Restricted is enabled on the cluster
    category: podSecurity
    check: |
      Under Restricted only these volume types are allowed:
      configMap, csi, downwardAPI, emptyDir, ephemeral, persistentVolumeClaim, projected, secret.
      Check the following field:
      - spec.volumes[*]
    fix: "Optional hardening: replace other volume types with an allowed type (hostPath is already covered by safeguard-no-host-path-volumes)"

  - id: safeguard-windows-block-container-admin
    policyId: 5485eac0
    severity: requiresChanges
    enforcement: conditional  # In initiative c047ea8e; not listed on the Learn Safeguards page. Windows node pools are optional on Automatic
    appliesWhen: The workload targets Windows nodes and the constraint is active on the cluster
    category: podSecurity
    check: |
      Windows containers must not run as ContainerAdministrator.
      Check the following fields:
      - spec.securityContext.windowsOptions.runAsUserName
      - spec.containers[*].securityContext.windowsOptions.runAsUserName
    fix: "Run as ContainerUser or another non-administrator Windows account"

# =============================================================================
# POD SECURITY STANDARDS — initiative metadata
# =============================================================================
podSecurityBaseline:
  initiative: a8640138-9b0a-4a28-b8cb-1666c838647d
  enforcement: mandatory on AKS Automatic (Enforce; namespace exclusions allowed, cannot switch to Warn)
  note: Overlaps with the Baseline-level Safeguards rules above
  policies: [NoPrivilegedContainers, BlockUsingHostNetwork, BlockUsingHostProcessIDAndIPC, ContainerCapabilities, NoHostPathVolume]

podSecurityRestricted:
  initiative: 42b8ef37-b724-4e24-bbc8-7a7708edfe00
  enforcement: optional opt-in (not enforced by default on Automatic)
  note: Adds the conditionalSafeguards marked "PSS Restricted Only"
  additionalPolicies: [NoPrivilegeEscalation, AllowedVolumeTypes, AllowedUsersGroups, AllowedSeccompProfiles]

# =============================================================================
# WEBHOOK MUTATIONS (2 active mutators) — auto-applied at admission
# =============================================================================
mutations:
  - id: mutation-anti-affinity-topology-spread
    policyId: implicit
    target: [Deployment, StatefulSet, ReplicaSet]
    effect: "Adds preferred pod anti-affinity (weight=100, kubernetes.io/hostname) + topology spread (maxSkew=1, kubernetes.io/hostname, ScheduleAnyway). Skips if any existing anti-affinity or topology spread. Label priority: app > app.kubernetes.io/name > default-antiaffinity-applabel."

  - id: mutation-resource-requests-default
    policyId: implicit
    target: containers
    effect: "Sets resources.requests+limits defaults cpu=500m, memory=2Gi. Minimums cpu=100m, memory=100Mi. If only limits set, requests=limits. If requests > limits, requests capped at limits (QoS fix)."

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Needs an MCP server, Needs a command-line tool, Needs Node.js

Security

What our scanner noticed· Low risk

  • Phrasing that asks for actions without confirmation

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Created by
Microsoft
Publisher
Microsoft (Official)
Source
microsoft/skills · .github/plugins/azure-skills/skills/azure-kubernetes/azure-kubernetes-automatic-readiness · commit 0696600
Licence
MIT License (redistribution allowed)
  • LICENSE (added by AutoGineer from .github/plugins/azure-skills/LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced
Also distributed in
microsoft/azure-skills

AutoGineer is not affiliated with or endorsed by Microsoft or Microsoft.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download azure-kubernetes-automatic-readiness.zip