Analyze Azure resource configurations against security best practices using Azure MCP bestpractices service. Produces per-resource security assessment with severity ratings and recommendations. Use during template generation before deployment confirmation.
npx skills add https://github.com/Azure/git-ape --skill azure-security-analyzer
Analyze Azure resource configurations against Microsoft security best practices and produce a per-resource security assessment report.
Every claim in the security report MUST be verifiable against the ARM template. Never fabricate, assume, or misrepresent security status.
Every "✅ Applied" status MUST cite the exact ARM template property path and its value that proves the control is in place. If you cannot point to a specific property in the template JSON, you cannot mark it as applied.
# ✅ CORRECT — cites exact property
| HTTPS-only | 🔴 Critical | ✅ Applied | `properties.httpsOnly: true` | Explicitly set in template |
# ❌ WRONG — no evidence from template
| Disk encryption | 🔴 Critical | ✅ Applied | `managedDisk.storageAccountType` | This property is the performance tier, NOT encryption |
Azure provides some security controls by default (e.g., SSE at rest on managed disks). These are NOT the same as explicitly configured controls.
| Status | Icon | Meaning | When to Use |
|--------|------|---------|-------------|
| ✅ Applied | ✅ | Explicitly configured in the ARM template | Property exists in template JSON with secure value |
| 🔄 Platform Default | 🔄 | Azure provides this automatically, NOT in template | Control exists due to Azure platform behavior, not template config |
| ⚠️ Not applied | ⚠️ | Control is missing and should be considered | Property absent from template, no platform default covers it |
| ❌ Misconfigured | ❌ | Property exists but set to an insecure value | Property in template with wrong/insecure value |
# ✅ CORRECT — distinguishes platform default from explicit config
| SSE at rest (managed disks) | 🟡 Medium | 🔄 Platform Default | Not in template | Azure encrypts all managed disks at rest with platform-managed keys automatically |
| Encryption at host (ADE) | 🟡 Medium | ⚠️ Not applied | `securityProfile.encryptionAtHost` absent | Not enabled — would encrypt temp disks and caches too |
# ❌ WRONG — claims explicit config for a platform default
| Managed disk encryption | 🔴 Critical | ✅ Applied | `managedDisk.storageAccountType` | WRONG: storageAccountType is performance tier, not encryption |
Describe security status accurately and literally. Do not soften or reframe risks.
# ❌ WRONG — misleading framing
| No open SSH to internet | 🔴 Critical | ✅ Applied |
# This is misleading: the VM HAS a public IP with port 22 open.
# IP-restriction reduces risk but port 22 IS internet-reachable.
# ✅ CORRECT — accurate framing
| SSH not open to 0.0.0.0/0 | 🔴 Critical | ✅ Applied | `sourceAddressPrefix: 175.x.x.x/32` | Restricted to single IP |
| VM is internet-facing (public IP + port 22) | 🟠 High | ⚠️ Risk accepted | Public IP attached to NIC | Port 22 reachable from internet (IP-restricted). Safer: Azure Bastion |
Specific rules:
Before generating the security report, perform this verification checklist:
storageAccountType is NOT encryption)publicIPAddress resource is attached to a NIC. If yes → VM is internet-facing, period.If you cannot determine a security status with certainty:
| {check} | {severity} | ❓ Unknown | {property} | Unable to verify — property path unclear or resource type not in checklist |
Never guess. Never fabricate. When in doubt, flag it.
Parse the ARM template or requirements to identify all resources and their configurations:
Input: ARM template JSON or resource configuration list
Extract for each resource:
- Resource type (e.g., Microsoft.Storage/storageAccounts)
- Resource name
- All security-relevant properties
- Current configuration values
For EACH resource type, query the Azure MCP bestpractices service to get security recommendations:
Tool: mcp_azure_mcp_search
Intent: "bestpractices {resource-type}"
Examples:
- "bestpractices Microsoft.Storage/storageAccounts"
- "bestpractices Microsoft.Web/sites"
- "bestpractices Microsoft.Sql/servers"
- "bestpractices Microsoft.DocumentDB/databaseAccounts"
- "bestpractices Microsoft.KeyVault/vaults"
- "bestpractices Microsoft.ContainerApp/containerApps"
Parse the MCP response for:
Cross-reference MCP recommendations against the template configuration.
Storage Accounts (Microsoft.Storage/storageAccounts):
| # | Check | Property | Severity | Secure Value |
|---|-------|----------|----------|--------------|
| 1 | HTTPS-only transfer | supportsHttpsTrafficOnly | 🔴 Critical | true |
| 2 | TLS 1.2 minimum | minimumTlsVersion | 🔴 Critical | TLS1_2 |
| 3 | Disable public blob access | allowBlobPublicAccess | 🟠 High | false |
| 4 | Blob soft delete | deleteRetentionPolicy.enabled | 🟠 High | true |
| 5 | Container soft delete | containerDeleteRetentionPolicy.enabled | 🟡 Medium | true |
| 6 | Disable shared key access | allowSharedKeyAccess | � High | false |
| 7 | Network rules / firewall | networkAcls.defaultAction | 🟡 Medium | Deny (prod) |
| 8 | Private endpoint | Private endpoint resource | 🟡 Medium | Configured (prod) |
| 9 | Infrastructure encryption | encryption.requireInfrastructureEncryption | 🔵 Low | true |
| 10 | Immutability policy | immutableStorageWithVersioning | 🔵 Low | Enabled (compliance) |
Function Apps / App Services (Microsoft.Web/sites):
| # | Check | Property | Severity | Secure Value |
|---|-------|----------|----------|--------------|
| 1 | HTTPS-only | httpsOnly | 🔴 Critical | true |
| 2 | TLS 1.2 minimum | siteConfig.minTlsVersion | 🔴 Critical | 1.2 |
| 3 | Managed identity | identity.type | 🔴 Critical | SystemAssigned |
| 4 | Identity-based storage access | AzureWebJobsStorage__accountName (not AzureWebJobsStorage) | 🔴 Critical | Identity-based |
| 5 | RBAC for storage | Role assignments for MI → Storage | 🔴 Critical | Storage Blob Data Owner + Storage Account Contributor |
| 6 | FTP disabled | siteConfig.ftpsState | 🟠 High | Disabled |
| 7 | Remote debugging off | siteConfig.remoteDebuggingEnabled | 🟠 High | false |
| 8 | Latest runtime version | siteConfig.linuxFxVersion or netFrameworkVersion | 🟠 High | Latest stable |
| 9 | App Insights connected | APPINSIGHTS_INSTRUMENTATIONKEY in appSettings | 🟡 Medium | Set |
| 8 | Health check enabled | siteConfig.healthCheckPath | 🟡 Medium | Set |
| 9 | CORS not wildcard | siteConfig.cors.allowedOrigins | 🟡 Medium | Not * |
| 10 | VNet integration | virtualNetworkSubnetId | 🟡 Medium | Configured (prod) |
| 11 | IP restrictions | siteConfig.ipSecurityRestrictions | 🔵 Low | Configured |
| 12 | HTTP/2 enabled | siteConfig.http20Enabled | 🔵 Low | true |
SQL Servers (Microsoft.Sql/servers):
| # | Check | Property | Severity | Secure Value |
|---|-------|----------|----------|--------------|
| 1 | TDE enabled | transparentDataEncryption.status | 🔴 Critical | Enabled |
| 2 | AAD-only auth | administrators.azureADOnlyAuthentication | 🔴 Critical | true |
| 3 | Minimal TLS 1.2 | minimalTlsVersion | 🔴 Critical | 1.2 |
| 4 | Auditing enabled | auditingSettings.state | 🟠 High | Enabled |
| 5 | Advanced threat protection | securityAlertPolicies.state | 🟠 High | Enabled |
| 6 | Firewall rules restrictive | firewallRules | 🟠 High | No 0.0.0.0/0 (prod) |
| 7 | Vulnerability assessment | vulnerabilityAssessments | 🟡 Medium | Enabled |
| 8 | Private endpoint | Private endpoint resource | 🟡 Medium | Configured (prod) |
| 9 | Long-term backup retention | backupLongTermRetentionPolicies | 🟡 Medium | Configured |
| 10 | Connection policy | connectionPolicies.connectionType | 🔵 Low | Redirect |
Cosmos DB (Microsoft.DocumentDB/databaseAccounts):
| # | Check | Property | Severity | Secure Value |
|---|-------|----------|----------|--------------|
| 1 | Firewall configured | ipRules or virtualNetworkRules | 🔴 Critical | Not empty |
| 2 | Disable key-based metadata writes | disableKeyBasedMetadataWriteAccess | 🟠 High | true |
| 3 | RBAC-based access | disableLocalAuth | 🟠 High | true (prefer RBAC) |
| 4 | Continuous backup | backupPolicy.type | 🟡 Medium | Continuous |
| 5 | Customer-managed keys | keyVaultKeyUri | 🟡 Medium | Set (prod) |
| 6 | Diagnostic logging | Diagnostic setting resource | 🟡 Medium | Enabled |
| 7 | Private endpoint | Private endpoint resource | 🟡 Medium | Configured (prod) |
Key Vault (Microsoft.KeyVault/vaults):
| # | Check | Property | Severity | Secure Value |
|---|-------|----------|----------|--------------|
| 1 | Soft delete enabled | enableSoftDelete | 🔴 Critical | true (now default) |
| 2 | Purge protection | enablePurgeProtection | 🔴 Critical | true |
| 3 | RBAC authorization | enableRbacAuthorization | 🟠 High | true |
| 4 | Network rules | networkAcls.defaultAction | 🟡 Medium | Deny (prod) |
| 5 | Private endpoint | Private endpoint resource | 🟡 Medium | Configured (prod) |
| 6 | Diagnostic logging | Diagnostic setting resource | 🟡 Medium | Enabled |
Container Apps (Microsoft.App/containerApps):
| # | Check | Property | Severity | Secure Value |
|---|-------|----------|----------|--------------|
| 1 | Ingress HTTPS only | ingress.transport | 🔴 Critical | http with allowInsecure: false |
| 2 | Managed identity | identity.type | 🟠 High | SystemAssigned |
| 3 | Min replicas > 0 (prod) | scale.minReplicas | 🟡 Medium | > 0 for prod |
| 4 | VNet integration | Container Apps Environment | 🟡 Medium | Configured |
| 5 | Secret management | secrets with Key Vault refs | 🟡 Medium | Key Vault references |
Virtual Machines (Microsoft.Compute/virtualMachines):
| # | Check | Property | Severity | Secure Value |
|---|-------|----------|----------|--------------|
| 1 | Password authentication disabled | osProfile.linuxConfiguration.disablePasswordAuthentication | 🔴 Critical | true |
| 2 | SSH key configured | osProfile.linuxConfiguration.ssh.publicKeys | 🔴 Critical | At least one key |
| 3 | Internet exposure (public IP) | Check if NIC references publicIPAddress | 🟠 High | No public IP (use Bastion). If public IP present → flag as internet-facing |
| 4 | NSG SSH not open to 0.0.0.0/0 | NSG securityRules[].sourceAddressPrefix for port 22 | 🔴 Critical | Not * or Internet — must be specific IP/CIDR |
| 5 | Encryption at host | securityProfile.encryptionAtHost | 🟡 Medium | true (encrypts temp disks + caches) |
| 6 | Azure Disk Encryption (ADE) | ADE VM extension resource | 🟡 Medium | Extension present |
| 7 | SSE at rest (managed disks) | Platform default — NOT a template property | 🔵 Info | 🔄 Platform Default — Azure encrypts all managed disks automatically. Do NOT mark as "✅ Applied" |
| 8 | Boot diagnostics | diagnosticsProfile.bootDiagnostics.enabled | 🟡 Medium | true |
| 9 | Managed identity | identity.type | 🟡 Medium | SystemAssigned (if VM accesses Azure resources) |
| 10 | Automatic OS updates | osProfile.linuxConfiguration.patchSettings.patchMode | 🔵 Low | AutomaticByPlatform |
| 11 | Trusted launch | securityProfile.securityType | 🟡 Medium | TrustedLaunch with vTPM and secure boot |
⚠️ VM Internet Exposure Rule: If ANY Microsoft.Network/publicIPAddresses resource is attached to the VM's NIC, the VM IS internet-facing. Always flag this explicitly, even if NSG rules restrict source IPs. An IP-restricted port is still internet-reachable — the restriction is a mitigation, not a closure.
Network Security Groups (Microsoft.Network/networkSecurityGroups):
| # | Check | Property | Severity | Secure Value |
|---|-------|----------|----------|--------------|
| 1 | No rules with source * or Internet on management ports (22, 3389) | securityRules[].sourceAddressPrefix | 🔴 Critical | Specific IP/CIDR only |
| 2 | Explicit deny-all inbound rule | Custom deny rule at high priority | 🟠 High | Present |
| 3 | No overly permissive rules (* destination port) | securityRules[].destinationPortRange | 🟠 High | Specific ports only |
| 4 | NSG flow logs | Separate flow log resource | 🟡 Medium | Enabled |
Before classifying posture, run the verification checklist from the Verification Integrity Rules section:
publicIPAddress resource exists and which ports are open.If you find an error during verification: Fix it immediately. Do not present unverified findings to the user.
Based on the per-resource analysis, calculate an overall score AND the Security Gate status:
Security Gate (BLOCKING):
- ALL 🔴 Critical checks MUST pass → if any fail, gate = 🔴 BLOCKED
- ALL 🟠 High checks MUST pass → if any fail, gate = 🔴 BLOCKED
- If all Critical + High pass → gate = 🟢 PASSED
- 🟡 Medium and 🔵 Low do NOT block deployment
"Pass" means status is ✅ Applied or 🔄 Platform Default.
"Fail" means status is ⚠️ Not applied, ❌ Misconfigured, or ❓ Unknown.
Overall Posture (informational — does NOT control gating):
- **EXCELLENT** — All critical+high passed, > 75% medium passed
- **GOOD** — All critical+high passed, > 50% medium passed
- **ACCEPTABLE** — All critical passed, some high missing
- **NEEDS ATTENTION** — Some high-severity checks failed
- **NEEDS IMMEDIATE ATTENTION** — Critical checks failed (DO NOT deploy without fixing)
The Security Gate is the authoritative deployment-blocking mechanism. The posture label is informational only. A posture of "ACCEPTABLE" still results in 🔴 BLOCKED if any High checks fail.
Produce a structured security assessment:
# Security Best Practices Analysis
**Deployment ID:** {deployment-id}
**Analyzed:** {timestamp}
**Source:** Azure MCP bestpractices service
**Resources Analyzed:** {count}
## Overall Security Posture: {EXCELLENT|GOOD|ACCEPTABLE|NEEDS ATTENTION}
**Summary:**
- 🔴 Critical: {passed}/{total} passed
- 🟠 High: {passed}/{total} passed
- 🟡 Medium: {passed}/{total} passed
- 🔵 Low: {passed}/{total} passed
## Per-Resource Assessment
### {Resource Type}: {Resource Name}
| # | Recommendation | Severity | Status | Property | Evidence | Notes |
|---|---------------|----------|--------|----------|----------|-------|
| 1 | {check name} | {severity} | ✅ Applied | {exact property path} | {actual value from template} | {note} |
| 2 | {check name} | {severity} | 🔄 Platform Default | {property} | Not in template | {Azure provides this automatically} |
| 3 | {check name} | {severity} | ⚠️ Not applied | {property} | Absent | {recommendation} |
**Score: {applied}/{total}** ({percentage}%)
{Repeat for each resource}
## Recommendations
### Must Fix (before deployment)
{List any failed critical checks — these should block deployment}
### Should Fix (strongly recommended)
{List any failed high checks — warn user but don't block}
### Consider (best practice)
{List failed medium/low checks — informational}
## Environment-Specific Notes
**For production deployments:**
- Private endpoints should be configured for all data resources
- Network rules should default to Deny
- VNet integration recommended for compute resources
- Consider customer-managed keys for encryption
**For dev/staging:**
- Network rules can use Allow for easier development
- Private endpoints are optional
- Shared key access acceptable for development
Return the security report to the calling agent (template generator) with two key outputs:
security-analysis.md)🟢 PASSED or 🔴 BLOCKED with list of blocking findingsThe gate status MUST be prominently displayed at the top of the report:
## Security Gate: 🟢 PASSED
All Critical and High security checks pass. Deployment may proceed.
or:
## Security Gate: 🔴 BLOCKED
Deployment cannot proceed. The following checks must be resolved:
| # | Check | Severity | Resource | Status | Required Fix |
|---|-------|----------|----------|--------|--------------|
| 1 | {check} | 🔴 Critical | {resource} | ⚠️ Not applied | {fix} |
Also save the report to .azure/deployments/$DEPLOYMENT_ID/security-analysis.md.
Save the gate result to .azure/deployments/$DEPLOYMENT_ID/security-gate.json:
{
"gate": "PASSED",
"blockingFindings": [],
"criticalTotal": 4,
"criticalPassed": 4,
"highTotal": 6,
"highPassed": 6,
"timestamp": "2026-02-19T10:00:00Z"
}
| Severity | Icon | Meaning | Action |
|----------|------|---------|--------|
| Critical | 🔴 | Security vulnerability if missing | Must fix before deployment |
| High | 🟠 | Strongly recommended by Microsoft | Should fix, warn user |
| Medium | 🟡 | Best practice, may have trade-offs | Recommend, user decides |
| Low | 🔵 | Nice to have, optional | Informational only |
Some checks are environment-dependent:
| Check | Dev | Staging | Prod |
|-------|-----|---------|------|
| Private endpoints | 🔵 Optional | 🟡 Recommended | 🟠 Required |
| Network firewall (Deny) | 🔵 Optional | 🟡 Recommended | 🟠 Required |
| VNet integration | 🔵 Optional | 🟡 Recommended | 🟠 Required |
| Customer-managed keys | 🔵 Optional | 🔵 Optional | 🟡 Recommended |
| IP restrictions | 🔵 Optional | 🟡 Recommended | 🟠 Required |
| Shared key access | 🟡 Acceptable | 🟡 Restricted | 🔴 Disabled |
When analyzing, adjust severity ratings based on the target environment from the requirements.
Invoked by template generator:
/azure-security-analyzer
Input: ARM template resources and target environment
Output: Per-resource security assessment with severity ratings
Manual invocation:
User: /azure-security-analyzer
Agent: Provide the ARM template or resource configurations to analyze.
User: [pastes template or points to deployment]
Agent: Analyzing 3 resources against Azure best practices...
[Produces security report]
Post-deployment audit:
User: /azure-security-analyzer --deployment-id deploy-20260218-193500
Agent: Loading template from .azure/deployments/deploy-20260218-193500/template.json...
[Analyzes and produces report]
If MCP bestpractices service is unavailable:
If a resource type is not in the checklists:
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.
Discovers available Azure OpenAI model capacity across regions and projects. Analyzes quota limits, compares availability, and recommends optimal deployment locations based on capacity requirements. USE FOR: find capacity, check quota, where can I deploy, capacity discovery, best region for capacity, multi-project capacity search, quota analysis, model availability, region comparison, check TPM availability. DO NOT USE FOR: actual deployment (hand off to preset or customize after discovery), quota increase requests (direct user to Azure Portal), listing existing deployments.
Interactive guided deployment flow for Azure OpenAI models with full customization control. Step-by-step selection of model version, SKU (GlobalStandard/Standard/ProvisionedManaged), capacity, RAI policy (content filter), and advanced options (dynamic quota, priority processing, spillover). USE FOR: custom deployment, customize model deployment, choose version, select SKU, set capacity, configure content filter, RAI policy, deployment options, detailed deployment, advanced deployment, PTU deployment, provisioned throughput. DO NOT USE FOR: quick deployment to optimal region (use preset).
Unified Azure OpenAI model deployment skill with intelligent intent-based routing. Handles quick preset deployments, fully customized deployments (version/SKU/capacity/RAI policy), and capacity discovery across regions and projects. USE FOR: deploy model, deploy gpt, create deployment, model deployment, deploy openai model, set up model, provision model, find capacity, check model availability, where can I deploy, best region for model, capacity analysis. DO NOT USE FOR: listing existing deployments (use foundry_models_deployments_list MCP tool), deleting deployments, agent creation (use agent/create), project creation (use project/create).
Intelligently deploys Azure OpenAI models to optimal regions by analyzing capacity across all available regions. Automatically checks current region first and shows alternatives if needed. USE FOR: quick deployment, optimal region, best region, automatic region selection, fast setup, multi-region capacity check, high availability deployment, deploy to best location. DO NOT USE FOR: custom SKU selection (use customize), specific version selection (use customize), custom capacity configuration (use customize), PTU deployments (use customize).
This skill should be used when working with LaminDB, an open-source data framework for biology that makes data queryable, traceable, reproducible, and FAIR. Use when managing biological datasets (scRNA-seq, spatial, flow cytometry, etc.), tracking computational workflows, curating and validating data with biological ontologies, building data lakehouses, or ensuring data lineage and reproducibility in biological research. Covers data management, annotation, ontologies (genes, cell types, diseases, tissues), schema validation, integrations with workflow managers (Nextflow, Snakemake) and MLOps platforms (W&B, MLflow), and deployment strategies.
Latch platform for bioinformatics workflows. Build pipelines with Latch SDK, @workflow/@task decorators, deploy serverless workflows, LatchFile/LatchDir, Nextflow/Snakemake integration.
Run Python code in the cloud with serverless containers, GPUs, and autoscaling. Use when deploying ML models, running batch processing jobs, scheduling compute-intensive tasks, or serving APIs that require GPU acceleration or dynamic scaling.
Take azure/azure-security-analyzer from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.