# AKS Automatic Compatibility Constraint Spec — Condensed Reference
# Version: 1.1.1 | AKS: 2026-03-15
# This condensed version is optimized for LLM context.

apiVersion: aks-automatic.azure.com/v1
kind: ConstraintSpecReference
metadata:
  version: "1.1.1"
  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 (26 total, 3 are internal/HOBO)
# =============================================================================
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"

  # -- HOBO (internal, skip in assessment) --
  - id: hobo-critical-addons-noschedule
    severity: internal
    note: AKS-managed, not customer-facing
  - id: hobo-critical-addons-noexecute
    severity: internal
    note: AKS-managed, not customer-facing
  - id: hobo-hosted-vm-taint
    severity: internal
    note: AKS-managed, not customer-facing

# =============================================================================
# WORKLOAD CONSTRAINTS — Deployment Safeguards (25 active policies)
# Initiative: c047ea8e | Effect: Deny on Automatic
# =============================================================================
safeguards:
  # -- AKS Best Practices (10 policies) --
  - id: safeguard-restricted-node-edits
    policyId: 53a4a537
    severity: requiresChanges
    category: nodeProtection
    check: Blocks unauthorized Node object mutations
    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 need 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 keys 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, or exec) — 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"

  - 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"

  # -- Baseline PSS policies in Safeguards (15 policies) --
  - id: safeguard-block-host-namespaces
    policyId: 47a1ee2f
    severity: incompatible
    category: podSecurity
    check: hostPID and hostIPC must be false
    fix: Remove hostPID/hostIPC; redesign if required

  - id: safeguard-host-network-ports
    policyId: 82985f06
    severity: incompatible
    category: podSecurity
    check: hostNetwork must be false, no hostPort allowed
    fix: Use ClusterIP Services or Ingress instead

  - id: safeguard-allowed-sysctls
    policyId: 5e5a0673
    severity: requiresChanges
    category: podSecurity
    check: Only safe sysctls allowed (10 specific ones)
    fix: Remove disallowed sysctls

  - id: safeguard-allowed-users-groups
    policyId: f06ddb64
    severity: requiresChanges
    category: podSecurity
    check: RunAsUser must be non-root (MustRunAsNonRoot)
    patch: "add securityContext.runAsNonRoot: true, runAsUser: 1000"

  - id: safeguard-windows-block-container-admin
    policyId: 5485eac0
    severity: requiresChanges
    category: podSecurity
    check: Windows containers must not run as ContainerAdministrator

  - id: safeguard-no-privilege-escalation
    policyId: 1c6e92c9
    severity: requiresChanges
    category: podSecurity
    check: allowPrivilegeEscalation must not be true
    patch: "add securityContext.allowPrivilegeEscalation: false"

  - id: safeguard-no-host-path-volumes
    policyId: 098fc59e
    severity: incompatible
    category: podSecurity
    check: hostPath volumes blocked (empty allowed list)
    fix: Replace with PVC, ConfigMap, CSI, or sidecar logging

  - id: safeguard-enforce-apparmor
    policyId: 511f5417
    severity: requiresChanges
    category: podSecurity
    check: Must use runtime/default or RuntimeDefault AppArmor profile
    patch: "add securityContext.appArmorProfile.type: RuntimeDefault (K8s 1.30+) or annotation container.apparmor.security.beta.kubernetes.io/{name}: runtime/default"

  - id: safeguard-enforce-selinux
    policyId: e1e6c427
    severity: informational
    category: podSecurity
    check: Restricted PSS only — SELinux type must be container_t, container_init_t, container_kvm_t, or container_engine_t. Not enforced by AKS Automatic baseline.
    fix: "Optional hardening: remove custom seLinuxOptions or use allowed types"

  - id: safeguard-windows-block-host-process
    policyId: 077f0ce1
    severity: incompatible
    category: podSecurity
    check: Windows HostProcess pods blocked
    fix: Remove hostProcess; incompatible if required

  - id: safeguard-no-privileged-containers
    policyId: 95edb821
    severity: incompatible
    category: podSecurity
    check: privileged=true blocked
    fix: Remove privileged mode; use specific capabilities instead

  - id: safeguard-no-custom-proc-mount
    policyId: f85eb0dd
    severity: requiresChanges
    category: podSecurity
    check: Only Default procMount allowed
    patch: "remove securityContext.procMount"

  - id: safeguard-container-capabilities
    policyId: c26596ff
    severity: requiresChanges
    category: podSecurity
    check: No capabilities may be added (allowedCapabilities=[])
    patch: "remove securityContext.capabilities.add"

  - id: safeguard-allowed-seccomp-profiles
    policyId: 975ce327
    severity: requiresChanges
    category: podSecurity
    check: Only RuntimeDefault and Localhost seccomp profiles
    patch: "add seccompProfile.type: RuntimeDefault"

  - id: safeguard-allowed-volume-types
    policyId: 16697877
    severity: informational
    category: podSecurity
    check: Restricted PSS recommendation (not enforced by AKS Automatic baseline)
    fix: "Optional hardening: replace non-standard volumes with supported alternatives"

# =============================================================================
# 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)."

# =============================================================================
# POD SECURITY STANDARDS
# =============================================================================
podSecurityBaseline:
  initiative: a8640138-9b0a-4a28-b8cb-1666c838647d
  enforcement: mandatory (Deny)
  note: All 5 policies overlap with Deployment Safeguards
  policies: [NoPrivilegedContainers, BlockUsingHostNetwork, BlockUsingHostProcessIDAndIPC, ContainerCapabilities, NoHostPathVolume]

podSecurityRestricted:
  initiative: 42b8ef37-b724-4e24-bbc8-7a7708edfe00
  enforcement: optional (Audit only)
  note: Not enforced by default. Opt-in for stricter security.
  additionalPolicies: [NoPrivilegeEscalation, AllowedVolumeTypes, AllowedUsersGroups, AllowedSeccompProfiles]
