🥒 CCC.ObjStor Test: ccc-test-container-20260410t090725z

Test Parameters

ServiceTypeobject-storage
ProviderServiceTypeMicrosoft.Storage/storageAccounts
CatalogTypesCCC.ObjStor
TagFilter@object-storage, @PerService, @Policy, ~@NEGATIVE, ~@OPT_IN
UID/subscriptions/c1cedd8e-bf91-4d7d-a4cc-45700402a2a1/resourceGroups/cfi_test_20260410t090725z/providers/Microsoft.Storage/storageAccounts/stgcfi20260410t090725z
ResourceNameccc-test-container-20260410t090725z
ReportFileccc-test-container-20260410t090725z-service
ReportTitleccc-test-container-20260410t090725z
Instance
{
  "ID": "main-azure",
  "Properties": {
    "Provider": "azure",
    "Region": "eastus",
    "AzureResourceGroup": "cfi_test_20260410t090725z",
    "AzureSubscriptionID": "c1cedd8e-bf91-4d7d-a4cc-45700402a2a1",
    "GcpProjectId": ""
  },
  "Services": [
    {
      "Type": "object-storage",
      "Properties": {
        "azure-storage-account": "stgcfi20260410t090725z",
        "default-container": "ccc-test-container-20260410t090725z",
        "object-storage-retention-period-days": 2
      }
    },
    {
      "Type": "logging",
      "Properties": {}
    }
  ],
  "Rules": {
    "permitted-destination-storage-accounts": [],
    "permitted-regions": [
      "eastus"
    ],
    "replication-locations": [
      "eastus",
      "westus"
    ]
  }
}
AzureResourceGroupcfi_test_20260410t090725z
AzureStorageAccountstgcfi20260410t090725z
AzureSubscriptionIDc1cedd8e-bf91-4d7d-a4cc-45700402a2a1
DefaultContainerccc-test-container-20260410t090725z
ObjectStorageRetentionPeriodDays2
PermittedDestinationStorageAccounts
[]
PermittedRegions
[
  "eastus"
]
Providerazure
Regioneastus
ReplicationLocations
[
  "eastus",
  "westus"
]
ResourceGroupcfi_test_20260410t090725z
SubscriptionIdc1cedd8e-bf91-4d7d-a4cc-45700402a2a1

Summary

Generated: 2026-04-10 09:13:12

Total Run Time: 1m41s

Features: 41

Scenarios: 41 (✅ 34 | ❌ 7)

Steps: 170 (✅ 156 | ❌ 7 | ⏭️ 7 | ❓ 0)

Feature: CCC.Core.CN01.AR01
Scenario: Storage account enforces minimum TLS version @CCC.Core @tlp-green @tlp-amber @tlp-red @CCC.Core.CN01 @Policy @PerService @object-storage
Given a cloud api for "{Instance}" in "api"50µs
When I attempt policy check "object-storage-tls-policy" for control "CCC.Core.CN01" assessment requirement "AR01" for service "{ServiceType}" on resource "{ResourceName}" and provider "{Provider}"1s
policy check failed: Azure Storage Account TLS Policy Check:
Then "{result}" is true24µs
📎 Attachments:
policy-result-object-storage-tls-policy.json
View JSON (2290 bytes)
{
  "policy_path": "/home/runner/work/ccc-cfi-compliance/ccc-cfi-compliance/testing/policy/CCC.Core/CCC.Core.CN01/AR01/object-storage-tls-policy/azure.yaml",
  "name": "Azure Storage Account TLS Policy Check",
  "service_type": "object-storage",
  "requirement_text": "When a port is exposed for non-SSH network traffic, all traffic MUST include  a TLS handshake AND be encrypted using TLS 1.3 or higher.\n",
  "validity_score": 9,
  "validity_commentary": "This query validates TLS configuration at the Azure Storage Account level. Azure enforces minimum TLS version at the account level for all blob, file, queue, and table endpoints. Note: Azure Storage currently supports TLS 1.2  as the highest minimum version - TLS 1.3 support is available but cannot  be set as the exclusive minimum yet.\n",
  "query_template": "az storage account show \\\n  --name ${AzureStorageAccount} \\\n  --resource-group ${AzureResourceGroup} \\\n  --query \"{minimumTlsVersion: minimumTlsVersion, supportsHttpsTrafficOnly: supportsHttpsTrafficOnly}\" \\\n  --output json\n",
  "query_executed": "az storage account show \\\n  --name stgcfi20260410t090725z \\\n  --resource-group cfi_test_20260410t090725z \\\n  --query \"{minimumTlsVersion: minimumTlsVersion, supportsHttpsTrafficOnly: supportsHttpsTrafficOnly}\" \\\n  --output json\n",
  "query_output": "{\n  \"minimumTlsVersion\": \"TLS1_2\",\n  \"supportsHttpsTrafficOnly\": null\n}\n",
  "passed": false,
  "rule_results": [
    {
      "jsonpath": "$.minimumTlsVersion",
      "expected_values": [
        "TLS1_3"
      ],
      "validation_rule": "^TLS1_3$",
      "description": "Verifies that the minimum TLS protocol version is set to TLS 1.3. Note: Azure Storage does not yet support TLS 1.3 as a minimum version, so this check will fail until Azure adds support. This accurately reflects the compliance gap against the CCC requirement.\n",
      "actual_value": "[TLS1_2]",
      "passed": false
    },
    {
      "jsonpath": "$.supportsHttpsTrafficOnly",
      "expected_values": [
        "true"
      ],
      "validation_rule": "^true$",
      "description": "Confirms that HTTPS-only traffic is enforced. When enabled, all HTTP  requests are rejected (not redirected).",
      "actual_value": "[null]",
      "passed": false
    }
  ]
}
Feature: CCC.Core.CN01.AR03
Scenario: Object storage policy prevents the use of unencrypted ports @tlp-green @tlp-amber @tlp-red @CCC.Core @CCC.Core.CN01 @Policy @PerService @object-storage
When I attempt policy check "object-storage-unencrypted-policy" for control "CCC.Core.CN01" assessment requirement "AR03" for service "{ServiceType}" on resource "{ResourceName}" and provider "{Provider}"1s
policy check failed: Azure Storage Unencrypted Traffic Block Check:
Then "{result}" is true25µs
📎 Attachments:
policy-result-object-storage-unencrypted-policy.json
View JSON (1874 bytes)
{
  "policy_path": "/home/runner/work/ccc-cfi-compliance/ccc-cfi-compliance/testing/policy/CCC.Core/CCC.Core.CN01/AR03/object-storage-unencrypted-policy/azure.yaml",
  "name": "Azure Storage Unencrypted Traffic Block Check",
  "service_type": "object-storage",
  "requirement_text": "Unencrypted traffic MUST be blocked or redirected to secure equivalents so that no data is transmitted in plaintext.\n",
  "validity_score": 9,
  "validity_commentary": "This query validates that Azure Storage rejects HTTP traffic at the account level. When supportsHttpsTrafficOnly is true, all HTTP requests are rejected (not redirected). Strengths: - Account-level enforcement for all blob, file, queue, and table endpoints - Prevents plaintext transmission Limitations: - Does not validate TLS version (see AR01 object-storage-tls-policy) - Redirect behavior (301/302) is not validated here; Azure rejects HTTP outright\n",
  "query_template": "az storage account show \\\n  --name ${AzureStorageAccount} \\\n  --resource-group ${AzureResourceGroup} \\\n  --query \"{supportsHttpsTrafficOnly: supportsHttpsTrafficOnly}\" \\\n  --output json\n",
  "query_executed": "az storage account show \\\n  --name stgcfi20260410t090725z \\\n  --resource-group cfi_test_20260410t090725z \\\n  --query \"{supportsHttpsTrafficOnly: supportsHttpsTrafficOnly}\" \\\n  --output json\n",
  "query_output": "{\n  \"supportsHttpsTrafficOnly\": null\n}\n",
  "passed": false,
  "rule_results": [
    {
      "jsonpath": "$.supportsHttpsTrafficOnly",
      "expected_values": [
        "true"
      ],
      "validation_rule": "^true$",
      "description": "Confirms that HTTPS-only traffic is enforced. When enabled, all HTTP requests are rejected at the storage account level, preventing plaintext transmission to containers and blobs.\n",
      "actual_value": "[null]",
      "passed": false
    }
  ]
}
Feature: CCC.Core.CN01.AR08
Scenario: Storage account enforces mutual TLS @tls @tlp-amber @tlp-red @CCC.Core @CCC.Core.CN01 @Policy @NotTested @PerService @object-storage
Then no-op required26µs
Feature: CCC.Core.CN02.AR01 - Data Encryption at Rest
Scenario: Object storage encryption compliance @PerService @CCC.Core @CCC.Core.CN02 @tlp-green @tlp-amber @tlp-red @Policy @object-storage
Given a cloud api for "{Instance}" in "api"40µs
When I attempt policy check "object-storage-encryption" for control "CCC.Core.CN02" assessment requirement "AR01" for service "{ServiceType}" on resource "{ResourceName}" and provider "{Provider}"1s
Then "{result}" is true43µs
📎 Attachments:
policy-result-object-storage-encryption.json
View JSON (2975 bytes)
{
  "policy_path": "/home/runner/work/ccc-cfi-compliance/ccc-cfi-compliance/testing/policy/CCC.Core/CCC.Core.CN02/AR01/object-storage-encryption/azure.yaml",
  "name": "Azure Storage Account Encryption Check",
  "service_type": "object-storage",
  "requirement_text": "When data is stored, it MUST be encrypted using the latest industry-standard  encryption methods.\n",
  "validity_score": 9,
  "validity_commentary": "This query validates Azure Storage Account encryption configuration. Azure Storage automatically encrypts all data at rest with 256-bit AES encryption. Strengths: - Directly queries the storage account's encryption configuration - Validates encryption key source (Microsoft-managed or customer-managed) - Azure enforces encryption for all data, cannot be disabled Limitations: - Does not validate Key Vault key configuration details - Does not verify customer-managed key rotation policies - Infrastructure encryption (double encryption) is checked separately\n",
  "query_template": "az storage account show \\\n  --name ${AzureStorageAccount} \\\n  --resource-group ${AzureResourceGroup} \\\n  --query \"{keySource: encryption.keySource, requireInfrastructureEncryption: encryption.requireInfrastructureEncryption, services: encryption.services}\" \\\n  --output json\n",
  "query_executed": "az storage account show \\\n  --name stgcfi20260410t090725z \\\n  --resource-group cfi_test_20260410t090725z \\\n  --query \"{keySource: encryption.keySource, requireInfrastructureEncryption: encryption.requireInfrastructureEncryption, services: encryption.services}\" \\\n  --output json\n",
  "query_output": "{\n  \"keySource\": \"Microsoft.Storage\",\n  \"requireInfrastructureEncryption\": null,\n  \"services\": {\n    \"blob\": {\n      \"enabled\": true,\n      \"keyType\": \"Account\",\n      \"lastEnabledTime\": \"2026-04-10T09:08:27.063268+00:00\"\n    },\n    \"file\": {\n      \"enabled\": true,\n      \"keyType\": \"Account\",\n      \"lastEnabledTime\": \"2026-04-10T09:08:27.063268+00:00\"\n    },\n    \"queue\": null,\n    \"table\": null\n  }\n}\n",
  "passed": true,
  "rule_results": [
    {
      "jsonpath": "$.keySource",
      "expected_values": [
        "Microsoft.Storage",
        "Microsoft.Keyvault"
      ],
      "validation_rule": "^(Microsoft\\.Storage|Microsoft\\.Keyvault)$",
      "description": "Verifies that encryption is configured with an approved key source. 'Microsoft.Storage' uses Microsoft-managed keys, 'Microsoft.Keyvault' uses customer-managed keys stored in Azure Key Vault.\n",
      "actual_value": "[Microsoft.Storage]",
      "passed": true
    },
    {
      "jsonpath": "$.services.blob.enabled",
      "expected_values": [
        "true"
      ],
      "validation_rule": "^true$",
      "description": "Verifies that blob service encryption is enabled. This should always be true as Azure Storage encryption cannot be disabled.\n",
      "actual_value": "[true]",
      "passed": true
    }
  ]
}
Feature: CCC.Core.CN03.AR01 - Multi-Factor Authentication for Destructive Operations
Scenario: Object storage delete protection compliance @PerService @CCC.Core @CCC.Core.CN03 @tlp-green @tlp-amber @tlp-red @Policy @object-storage
Given a cloud api for "{Instance}" in "api"44µs
When I attempt policy check "object-storage-delete-protection" for control "CCC.Core.CN03" assessment requirement "AR01" for service "{ServiceType}" on resource "{ResourceName}" and provider "{Provider}"1s
Then "{result}" is true33µs
📎 Attachments:
policy-result-object-storage-delete-protection.json
View JSON (3042 bytes)
{
  "policy_path": "/home/runner/work/ccc-cfi-compliance/ccc-cfi-compliance/testing/policy/CCC.Core/CCC.Core.CN03/AR01/object-storage-delete-protection/azure.yaml",
  "name": "Azure Storage Account Soft Delete and Versioning Configuration",
  "service_type": "object-storage",
  "requirement_text": "When an entity attempts to modify the service through a user interface, the  authentication process MUST require multiple identifying factors for authentication.\n",
  "validity_score": 5,
  "validity_commentary": "Azure does not have a direct equivalent to S3 MFA Delete at the storage level. MFA in Azure is enforced at the Azure AD/Entra ID level for all operations. This check validates soft delete and versioning as compensating controls. Strengths: - Soft delete allows recovery of deleted blobs - Versioning preserves all blob versions - Azure AD MFA applies to all authenticated operations Limitations: - This is NOT a direct MFA-for-delete check - MFA enforcement is at the identity layer, not storage layer - Soft delete only protects for the retention period - For true MFA enforcement, Azure AD Conditional Access policies should be verified\n",
  "query_template": "az storage account blob-service-properties show \\\n  --account-name ${AzureStorageAccount} \\\n  --resource-group ${AzureResourceGroup} \\\n  --query \"{softDeleteEnabled: deleteRetentionPolicy.enabled, softDeleteDays: deleteRetentionPolicy.days, versioningEnabled: isVersioningEnabled}\" \\\n  --output json\n",
  "query_executed": "az storage account blob-service-properties show \\\n  --account-name stgcfi20260410t090725z \\\n  --resource-group cfi_test_20260410t090725z \\\n  --query \"{softDeleteEnabled: deleteRetentionPolicy.enabled, softDeleteDays: deleteRetentionPolicy.days, versioningEnabled: isVersioningEnabled}\" \\\n  --output json\n",
  "query_output": "{\n  \"softDeleteDays\": 7,\n  \"softDeleteEnabled\": true,\n  \"versioningEnabled\": true\n}\n",
  "passed": true,
  "rule_results": [
    {
      "jsonpath": "$.softDeleteEnabled",
      "expected_values": [
        "true"
      ],
      "validation_rule": "^true$",
      "description": "Verifies that blob soft delete is enabled. This allows recovery of deleted blobs within the retention period, providing protection against accidental or malicious deletion.\n",
      "actual_value": "[true]",
      "passed": true
    },
    {
      "jsonpath": "$.softDeleteDays",
      "expected_values": [],
      "validation_rule": "^[7-9]|[1-9][0-9]+$",
      "description": "Verifies that soft delete retention is at least 7 days. Higher values provide longer recovery windows.\n",
      "actual_value": "[7]",
      "passed": true
    },
    {
      "jsonpath": "$.versioningEnabled",
      "expected_values": [
        "true"
      ],
      "validation_rule": "^true$",
      "description": "Verifies that blob versioning is enabled. Versioning preserves all previous versions of blobs, enabling recovery from modifications.\n",
      "actual_value": "[true]",
      "passed": true
    }
  ]
}
Feature: CCC.Core.CN03.AR02 - API Authentication with Credentials
Scenario: API modification requires credential and trust perimeter origin @PerService @CCC.Core @CCC.Core.CN03 @tlp-clear @tlp-green @tlp-amber @tlp-red @Policy @NotTestable @object-storage @load-balancer
Given a cloud api for "{Instance}" in "api"33µs
Then no-op required24µs
Feature: CCC.Core.CN03.AR03 - MFA for UI Viewing
Scenario: UI viewing requires multi-factor authentication @PerService @CCC.Core @CCC.Core.CN03 @tlp-amber @tlp-red @Policy @NotTestable @object-storage @load-balancer
Given a cloud api for "{Instance}" in "api"42µs
Then no-op required21µs
Feature: CCC.Core.CN03.AR04 - API Authentication for Viewing
Scenario: API viewing requires credential and trust perimeter origin @PerService @CCC.Core @CCC.Core.CN03 @tlp-amber @tlp-red @Policy @NotTestable @object-storage @load-balancer
Given a cloud api for "{Instance}" in "api"38µs
Then no-op required21µs
Feature: CCC.Core.CN04.AR01 - Log Administrative Access Attempts
Scenario: Object storage admin logging compliance @PerService @CCC.Core @CCC.Core.CN04 @tlp-clear @tlp-green @tlp-amber @tlp-red @Policy @object-storage
When I attempt policy check "admin-logging" for control "CCC.Core.CN04" assessment requirement "AR01" for service "{ServiceType}" on resource "{ResourceName}" and provider "{Provider}"4s
Then "{result}" is true33µs
📎 Attachments:
policy-result-admin-logging.json
View JSON (7242 bytes)
{
  "policy_path": "/home/runner/work/ccc-cfi-compliance/ccc-cfi-compliance/testing/policy/CCC.Core/CCC.Core.CN04/AR01/admin-logging/azure.yaml",
  "name": "Azure Activity Log Configuration",
  "service_type": "all",
  "requirement_text": "The service MUST log all access and changes by administrators  (identity, timestamp, action, result).\n",
  "validity_score": 9,
  "validity_commentary": "Azure Activity Log automatically captures all administrative operations for all Azure resources. Activity Log is enabled by default at the subscription level and cannot be disabled. Strengths: - Activity Log is enabled by default and cannot be disabled - Logs include caller identity, timestamp, operation, and status - Covers all resources in the subscription Limitations: - Default retention is 90 days; longer retention requires export - Does not validate export to Log Analytics or Storage Account\n",
  "query_template": "az monitor activity-log list \\\n  --subscription ${AzureSubscriptionID} \\\n  --max-events 1 \\\n  --output json\n",
  "query_executed": "az monitor activity-log list \\\n  --subscription c1cedd8e-bf91-4d7d-a4cc-45700402a2a1 \\\n  --max-events 1 \\\n  --output json\n",
  "query_output": "[\n  {\n    \"authorization\": {\n      \"action\": \"Microsoft.Storage/storageAccounts/blobServices/containers/immutabilityPolicies/lock/action\",\n      \"scope\": \"/subscriptions/c1cedd8e-bf91-4d7d-a4cc-45700402a2a1/resourceGroups/cfi_test_20260410t090725z/providers/Microsoft.Storage/storageAccounts/stgcfi20260410t090725z/blobServices/default/containers/ccc-test-container-20260410t090725z/immutabilityPolicies/default\"\n    },\n    \"caller\": \"02d55131-c257-44f6-af4e-edb89ce735e7\",\n    \"category\": {\n      \"localizedValue\": \"Administrative\",\n      \"value\": \"Administrative\"\n    },\n    \"claims\": {\n      \"aio\": \"AWQAm/8bAAAAIbpv82d2/omBY+0MiHtOOYH8ESTtd4MblQCK4G5gu1ebtgA5GNgUOX4YY9K9i9tnoEUiT0/USsNu3F5IA68DXuJOVUXusX5BD9V++s44+rSzI7VNqapqubriErtcWjoS\",\n      \"appid\": \"fd1a537d-a7ae-4a92-bb37-8ddbef54a795\",\n      \"appidacr\": \"2\",\n      \"aud\": \"https://management.azure.com\",\n      \"exp\": \"1775815665\",\n      \"http://schemas.microsoft.com/identity/claims/identityprovider\": \"https://sts.windows.net/fa193ac0-9c06-4111-bf55-341e4db193d3/\",\n      \"http://schemas.microsoft.com/identity/claims/objectidentifier\": \"02d55131-c257-44f6-af4e-edb89ce735e7\",\n      \"http://schemas.microsoft.com/identity/claims/tenantid\": \"fa193ac0-9c06-4111-bf55-341e4db193d3\",\n      \"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier\": \"02d55131-c257-44f6-af4e-edb89ce735e7\",\n      \"iat\": \"1775811765\",\n      \"idtyp\": \"app\",\n      \"iss\": \"https://sts.windows.net/fa193ac0-9c06-4111-bf55-341e4db193d3/\",\n      \"nbf\": \"1775811765\",\n      \"rh\": \"1.AXUAwDoZ-gacEUG_VTQeTbGT00ZIf3kAutdPukPawfj2MBMAAAB1AA.\",\n      \"uti\": \"9v5K1mpshkeH1jtNG4UEAA\",\n      \"ver\": \"1.0\",\n      \"wids\": \"0997a1d0-0d1d-4acb-b408-d5ca73121e90\",\n      \"xms_act_fct\": \"3 9\",\n      \"xms_ftd\": \"wz35Yxuo8KAr5MM4R-QfPtOiePjr7T6bLKxuspxkVPsBdXNzb3V0aC1kc21z\",\n      \"xms_idrel\": \"7 6\",\n      \"xms_rd\": \"0.AXgAh_8KBQgCEgF1EhQIBxIQoLZOn9BLxESh-gTgBeFSJhIUCAkSEC159G0uOGtDqn2XbOd5Be8SFAgIEhBGSH95ALrXT7pD2sH49jATEhQICxIQWKeaQFZxfVdcsCtuOA6aNhoOCAoSCjE3NzU4MTIwNDcaBwgEEgNDUDE\",\n      \"xms_sub_fct\": \"3 9\",\n      \"xms_tcdt\": \"1763979378\"\n    },\n    \"correlationId\": \"e0e4ee86-0f3d-4d70-f397-5c209cd546c5\",\n    \"description\": \"\",\n    \"eventDataId\": \"f7e0fcca-4a19-4910-910b-49e1becd5928\",\n    \"eventName\": {\n      \"localizedValue\": \"End request\",\n      \"value\": \"EndRequest\"\n    },\n    \"eventTimestamp\": \"2026-04-10T09:09:34.1474255Z\",\n    \"httpRequest\": {\n      \"clientIpAddress\": \"172.208.127.244\",\n      \"clientRequestId\": \"\",\n      \"method\": \"POST\",\n      \"uri\": \"https://management.azure.com/subscriptions/c1cedd8e-bf91-4d7d-a4cc-45700402a2a1/resourceGroups/cfi_test_20260410t090725z/providers/Microsoft.Storage/storageAccounts/stgcfi20260410t090725z/blobServices/default/containers/ccc-test-container-20260410t090725z/immutabilityPolicies/default/lock?api-version=2025-06-01\"\n    },\n    \"id\": \"/subscriptions/c1cedd8e-bf91-4d7d-a4cc-45700402a2a1/resourceGroups/cfi_test_20260410t090725z/providers/Microsoft.Storage/storageAccounts/stgcfi20260410t090725z/blobServices/default/containers/ccc-test-container-20260410t090725z/immutabilityPolicies/default/events/f7e0fcca-4a19-4910-910b-49e1becd5928/ticks/639114089741474255\",\n    \"level\": \"Informational\",\n    \"operationId\": \"6257e772-9ac7-4e25-8580-dc1f329f9dc1\",\n    \"operationName\": {\n      \"localizedValue\": \"Lock blob container immutability policy\",\n      \"value\": \"Microsoft.Storage/storageAccounts/blobServices/containers/immutabilityPolicies/lock/action\"\n    },\n    \"properties\": {\n      \"entity\": \"/subscriptions/c1cedd8e-bf91-4d7d-a4cc-45700402a2a1/resourceGroups/cfi_test_20260410t090725z/providers/Microsoft.Storage/storageAccounts/stgcfi20260410t090725z/blobServices/default/containers/ccc-test-container-20260410t090725z/immutabilityPolicies/default\",\n      \"eventCategory\": \"Administrative\",\n      \"hierarchy\": \"fa193ac0-9c06-4111-bf55-341e4db193d3/c1cedd8e-bf91-4d7d-a4cc-45700402a2a1\",\n      \"message\": \"Microsoft.Storage/storageAccounts/blobServices/containers/immutabilityPolicies/lock/action\",\n      \"statusCode\": \"OK\"\n    },\n    \"resourceGroup\": \"cfi_test_20260410t090725z\",\n    \"resourceGroupName\": \"cfi_test_20260410t090725z\",\n    \"resourceId\": \"/subscriptions/c1cedd8e-bf91-4d7d-a4cc-45700402a2a1/resourceGroups/cfi_test_20260410t090725z/providers/Microsoft.Storage/storageAccounts/stgcfi20260410t090725z/blobServices/default/containers/ccc-test-container-20260410t090725z/immutabilityPolicies/default\",\n    \"resourceProviderName\": {\n      \"localizedValue\": \"Microsoft.Storage\",\n      \"value\": \"Microsoft.Storage\"\n    },\n    \"resourceType\": {\n      \"localizedValue\": \"Microsoft.Storage/storageAccounts/blobServices/containers/immutabilityPolicies\",\n      \"value\": \"Microsoft.Storage/storageAccounts/blobServices/containers/immutabilityPolicies\"\n    },\n    \"status\": {\n      \"localizedValue\": \"Succeeded\",\n      \"value\": \"Succeeded\"\n    },\n    \"subStatus\": {\n      \"localizedValue\": \"OK (HTTP Status Code: 200)\",\n      \"value\": \"OK\"\n    },\n    \"submissionTimestamp\": \"2026-04-10T09:11:10Z\",\n    \"subscriptionId\": \"c1cedd8e-bf91-4d7d-a4cc-45700402a2a1\",\n    \"tenantId\": \"fa193ac0-9c06-4111-bf55-341e4db193d3\"\n  }\n]\n",
  "passed": true,
  "rule_results": [
    {
      "jsonpath": "$[0].eventTimestamp",
      "expected_values": [],
      "validation_rule": "^\\d{4}-\\d{2}-\\d{2}T.*$",
      "description": "Azure Activity Log is enabled by default for all subscriptions. This check verifies Activity Log is accessible and contains events. Activity logs include identity (caller), timestamp, operation name, and result status for all administrative actions.\n",
      "actual_value": "[2026-04-10T09:09:34.1474255Z]",
      "passed": true
    }
  ]
}
Feature: CCC.Core.CN04.AR02 - Log Data Modification Attempts
Scenario: Object storage data modification logging compliance @PerService @CCC.Core @CCC.Core.CN04 @tlp-amber @tlp-red @Policy @object-storage
Given a cloud api for "{Instance}" in "api"28µs
When I attempt policy check "data-write-logging" for control "CCC.Core.CN04" assessment requirement "AR02" for service "{ServiceType}" on resource "{ResourceName}" and provider "{Provider}"1s
policy check failed: Azure Diagnostic Logging Write Configuration:
Then "{result}" is true25µs
📎 Attachments:
policy-result-data-write-logging.json
View JSON (1985 bytes)
{
  "policy_path": "/home/runner/work/ccc-cfi-compliance/ccc-cfi-compliance/testing/policy/CCC.Core/CCC.Core.CN04/AR02/data-write-logging/azure.yaml",
  "name": "Azure Diagnostic Logging Write Configuration",
  "service_type": "all",
  "requirement_text": "The service MUST log all data modification attempts  (identity, timestamp, action, result).\n",
  "validity_score": 7,
  "validity_commentary": "This query validates that Azure diagnostic settings are configured to log write operations. Strengths: - StorageWrite captures blob upload, delete, and copy operations - Logs include caller identity, timestamp, operation, and status - Separate from the storage account being logged Limitations: - Diagnostic settings must be explicitly configured (not default) - Requires destination (Log Analytics, Storage, or Event Hub) - High-volume accounts may generate significant log data\n",
  "query_template": "az monitor diagnostic-settings list \\\n  --resource \"/subscriptions/${AzureSubscriptionID}/resourceGroups/${AzureResourceGroup}/providers/Microsoft.Storage/storageAccounts/${AzureStorageAccount}/blobServices/default\" \\\n  --output json\n",
  "query_executed": "az monitor diagnostic-settings list \\\n  --resource \"/subscriptions/c1cedd8e-bf91-4d7d-a4cc-45700402a2a1/resourceGroups/cfi_test_20260410t090725z/providers/Microsoft.Storage/storageAccounts/stgcfi20260410t090725z/blobServices/default\" \\\n  --output json\n",
  "query_output": "[]\n",
  "passed": false,
  "rule_results": [
    {
      "jsonpath": "$.value[*].properties.logs[?(@.category==\"StorageWrite\")].enabled",
      "expected_values": [],
      "validation_rule": "^true$",
      "description": "Validates that StorageWrite logging is enabled for the blob service. StorageWrite captures blob creation, deletion, update, and copy operations with full caller identity and timestamp. If no diagnostic settings exist, this check will fail.\n",
      "actual_value": "[]",
      "passed": false
    }
  ]
}
Feature: CCC.Core.CN04.AR03 - Log Data Read Attempts
Scenario: Data read logging compliance @PerService @CCC.Core @CCC.Core.CN04 @tlp-red @Policy @object-storage @vpc
Given a cloud api for "{Instance}" in "api"63µs
When I attempt policy check "data-read-logging" for control "CCC.Core.CN04" assessment requirement "AR03" for service "{ServiceType}" on resource "{ResourceName}" and provider "{Provider}"1s
policy check failed: Azure Diagnostic Logging Read Configuration:
Then "{result}" is true22µs
📎 Attachments:
policy-result-data-read-logging.json
View JSON (1965 bytes)
{
  "policy_path": "/home/runner/work/ccc-cfi-compliance/ccc-cfi-compliance/testing/policy/CCC.Core/CCC.Core.CN04/AR03/data-read-logging/azure.yaml",
  "name": "Azure Diagnostic Logging Read Configuration",
  "service_type": "all",
  "requirement_text": "The service MUST log all data read attempts  (identity, timestamp, action, result).\n",
  "validity_score": 7,
  "validity_commentary": "This query validates that Azure diagnostic settings are configured to log read operations. Strengths: - StorageRead captures blob download and list operations - Logs include caller identity, timestamp, operation, and status - Separate from the storage account being logged Limitations: - Diagnostic settings must be explicitly configured (not default) - Requires destination (Log Analytics, Storage, or Event Hub) - High-volume accounts may generate very significant log data\n",
  "query_template": "az monitor diagnostic-settings list \\\n  --resource \"/subscriptions/${AzureSubscriptionID}/resourceGroups/${AzureResourceGroup}/providers/Microsoft.Storage/storageAccounts/${AzureStorageAccount}/blobServices/default\" \\\n  --output json\n",
  "query_executed": "az monitor diagnostic-settings list \\\n  --resource \"/subscriptions/c1cedd8e-bf91-4d7d-a4cc-45700402a2a1/resourceGroups/cfi_test_20260410t090725z/providers/Microsoft.Storage/storageAccounts/stgcfi20260410t090725z/blobServices/default\" \\\n  --output json\n",
  "query_output": "[]\n",
  "passed": false,
  "rule_results": [
    {
      "jsonpath": "$.value[*].properties.logs[?(@.category==\"StorageRead\")].enabled",
      "expected_values": [],
      "validation_rule": "^true$",
      "description": "Validates that StorageRead logging is enabled for the blob service. StorageRead captures blob download, metadata read, and list operations with full caller identity and timestamp. If no diagnostic settings exist, this check will fail.\n",
      "actual_value": "[]",
      "passed": false
    }
  ]
}
Feature: CCC.Core.CN05.AR01 - Block Unauthorized Data Modification
Scenario: Storage is not configured for public write access @PerService @CCC.Core @CCC.Core.CN05 @tlp-clear @tlp-green @tlp-amber @tlp-red @Policy @object-storage
Given a cloud api for "{Instance}" in "api"39µs
And I call "{api}" with "GetServiceAPI" using argument "object-storage"107µs
And I refer to "{result}" as "storage"20µs
And I call "{api}" with "GetServiceAPI" using argument "iam"61µs
And I refer to "{result}" as "iamService"20µs
When I attempt policy check "object-storage-block-public-write-access" for control "CCC.Core.CN05" assessment requirement "AR01" for service "{ServiceType}" on resource "{ResourceName}" and provider "{Provider}"1s
Then "{result}" is true34µs
📎 Attachments:
policy-result-object-storage-block-public-write-access.json
View JSON (5632 bytes)
{
  "policy_path": "/home/runner/work/ccc-cfi-compliance/ccc-cfi-compliance/testing/policy/CCC.Core/CCC.Core.CN05/AR01/object-storage-block-public-write-access/azure.yaml",
  "name": "Azure Storage Block Blob Public Access",
  "service_type": "object-storage",
  "requirement_text": "When an attempt is made to modify data on the service or a child resource, the service MUST block requests from unauthorized entities. Disabling blob public access ensures the storage account is not world-writable.\n",
  "validity_score": 8,
  "validity_commentary": "This query validates that Azure Storage has blob public access disabled. When allowBlobPublicAccess is false, anonymous access to blobs is not permitted, reducing the risk of unauthorized data modification. Strengths: - Storage account-level setting applies to all containers - Overrides any public access settings on individual containers - Aligns with CIS and Prowler benchmarks Limitations: - Does not validate shared key or SAS token restrictions - Behavioral testing (CN05-AR01) verifies unauthorized modification is blocked at runtime - Network rules (e.g. allow from VNet only) are checked separately\n",
  "query_template": "az storage account show \\\n  --name ${AzureStorageAccount} \\\n  --resource-group ${AzureResourceGroup} \\\n  --output json\n",
  "query_executed": "az storage account show \\\n  --name stgcfi20260410t090725z \\\n  --resource-group cfi_test_20260410t090725z \\\n  --output json\n",
  "query_output": "{\n  \"accessTier\": \"Hot\",\n  \"accountMigrationInProgress\": null,\n  \"allowBlobPublicAccess\": false,\n  \"allowCrossTenantReplication\": false,\n  \"allowSharedKeyAccess\": true,\n  \"allowedCopyScope\": null,\n  \"azureFilesIdentityBasedAuthentication\": null,\n  \"blobRestoreStatus\": null,\n  \"creationTime\": \"2026-04-10T09:08:26.607882+00:00\",\n  \"customDomain\": null,\n  \"defaultToOAuthAuthentication\": false,\n  \"dnsEndpointType\": \"Standard\",\n  \"dualStackEndpointPreference\": null,\n  \"enableExtendedGroups\": null,\n  \"enableHttpsTrafficOnly\": true,\n  \"enableNfsV3\": false,\n  \"encryption\": {\n    \"encryptionIdentity\": null,\n    \"keySource\": \"Microsoft.Storage\",\n    \"keyVaultProperties\": null,\n    \"requireInfrastructureEncryption\": null,\n    \"services\": {\n      \"blob\": {\n        \"enabled\": true,\n        \"keyType\": \"Account\",\n        \"lastEnabledTime\": \"2026-04-10T09:08:27.063268+00:00\"\n      },\n      \"file\": {\n        \"enabled\": true,\n        \"keyType\": \"Account\",\n        \"lastEnabledTime\": \"2026-04-10T09:08:27.063268+00:00\"\n      },\n      \"queue\": null,\n      \"table\": null\n    }\n  },\n  \"extendedLocation\": null,\n  \"failoverInProgress\": null,\n  \"geoPriorityReplicationStatus\": null,\n  \"geoReplicationStats\": null,\n  \"id\": \"/subscriptions/c1cedd8e-bf91-4d7d-a4cc-45700402a2a1/resourceGroups/cfi_test_20260410t090725z/providers/Microsoft.Storage/storageAccounts/stgcfi20260410t090725z\",\n  \"identity\": {\n    \"principalId\": null,\n    \"tenantId\": null,\n    \"type\": \"None\",\n    \"userAssignedIdentities\": null\n  },\n  \"immutableStorageWithVersioning\": null,\n  \"isHnsEnabled\": false,\n  \"isLocalUserEnabled\": false,\n  \"isSftpEnabled\": false,\n  \"isSkuConversionBlocked\": null,\n  \"keyCreationTime\": {\n    \"key1\": \"2026-04-10T09:08:27.057745+00:00\",\n    \"key2\": \"2026-04-10T09:08:27.057745+00:00\"\n  },\n  \"keyPolicy\": null,\n  \"kind\": \"StorageV2\",\n  \"largeFileSharesState\": null,\n  \"lastGeoFailoverTime\": null,\n  \"location\": \"eastus\",\n  \"minimumTlsVersion\": \"TLS1_2\",\n  \"name\": \"stgcfi20260410t090725z\",\n  \"networkRuleSet\": {\n    \"bypass\": \"AzureServices\",\n    \"defaultAction\": \"Allow\",\n    \"ipRules\": [],\n    \"ipv6Rules\": [],\n    \"resourceAccessRules\": [],\n    \"virtualNetworkRules\": []\n  },\n  \"placement\": null,\n  \"primaryEndpoints\": {\n    \"blob\": \"https://stgcfi20260410t090725z.blob.core.windows.net/\",\n    \"dfs\": \"https://stgcfi20260410t090725z.dfs.core.windows.net/\",\n    \"file\": \"https://stgcfi20260410t090725z.file.core.windows.net/\",\n    \"internetEndpoints\": null,\n    \"ipv6Endpoints\": null,\n    \"microsoftEndpoints\": null,\n    \"queue\": \"https://stgcfi20260410t090725z.queue.core.windows.net/\",\n    \"table\": \"https://stgcfi20260410t090725z.table.core.windows.net/\",\n    \"web\": \"https://stgcfi20260410t090725z.z13.web.core.windows.net/\"\n  },\n  \"primaryLocation\": \"eastus\",\n  \"privateEndpointConnections\": [],\n  \"provisioningState\": \"Succeeded\",\n  \"publicNetworkAccess\": \"Enabled\",\n  \"resourceGroup\": \"cfi_test_20260410t090725z\",\n  \"routingPreference\": null,\n  \"sasPolicy\": null,\n  \"secondaryEndpoints\": null,\n  \"secondaryLocation\": \"westus\",\n  \"sku\": {\n    \"name\": \"Standard_GRS\",\n    \"tier\": \"Standard\"\n  },\n  \"statusOfPrimary\": \"available\",\n  \"statusOfSecondary\": \"available\",\n  \"storageAccountSkuConversionStatus\": null,\n  \"tags\": {},\n  \"type\": \"Microsoft.Storage/storageAccounts\",\n  \"zones\": null\n}\n",
  "passed": true,
  "rule_results": [
    {
      "jsonpath": "$.allowBlobPublicAccess",
      "expected_values": [
        "false"
      ],
      "validation_rule": "^false$",
      "description": "Validates that blob public access is disabled at the storage account level. When false, anonymous access is not permitted regardless of container ACLs. This is a necessary precondition for blocking unauthorized data modification.\n",
      "actual_value": "[false]",
      "passed": true
    }
  ]
}
Feature: CCC.Core.CN05.AR02 - Block Unauthorized Administrative Access
Scenario: Unauthorized administrative access is blocked @PerService @CCC.Core @CCC.Core.CN05 @tlp-clear @tlp-green @tlp-amber @tlp-red @Policy @object-storage
Given a cloud api for "{Instance}" in "api"27µs
And I call "{api}" with "GetServiceAPI" using argument "object-storage"39µs
And I refer to "{result}" as "storage"27µs
And I call "{api}" with "GetServiceAPI" using argument "iam"31µs
And I refer to "{result}" as "iamService"25µs
Then no-op required23µs
Feature: CCC.Core.CN05.AR03 - Block Cross-Tenant Access
Scenario: Cross-tenant access is blocked without explicit allowlist @PerService @CCC.Core @CCC.Core.CN05 @tlp-clear @tlp-green @tlp-amber @tlp-red @Policy @object-storage
Given a cloud api for "{Instance}" in "api"25µs
When I attempt policy check "object-storage-cross-tenant-block" for control "CCC.Core.CN05" assessment requirement "AR03" for service "{ServiceType}" on resource "{ResourceName}" and provider "{Provider}"789ms
Then "{result}" is true32µs
📎 Attachments:
policy-result-object-storage-cross-tenant-block.json
View JSON (3130 bytes)
{
  "policy_path": "/home/runner/work/ccc-cfi-compliance/ccc-cfi-compliance/testing/policy/CCC.Core/CCC.Core.CN05/AR03/object-storage-cross-tenant-block/azure.yaml",
  "name": "Azure Storage Cross-Tenant Replication Block",
  "service_type": "object-storage",
  "requirement_text": "When administrative access or configuration change is attempted on the service or a child resource in a multi-tenant environment, the service MUST refuse requests across tenant boundaries unless the origin is explicitly included in a pre-approved allowlist.\n",
  "validity_score": 8,
  "validity_commentary": "This query validates Azure Storage object replication against permitted-destination-storage-accounts. When allowCrossTenantReplication is false, no cross-tenant replication is possible (pass). When true, all replication policy destinations must be in the permitted list. Strengths: - Directly queries replication policies and destination accounts - Uses provider-specific allowlist for precise control - Aligns with CIS and Prowler benchmarks Limitations: - Does not validate cross-tenant access via other mechanisms (e.g. SAS) - Destination format (name vs resource ID) must match Azure API response\n",
  "query_template": "ALLOW_XT=$(az storage account show \\\n  --name ${AzureStorageAccount} \\\n  --resource-group ${AzureResourceGroup} \\\n  --query \"properties.allowCrossTenantReplication\" --output tsv 2\u003e/dev/null || echo \"false\")\nif [ \"$ALLOW_XT\" != \"true\" ]; then\n  echo '{\"destinationAccounts\": []}'\nelse\n  az rest --method get \\\n    --url \"https://management.azure.com/subscriptions/${AzureSubscriptionID}/resourceGroups/${AzureResourceGroup}/providers/Microsoft.Storage/storageAccounts/${AzureStorageAccount}/objectReplicationPolicies?api-version=2025-06-01\" \\\n    --query \"{destinationAccounts: value[].properties.destinationAccount}\" -o json 2\u003e/dev/null || echo '{\"destinationAccounts\": []}'\nfi\n",
  "query_executed": "ALLOW_XT=$(az storage account show \\\n  --name stgcfi20260410t090725z \\\n  --resource-group cfi_test_20260410t090725z \\\n  --query \"properties.allowCrossTenantReplication\" --output tsv 2\u003e/dev/null || echo \"false\")\nif [ \"$ALLOW_XT\" != \"true\" ]; then\n  echo '{\"destinationAccounts\": []}'\nelse\n  az rest --method get \\\n    --url \"https://management.azure.com/subscriptions/c1cedd8e-bf91-4d7d-a4cc-45700402a2a1/resourceGroups/cfi_test_20260410t090725z/providers/Microsoft.Storage/storageAccounts/stgcfi20260410t090725z/objectReplicationPolicies?api-version=2025-06-01\" \\\n    --query \"{destinationAccounts: value[].properties.destinationAccount}\" -o json 2\u003e/dev/null || echo '{\"destinationAccounts\": []}'\nfi\n",
  "query_output": "{\"destinationAccounts\": []}\n",
  "passed": true,
  "rule_results": [
    {
      "jsonpath": "$.destinationAccounts",
      "expected_values": [],
      "validation_rule": "",
      "description": "Validates that when cross-tenant replication is enabled, all destination storage accounts are in permitted-destination-storage-accounts.\n",
      "actual_value": "[]",
      "passed": true
    }
  ]
}
Feature: CCC.Core.CN05.AR04 - Block Unauthorized External Data Requests
Scenario: External unauthorized data requests are blocked @PerService @CCC.Core @CCC.Core.CN05 @tlp-amber @tlp-red @Policy @object-storage
Given a cloud api for "{Instance}" in "api"38µs
When I attempt policy check "object-storage-block-public-read" for control "CCC.Core.CN05" assessment requirement "AR04" for service "{ServiceType}" on resource "{ResourceName}" and provider "{Provider}"1s
Then "{result}" is true37µs
📎 Attachments:
policy-result-object-storage-block-public-read.json
View JSON (2048 bytes)
{
  "policy_path": "/home/runner/work/ccc-cfi-compliance/ccc-cfi-compliance/testing/policy/CCC.Core/CCC.Core.CN05/AR04/object-storage-block-public-read/azure.yaml",
  "name": "Azure Storage Block External Unauthorized Data Requests",
  "service_type": "object-storage",
  "requirement_text": "Data requests from outside the trust perimeter MUST be blocked so that data exfiltration is prevented. Only authorised identities may read data.\n",
  "validity_score": 8,
  "validity_commentary": "This query validates that Azure Storage has blob public access disabled. When allowBlobPublicAccess is false, anonymous read access to blobs is not permitted, blocking external unauthorized data requests. Strengths: - Storage account-level setting applies to all containers and blobs - Overrides any public access settings on individual containers - Aligns with CIS and Prowler benchmarks Limitations: - Does not validate network rules (e.g. allow from VNet only) - Does not validate shared key or SAS token restrictions - Behavioral testing verifies unauthorized read is blocked at runtime\n",
  "query_template": "az storage account show \\\n  --name ${AzureStorageAccount} \\\n  --resource-group ${AzureResourceGroup} \\\n  --query \"{allowBlobPublicAccess:allowBlobPublicAccess}\" \\\n  --output json\n",
  "query_executed": "az storage account show \\\n  --name stgcfi20260410t090725z \\\n  --resource-group cfi_test_20260410t090725z \\\n  --query \"{allowBlobPublicAccess:allowBlobPublicAccess}\" \\\n  --output json\n",
  "query_output": "{\n  \"allowBlobPublicAccess\": false\n}\n",
  "passed": true,
  "rule_results": [
    {
      "jsonpath": "$.allowBlobPublicAccess",
      "expected_values": [
        "false"
      ],
      "validation_rule": "^false$",
      "description": "Validates that blob public access is disabled at the storage account level. When false, anonymous read access is not permitted, blocking external unauthorized data requests to containers and blobs.\n",
      "actual_value": "[false]",
      "passed": true
    }
  ]
}
Feature: CCC.Core.CN05.AR05 - Hide Service Existence from External Requests
Scenario: External requests do not reveal service existence @PerService @CCC.Core @CCC.Core.CN05 @tlp-red @Policy @NotTested @object-storage
Given a cloud api for "{Instance}" in "api"37µs
Then no-op required25µs
Feature: CCC.Core.CN05.AR06 - Block All Unauthorized Requests
Scenario: All unauthorized requests are blocked @PerService @CCC.Core @CCC.Core.CN05 @tlp-green @tlp-amber @tlp-red @Policy @Duplicate @object-storage
Given a cloud api for "{Instance}" in "api"35µs
And I call "{api}" with "GetServiceAPI" using argument "object-storage"64µs
And I refer to "{result}" as "storage"23µs
And I call "{api}" with "GetServiceAPI" using argument "iam"27µs
And I refer to "{result}" as "iamService"19µs
Then no-op required15µs
Feature: CCC.Core.CN06.AR01 - Resource Location Compliance
Scenario: Object storage region compliance @PerService @CCC.Core @CCC.Core.CN06 @tlp-green @tlp-amber @tlp-red @Policy @object-storage
Given a cloud api for "{Instance}" in "api"116µs
When I attempt policy check "object-storage-region" for control "CCC.Core.CN06" assessment requirement "AR01" for service "{ServiceType}" on resource "{ResourceName}" and provider "{Provider}"1s
Then "{result}" is true34µs
📎 Attachments:
policy-result-object-storage-region.json
View JSON (2029 bytes)
{
  "policy_path": "/home/runner/work/ccc-cfi-compliance/ccc-cfi-compliance/testing/policy/CCC.Core/CCC.Core.CN06/AR01/object-storage-region/azure.yaml",
  "name": "Azure Storage Account Region Compliance",
  "service_type": "object-storage",
  "requirement_text": "When the service is running, its region and availability zone MUST be included  in a list of explicitly trusted or approved locations within the trust perimeter.\n",
  "validity_score": 8,
  "validity_commentary": "This query validates that Azure Storage Accounts are deployed in approved regions. Storage accounts are regional resources, making region validation straightforward. Strengths: - Directly queries storage account location - Storage account region cannot be changed after creation - Easy to validate against an approved region list Limitations: - Approved regions must be defined externally (not in this query) - Does not validate geo-redundant storage secondary regions - Blob replication destinations are checked separately (CN10)\n",
  "query_template": "az storage account show \\\n  --name ${AzureStorageAccount} \\\n  --resource-group ${AzureResourceGroup} \\\n  --query \"{location: location}\" \\\n  --output json\n",
  "query_executed": "az storage account show \\\n  --name stgcfi20260410t090725z \\\n  --resource-group cfi_test_20260410t090725z \\\n  --query \"{location: location}\" \\\n  --output json\n",
  "query_output": "{\n  \"location\": \"eastus\"\n}\n",
  "passed": true,
  "rule_results": [
    {
      "jsonpath": "$.location",
      "expected_values": [
        "northeurope",
        "eastus",
        "eastus2",
        "westus",
        "westus2",
        "westeurope"
      ],
      "validation_rule": "^(eastus|eastus2|westus|westus2|westeurope|northeurope)$",
      "description": "Validates that the storage account is located in an approved region. The expected_values list should be customized to match your organization's approved Azure regions.\n",
      "actual_value": "[eastus]",
      "passed": true
    }
  ]
}
Feature: CCC.Core.CN06.AR02 - Child Resource Location Compliance
Scenario: Child resource region compliance @PerService @CCC.Core @CCC.Core.CN06 @tlp-clear @tlp-green @tlp-amber @tlp-red @Policy @NotTestable @object-storage
Given a cloud api for "{Instance}" in "api"34µs
Then no-op required25µs
Feature: CCC.Core.CN07.AR01 - Publish Enumeration Activity Events
Scenario: Enumeration activities publish events to monitored channels @PerService @CCC.Core @CCC.Core.CN07 @tlp-amber @tlp-red @Policy @object-storage
Given a cloud api for "{Instance}" in "api"38µs
When I attempt policy check "enumeration-monitoring-policy" for control "CCC.Core.CN07" assessment requirement "AR01" for service "{ServiceType}" on resource "{ResourceName}" and provider "{Provider}"2s
policy check failed: Azure Storage Enumeration Monitoring Policy Check:
Then "{result}" is true23µs
📎 Attachments:
policy-result-enumeration-monitoring-policy.json
View JSON (1468 bytes)
{
  "policy_path": "/home/runner/work/ccc-cfi-compliance/ccc-cfi-compliance/testing/policy/CCC.Core/CCC.Core.CN07/AR01/enumeration-monitoring-policy/azure.yaml",
  "name": "Azure Storage Enumeration Monitoring Policy Check",
  "service_type": "object-storage",
  "requirement_text": "Enumeration activities must be monitored and generate events that can be sent to monitored channels.\n",
  "validity_score": 9,
  "validity_commentary": "This query validates monitoring configuration at the Azure Storage blob service level.\n",
  "query_template": "az monitor diagnostic-settings list \\\n  --resource \"/subscriptions/${AzureSubscriptionID}/resourceGroups/${AzureResourceGroup}/providers/Microsoft.Storage/storageAccounts/${AzureStorageAccount}/blobServices/default\" \\\n  --output json\n",
  "query_executed": "az monitor diagnostic-settings list \\\n  --resource \"/subscriptions/c1cedd8e-bf91-4d7d-a4cc-45700402a2a1/resourceGroups/cfi_test_20260410t090725z/providers/Microsoft.Storage/storageAccounts/stgcfi20260410t090725z/blobServices/default\" \\\n  --output json\n",
  "query_output": "[]\n",
  "passed": false,
  "rule_results": [
    {
      "jsonpath": "$.value[*].properties.logs[?(@.categoryGroup==\"audit\")].enabled",
      "expected_values": [],
      "validation_rule": "^true$",
      "description": "Verifies that diagnostic settings are configured to audit enumeration activities.\n",
      "actual_value": "[]",
      "passed": false
    }
  ]
}
Feature: CCC.Core.CN07.AR02 - Log Enumeration Activities
Scenario: Enumeration activities are logged @PerService @CCC.Core @CCC.Core.CN07 @tlp-clear @tlp-green @tlp-amber @tlp-red @Policy @object-storage
Given a cloud api for "{Instance}" in "api"48µs
When I attempt policy check "enumeration-logging-policy" for control "CCC.Core.CN07" assessment requirement "AR02" for service "{ServiceType}" on resource "{ResourceName}" and provider "{Provider}"2s
policy check failed: Azure Storage Enumeration Logging Policy Check:
Then "{result}" is true30µs
📎 Attachments:
policy-result-enumeration-logging-policy.json
View JSON (1393 bytes)
{
  "policy_path": "/home/runner/work/ccc-cfi-compliance/ccc-cfi-compliance/testing/policy/CCC.Core/CCC.Core.CN07/AR02/enumeration-logging-policy/azure.yaml",
  "name": "Azure Storage Enumeration Logging Policy Check",
  "service_type": "object-storage",
  "requirement_text": "Enumeration activities must be logged.\n",
  "validity_score": 9,
  "validity_commentary": "This query validates that diagnostic settings are configured for the blob service.\n",
  "query_template": "az monitor diagnostic-settings list \\\n  --resource \"/subscriptions/${AzureSubscriptionID}/resourceGroups/${AzureResourceGroup}/providers/Microsoft.Storage/storageAccounts/${AzureStorageAccount}/blobServices/default\" \\\n  --output json\n",
  "query_executed": "az monitor diagnostic-settings list \\\n  --resource \"/subscriptions/c1cedd8e-bf91-4d7d-a4cc-45700402a2a1/resourceGroups/cfi_test_20260410t090725z/providers/Microsoft.Storage/storageAccounts/stgcfi20260410t090725z/blobServices/default\" \\\n  --output json\n",
  "query_output": "[]\n",
  "passed": false,
  "rule_results": [
    {
      "jsonpath": "$",
      "expected_values": [],
      "validation_rule": "(category|categoryGroup).*enabled.*true|enabled.*true.*(category|categoryGroup)",
      "description": "Verifies that at least one log category or category group is enabled.\n",
      "actual_value": "[]",
      "passed": false
    }
  ]
}
Feature: CCC.Core.CN08.AR01 - Data Replication and Redundancy
Scenario: Object storage replication compliance @PerService @CCC.Core @CCC.Core.CN08 @tlp-green @tlp-amber @tlp-red @Policy @object-storage
Given a cloud api for "{Instance}" in "api"47µs
And I call "{api}" with "GetServiceAPI" using argument "object-storage"42µs
And I refer to "{result}" as "storage"23µs
When I attempt policy check "object-storage-replication" for control "CCC.Core.CN08" assessment requirement "AR01" for service "{ServiceType}" on resource "{ResourceName}" and provider "{Provider}"1s
Then "{result}" is true39µs
📎 Attachments:
policy-result-object-storage-replication.json
View JSON (3075 bytes)
{
  "policy_path": "/home/runner/work/ccc-cfi-compliance/ccc-cfi-compliance/testing/policy/CCC.Core/CCC.Core.CN08/AR01/object-storage-replication/azure.yaml",
  "name": "Azure Storage Geo-Redundant Replication Configuration",
  "service_type": "object-storage",
  "requirement_text": "When data is created or modified, the data MUST have a complete and recoverable  duplicate that is stored in a physically separate data center.\n",
  "validity_score": 8,
  "validity_commentary": "This query validates Azure Storage geo-redundant replication configuration. Azure Storage provides automatic geo-replication through GRS, GZRS, or RA-GRS. Strengths: - Replication is automatic and synchronous/asynchronous - Secondary region is automatically selected by Azure (paired region) - RA-GRS/RA-GZRS provides read access to secondary Limitations: - Does not support custom destination region (uses Azure paired regions) - Failover must be manually initiated or use account failover - Object replication for cross-region copies requires separate configuration - LRS and ZRS do not provide geographic redundancy\n",
  "query_template": "az storage account show \\\n  --name ${AzureStorageAccount} \\\n  --resource-group ${AzureResourceGroup} \\\n  --query \"{sku: sku.name, primaryLocation: primaryLocation, secondaryLocation: secondaryLocation, statusOfSecondary: statusOfSecondary}\" \\\n  --output json\n",
  "query_executed": "az storage account show \\\n  --name stgcfi20260410t090725z \\\n  --resource-group cfi_test_20260410t090725z \\\n  --query \"{sku: sku.name, primaryLocation: primaryLocation, secondaryLocation: secondaryLocation, statusOfSecondary: statusOfSecondary}\" \\\n  --output json\n",
  "query_output": "{\n  \"primaryLocation\": \"eastus\",\n  \"secondaryLocation\": \"westus\",\n  \"sku\": \"Standard_GRS\",\n  \"statusOfSecondary\": \"available\"\n}\n",
  "passed": true,
  "rule_results": [
    {
      "jsonpath": "$.sku",
      "expected_values": [
        "Standard_GRS",
        "Standard_GZRS",
        "Standard_RAGRS",
        "Standard_RAGZRS"
      ],
      "validation_rule": "^Standard_(GRS|GZRS|RAGRS|RAGZRS)$",
      "description": "Validates that the storage account uses a geo-redundant SKU. GRS/GZRS replicate to a secondary region. RA- variants provide read access. LRS and ZRS do not satisfy cross-region replication requirements.\n",
      "actual_value": "[Standard_GRS]",
      "passed": true
    },
    {
      "jsonpath": "$.secondaryLocation",
      "expected_values": [],
      "validation_rule": "^[a-z]+$",
      "description": "Validates that a secondary location is configured for geo-replication. This is automatically set based on Azure paired regions.\n",
      "actual_value": "[westus]",
      "passed": true
    },
    {
      "jsonpath": "$.statusOfSecondary",
      "expected_values": [
        "available"
      ],
      "validation_rule": "^available$",
      "description": "Verifies the secondary region is available and replication is healthy.\n",
      "actual_value": "[available]",
      "passed": true
    }
  ]
}
Feature: CCC.Core.CN08.AR02 - Replication Status Visibility
Scenario: Object storage replication status is visible @PerService @CCC.Core @CCC.Core.CN08 @tlp-green @tlp-amber @tlp-red @Policy @object-storage
Given a cloud api for "{Instance}" in "api"30µs
And I call "{api}" with "GetServiceAPI" using argument "object-storage"42µs
And I refer to "{result}" as "storage"22µs
When I attempt policy check "object-storage-replication-status" for control "CCC.Core.CN08" assessment requirement "AR02" for service "{ServiceType}" on resource "{ResourceName}" and provider "{Provider}"1s
Then "{result}" is true66µs
📎 Attachments:
policy-result-object-storage-replication-status.json
View JSON (2624 bytes)
{
  "policy_path": "/home/runner/work/ccc-cfi-compliance/ccc-cfi-compliance/testing/policy/CCC.Core/CCC.Core.CN08/AR02/object-storage-replication-status/azure.yaml",
  "name": "Azure Storage Replication Status Visibility",
  "service_type": "object-storage",
  "requirement_text": "When data is replicated into a second location, the service MUST be able to accurately represent the replication locations, replication status, and data synchronization status.\n",
  "validity_score": 8,
  "validity_commentary": "This query validates that Azure Storage geo-replication status is visible. Azure Storage provides automatic geo-replication with status reporting. Strengths: - Secondary location is visible in account properties - Replication status is automatically tracked - Last sync time available for RA-GRS/RA-GZRS Limitations: - Replication lag is not guaranteed - Detailed sync metrics require Azure Monitor\n",
  "query_template": "az storage account show \\\n  --name ${AzureStorageAccount} \\\n  --resource-group ${AzureResourceGroup} \\\n  --query \"{sku: sku.name, primaryLocation: primaryLocation, secondaryLocation: secondaryLocation, statusOfPrimary: statusOfPrimary, statusOfSecondary: statusOfSecondary, lastGeoFailoverTime: geoReplicationStats.lastSyncTime}\" \\\n  --output json\n",
  "query_executed": "az storage account show \\\n  --name stgcfi20260410t090725z \\\n  --resource-group cfi_test_20260410t090725z \\\n  --query \"{sku: sku.name, primaryLocation: primaryLocation, secondaryLocation: secondaryLocation, statusOfPrimary: statusOfPrimary, statusOfSecondary: statusOfSecondary, lastGeoFailoverTime: geoReplicationStats.lastSyncTime}\" \\\n  --output json\n",
  "query_output": "{\n  \"lastGeoFailoverTime\": null,\n  \"primaryLocation\": \"eastus\",\n  \"secondaryLocation\": \"westus\",\n  \"sku\": \"Standard_GRS\",\n  \"statusOfPrimary\": \"available\",\n  \"statusOfSecondary\": \"available\"\n}\n",
  "passed": true,
  "rule_results": [
    {
      "jsonpath": "$.secondaryLocation",
      "expected_values": [],
      "validation_rule": "^[a-z]+$",
      "description": "Validates that a secondary location is configured and visible, indicating geo-replication is active.\n",
      "actual_value": "[westus]",
      "passed": true
    },
    {
      "jsonpath": "$.statusOfSecondary",
      "expected_values": [
        "available"
      ],
      "validation_rule": "^(available|unavailable)$",
      "description": "Validates that the secondary region status is reported, providing visibility into replication health.\n",
      "actual_value": "[available]",
      "passed": true
    }
  ]
}
Feature: CCC.Core.CN09.AR01 - Access Logging Separation
Scenario: Object storage access logging compliance @PerService @CCC.Core @CCC.Core.CN09 @tlp-green @tlp-amber @tlp-red @Policy @object-storage
Given a cloud api for "{Instance}" in "api"53µs
When I attempt policy check "object-storage-access-logging" for control "CCC.Core.CN09" assessment requirement "AR01" for service "{ServiceType}" on resource "{ResourceName}" and provider "{Provider}"2s
policy check failed: Azure Storage Account Diagnostic Logging Configuration:
Then "{result}" is true24µs
📎 Attachments:
policy-result-object-storage-access-logging.json
View JSON (2769 bytes)
{
  "policy_path": "/home/runner/work/ccc-cfi-compliance/ccc-cfi-compliance/testing/policy/CCC.Core/CCC.Core.CN09/AR01/object-storage-access-logging/azure.yaml",
  "name": "Azure Storage Account Diagnostic Logging Configuration",
  "service_type": "object-storage",
  "requirement_text": "When the service is operational, its logs and any child resource logs MUST NOT  be accessible from the resource they record access to.\n",
  "validity_score": 7,
  "validity_commentary": "This query validates that Azure Storage blob diagnostic settings are configured. Azure Storage logs can be sent to Log Analytics, Storage Account, or Event Hub. Strengths: - Validates that diagnostic logging is enabled - Azure Monitor provides centralized logging separate from source - Supports multiple logging destinations Limitations: - Does not validate the specific logging destination - Does not verify Log Analytics workspace configuration - Classic storage analytics logging is deprecated in favor of Azure Monitor - Blob read/write/delete logs require specific category configuration\n",
  "query_template": "az monitor diagnostic-settings list \\\n  --resource \"/subscriptions/${AzureSubscriptionID}/resourceGroups/${AzureResourceGroup}/providers/Microsoft.Storage/storageAccounts/${AzureStorageAccount}/blobServices/default\" \\\n  --output json\n",
  "query_executed": "az monitor diagnostic-settings list \\\n  --resource \"/subscriptions/c1cedd8e-bf91-4d7d-a4cc-45700402a2a1/resourceGroups/cfi_test_20260410t090725z/providers/Microsoft.Storage/storageAccounts/stgcfi20260410t090725z/blobServices/default\" \\\n  --output json\n",
  "query_output": "[]\n",
  "passed": false,
  "rule_results": [
    {
      "jsonpath": "$.value[0].name",
      "expected_values": [],
      "validation_rule": "^.+$",
      "description": "Validates that at least one diagnostic setting exists for the blob service. The presence of any diagnostic setting indicates logging is configured.\n",
      "actual_value": "",
      "passed": false,
      "error": "JSONPath query failed $.value[0].name: could not select value, invalid key: expected number but got value (string)"
    },
    {
      "jsonpath": "$",
      "expected_values": [],
      "validation_rule": "(StorageRead.*StorageWrite.*StorageDelete|StorageRead.*StorageDelete.*StorageWrite|StorageWrite.*StorageRead.*StorageDelete|StorageWrite.*StorageDelete.*StorageRead|StorageDelete.*StorageRead.*StorageWrite|StorageDelete.*StorageWrite.*StorageRead)|categoryGroup[^\"]*audit",
      "description": "Validates read/write/delete logging: either individual categories (StorageRead, StorageWrite, StorageDelete) all enabled, or categoryGroup audit (which replaces them).\n",
      "actual_value": "[]",
      "passed": false
    }
  ]
}
Feature: CCC.Core.CN09.AR02 - Logs Cannot Be Disabled
Scenario: Disabling logs requires disabling the resource @PerService @CCC.Core @CCC.Core.CN09 @tlp-clear @tlp-green @tlp-amber @tlp-red @Policy @NotTestable @object-storage
Given a cloud api for "{Instance}" in "api"89µs
Then no-op required55µs
Feature: CCC.Core.CN09.AR03 - Log Redirection Requires Service Halt
Scenario: Redirecting logs requires halting the resource @PerService @CCC.Core @CCC.Core.CN09 @tlp-amber @tlp-red @Policy @NotTestable @object-storage
Given a cloud api for "{Instance}" in "api"32µs
Then no-op required22µs
Feature: CCC.Core.CN10.AR01 - Replication Destination Trust
Scenario: Object storage replication destination compliance @PerService @CCC.Core @CCC.Core.CN10 @tlp-green @tlp-amber @tlp-red @Policy @object-storage
Given a cloud api for "{Instance}" in "api"34µs
When I attempt policy check "object-storage-replication-destination" for control "CCC.Core.CN10" assessment requirement "AR01" for service "{ServiceType}" on resource "{ResourceName}" and provider "{Provider}"1s
Then "{result}" is true38µs
📎 Attachments:
policy-result-object-storage-replication-destination.json
View JSON (2784 bytes)
{
  "policy_path": "/home/runner/work/ccc-cfi-compliance/ccc-cfi-compliance/testing/policy/CCC.Core/CCC.Core.CN10/AR01/object-storage-replication-destination/azure.yaml",
  "name": "Azure Storage Replication Destination Region Validation",
  "service_type": "object-storage",
  "requirement_text": "When data is replicated, the service MUST ensure that replication only occurs  to destinations that are explicitly included within the defined trust perimeter.\n",
  "validity_score": 7,
  "validity_commentary": "This query validates that Azure Storage replication destinations are within approved Azure paired regions. Strengths: - Azure paired regions are pre-defined and documented - Secondary region is automatically set based on primary - Can validate against approved region pairs Limitations: - Azure does not allow custom secondary region selection for GRS - Object replication policies for custom destinations need separate checks - Cross-subscription replication requires additional trust validation\n",
  "query_template": "az storage account show \\\n  --name ${AzureStorageAccount} \\\n  --resource-group ${AzureResourceGroup} \\\n  --query \"{primaryLocation: primaryLocation, secondaryLocation: secondaryLocation, sku: sku.name}\" \\\n  --output json\n",
  "query_executed": "az storage account show \\\n  --name stgcfi20260410t090725z \\\n  --resource-group cfi_test_20260410t090725z \\\n  --query \"{primaryLocation: primaryLocation, secondaryLocation: secondaryLocation, sku: sku.name}\" \\\n  --output json\n",
  "query_output": "{\n  \"primaryLocation\": \"eastus\",\n  \"secondaryLocation\": \"westus\",\n  \"sku\": \"Standard_GRS\"\n}\n",
  "passed": true,
  "rule_results": [
    {
      "jsonpath": "$.secondaryLocation",
      "expected_values": [
        "westus",
        "westus2",
        "eastus",
        "eastus2",
        "northeurope",
        "westeurope"
      ],
      "validation_rule": "^(westus|westus2|eastus|eastus2|northeurope|westeurope)$",
      "description": "Validates that the secondary replication location is within the approved list of Azure regions in the trust perimeter. Azure paired regions are automatically determined but should be verified against policy.\n",
      "actual_value": "[westus]",
      "passed": true
    },
    {
      "jsonpath": "$.primaryLocation",
      "expected_values": [
        "eastus",
        "eastus2",
        "westus",
        "westus2",
        "westeurope",
        "northeurope"
      ],
      "validation_rule": "^(eastus|eastus2|westus|westus2|westeurope|northeurope)$",
      "description": "Validates the primary location is in an approved region. The secondary location is determined by Azure based on region pairing.\n",
      "actual_value": "[eastus]",
      "passed": true
    }
  ]
}
Feature: CCC.ObjStor.CN01.AR01
Scenario: Test policy for bucket access control @PerService @object-storage @CCC.ObjStor @tlp-amber @tlp-red @CCC.ObjStor.CN01 @Policy
Given a cloud api for "{Instance}" in "api"56µs
And I call "{api}" with "GetServiceAPI" using argument "object-storage"55µs
And I refer to "{result}" as "storage"17µs
And I call "{api}" with "GetServiceAPI" using argument "iam"33µs
And I refer to "{result}" as "iamService"16µs
When I attempt policy check "no-public-access" for control "CCC.ObjStor.CN01" assessment requirement "AR01" for service "{ServiceType}" on resource "{ResourceName}" and provider "{Provider}"1s
Then "{result}" is true34µs
📎 Attachments:
policy-result-no-public-access.json
View JSON (1685 bytes)
{
  "policy_path": "/home/runner/work/ccc-cfi-compliance/ccc-cfi-compliance/testing/policy/CCC.ObjStor/CCC.ObjStor.CN01/AR01/no-public-access/azure.yaml",
  "name": "Azure Blob Block Public Access Check",
  "service_type": "object-storage",
  "requirement_text": "The service MUST enforce access control so that only authorised identities can read, list, write, or create objects and buckets.\n",
  "validity_score": 9,
  "validity_commentary": "This query validates that public blob access is disabled at the Azure storage account level, preventing anonymous read access to containers and blobs. Strengths: - Checks account-level public access configuration - Ensures all access requires Azure AD authentication or SAS tokens Limitations: - Does not audit individual RBAC role assignments\n",
  "query_template": "az storage account show \\\n  --name ${AzureStorageAccount} \\\n  --resource-group ${AzureResourceGroup} \\\n  --query \"{allowBlobPublicAccess:allowBlobPublicAccess}\" \\\n  --output json\n",
  "query_executed": "az storage account show \\\n  --name stgcfi20260410t090725z \\\n  --resource-group cfi_test_20260410t090725z \\\n  --query \"{allowBlobPublicAccess:allowBlobPublicAccess}\" \\\n  --output json\n",
  "query_output": "{\n  \"allowBlobPublicAccess\": false\n}\n",
  "passed": true,
  "rule_results": [
    {
      "jsonpath": "$.allowBlobPublicAccess",
      "expected_values": [
        "false"
      ],
      "validation_rule": "^false$",
      "description": "Verifies that public blob access is disabled at the account level, requiring authenticated access to all containers and blobs.\n",
      "actual_value": "[false]",
      "passed": true
    }
  ]
}
Feature: CCC.ObjStor.CN01.AR02
Scenario: All unauthorized requests are blocked @PerService @object-storage @CCC.ObjStor @tlp-amber @tlp-red @CCC.ObjStor.CN01 @Policy
Given a cloud api for "{Instance}" in "api"34µs
And I call "{api}" with "GetServiceAPI" using argument "object-storage"38µs
And I refer to "{result}" as "storage"20µs
And I call "{api}" with "GetServiceAPI" using argument "iam"25µs
And I refer to "{result}" as "iamService"20µs
And I call "{storage}" with "CreateObject" using arguments "{ResourceName}", "test-object={Timestamp}.txt", and "test content"1m1s
And "{result}" is not an error35µs
When I attempt policy check "object-storage-no-public-principals" for control "CCC.ObjStor.CN01" assessment requirement "AR02" for service "{ServiceType}" on resource "{ResourceName}" and provider "{Provider}"1s
Then "{result}" is true39µs
📎 Attachments:
policy-result-object-storage-no-public-principals.json
View JSON (2041 bytes)
{
  "policy_path": "/home/runner/work/ccc-cfi-compliance/ccc-cfi-compliance/testing/policy/CCC.ObjStor/CCC.ObjStor.CN01/AR02/object-storage-no-public-principals/azure.yaml",
  "name": "Azure Storage RBAC in Use",
  "service_type": "object-storage",
  "requirement_text": "All unauthorized requests MUST be blocked. Access MUST be controlled by RBAC.\n",
  "validity_score": 7,
  "validity_commentary": "ObjStor.CN01.AR01 already validates no-public-access at the account level. This check validates that RBAC role assignments exist on the storage account, proving access control is role-based rather than anonymous or key-based. Strengths: - Confirms RBAC is configured for the storage account - Role assignments scope access to specific identities Limitations: - Does not validate least-privilege role assignments - Behavioral testing verifies unauthorized access is blocked at runtime\n",
  "query_template": "SCOPE=\"/subscriptions/${AzureSubscriptionID}/resourceGroups/${AzureResourceGroup}/providers/Microsoft.Storage/storageAccounts/${AzureStorageAccount}\"\nCOUNT=$(az role assignment list --scope \"$SCOPE\" --query \"length(@)\" --output tsv 2\u003e/dev/null || echo \"0\")\necho \"{\\\"rbacInUse\\\": $COUNT}\"\n",
  "query_executed": "SCOPE=\"/subscriptions/c1cedd8e-bf91-4d7d-a4cc-45700402a2a1/resourceGroups/cfi_test_20260410t090725z/providers/Microsoft.Storage/storageAccounts/stgcfi20260410t090725z\"\nCOUNT=$(az role assignment list --scope \"$SCOPE\" --query \"length(@)\" --output tsv 2\u003e/dev/null || echo \"0\")\necho \"{\\\"rbacInUse\\\": $COUNT}\"\n",
  "query_output": "{\"rbacInUse\": 1}\n",
  "passed": true,
  "rule_results": [
    {
      "jsonpath": "$.rbacInUse",
      "expected_values": [],
      "validation_rule": "^[1-9][0-9]*$",
      "description": "Validates that at least one RBAC role assignment exists on the storage account. RBAC is the required access control mechanism; no assignments indicates access may not be properly scoped.\n",
      "actual_value": "[1]",
      "passed": true
    }
  ]
}
Feature: CCC.ObjStor.CN01.AR03
Scenario: All unauthorized requests are blocked @PerService @object-storage @CCC.ObjStor @tlp-clear @tlp-green @tlp-amber @tlp-red @CCC.ObjStor.CN01 @Policy
Given a cloud api for "{Instance}" in "api"34µs
And I call "{api}" with "GetServiceAPI" using argument "object-storage"45µs
And I refer to "{result}" as "storage"26µs
And I call "{api}" with "GetServiceAPI" using argument "iam"32µs
And I refer to "{result}" as "iamService"24µs
When I attempt policy check "object-storage-no-public-principals" for control "CCC.ObjStor.CN01" assessment requirement "AR03" for service "{ServiceType}" on resource "{ResourceName}" and provider "{Provider}"1s
Then "{result}" is true35µs
📎 Attachments:
policy-result-object-storage-no-public-principals.json
View JSON (2045 bytes)
{
  "policy_path": "/home/runner/work/ccc-cfi-compliance/ccc-cfi-compliance/testing/policy/CCC.ObjStor/CCC.ObjStor.CN01/AR03/object-storage-no-public-principals/azure.yaml",
  "name": "Azure Storage RBAC in Use",
  "service_type": "object-storage",
  "requirement_text": "All unauthorized requests MUST be blocked. Access MUST be controlled by RBAC.\n",
  "validity_score": 7,
  "validity_commentary": "ObjStor.CN01.AR01/AR02 already validate no-public-access at the account level. This check validates that RBAC role assignments exist on the storage account, proving access control is role-based rather than anonymous or key-based. Strengths: - Confirms RBAC is configured for the storage account - Role assignments scope access to specific identities Limitations: - Does not validate least-privilege role assignments - Behavioral testing verifies unauthorized access is blocked at runtime\n",
  "query_template": "SCOPE=\"/subscriptions/${AzureSubscriptionID}/resourceGroups/${AzureResourceGroup}/providers/Microsoft.Storage/storageAccounts/${AzureStorageAccount}\"\nCOUNT=$(az role assignment list --scope \"$SCOPE\" --query \"length(@)\" --output tsv 2\u003e/dev/null || echo \"0\")\necho \"{\\\"rbacInUse\\\": $COUNT}\"\n",
  "query_executed": "SCOPE=\"/subscriptions/c1cedd8e-bf91-4d7d-a4cc-45700402a2a1/resourceGroups/cfi_test_20260410t090725z/providers/Microsoft.Storage/storageAccounts/stgcfi20260410t090725z\"\nCOUNT=$(az role assignment list --scope \"$SCOPE\" --query \"length(@)\" --output tsv 2\u003e/dev/null || echo \"0\")\necho \"{\\\"rbacInUse\\\": $COUNT}\"\n",
  "query_output": "{\"rbacInUse\": 1}\n",
  "passed": true,
  "rule_results": [
    {
      "jsonpath": "$.rbacInUse",
      "expected_values": [],
      "validation_rule": "^[1-9][0-9]*$",
      "description": "Validates that at least one RBAC role assignment exists on the storage account. RBAC is the required access control mechanism; no assignments indicates access may not be properly scoped.\n",
      "actual_value": "[1]",
      "passed": true
    }
  ]
}
Feature: CCC.ObjStor.CN01.AR04
Scenario: All unauthorized requests are blocked @PerService @object-storage @CCC.ObjStor @tlp-clear @tlp-green @tlp-amber @tlp-red @CCC.ObjStor.CN01 @Policy
Given a cloud api for "{Instance}" in "api"31µs
And I call "{api}" with "GetServiceAPI" using argument "object-storage"61µs
And I refer to "{result}" as "storage"20µs
And "{result}" is not an error29µs
And I call "{api}" with "GetServiceAPI" using argument "iam"29µs
And I refer to "{result}" as "iamService"23µs
And "{result}" is not an error16µs
When I attempt policy check "object-storage-no-public-principals" for control "CCC.ObjStor.CN01" assessment requirement "AR04" for service "{ServiceType}" on resource "{ResourceName}" and provider "{Provider}"1s
Then "{result}" is true32µs
📎 Attachments:
policy-result-object-storage-no-public-principals.json
View JSON (2045 bytes)
{
  "policy_path": "/home/runner/work/ccc-cfi-compliance/ccc-cfi-compliance/testing/policy/CCC.ObjStor/CCC.ObjStor.CN01/AR04/object-storage-no-public-principals/azure.yaml",
  "name": "Azure Storage RBAC in Use",
  "service_type": "object-storage",
  "requirement_text": "All unauthorized requests MUST be blocked. Access MUST be controlled by RBAC.\n",
  "validity_score": 7,
  "validity_commentary": "ObjStor.CN01.AR01/AR02 already validate no-public-access at the account level. This check validates that RBAC role assignments exist on the storage account, proving access control is role-based rather than anonymous or key-based. Strengths: - Confirms RBAC is configured for the storage account - Role assignments scope access to specific identities Limitations: - Does not validate least-privilege role assignments - Behavioral testing verifies unauthorized access is blocked at runtime\n",
  "query_template": "SCOPE=\"/subscriptions/${AzureSubscriptionID}/resourceGroups/${AzureResourceGroup}/providers/Microsoft.Storage/storageAccounts/${AzureStorageAccount}\"\nCOUNT=$(az role assignment list --scope \"$SCOPE\" --query \"length(@)\" --output tsv 2\u003e/dev/null || echo \"0\")\necho \"{\\\"rbacInUse\\\": $COUNT}\"\n",
  "query_executed": "SCOPE=\"/subscriptions/c1cedd8e-bf91-4d7d-a4cc-45700402a2a1/resourceGroups/cfi_test_20260410t090725z/providers/Microsoft.Storage/storageAccounts/stgcfi20260410t090725z\"\nCOUNT=$(az role assignment list --scope \"$SCOPE\" --query \"length(@)\" --output tsv 2\u003e/dev/null || echo \"0\")\necho \"{\\\"rbacInUse\\\": $COUNT}\"\n",
  "query_output": "{\"rbacInUse\": 1}\n",
  "passed": true,
  "rule_results": [
    {
      "jsonpath": "$.rbacInUse",
      "expected_values": [],
      "validation_rule": "^[1-9][0-9]*$",
      "description": "Validates that at least one RBAC role assignment exists on the storage account. RBAC is the required access control mechanism; no assignments indicates access may not be properly scoped.\n",
      "actual_value": "[1]",
      "passed": true
    }
  ]
}
Feature: CCC.ObjStor.CN02.AR01 - Uniform Bucket-Level Access (Consistent Allow)
Scenario: Test policy for uniform access @PerService @object-storage @CCC.ObjStor @tlp-amber @tlp-red @CCC.ObjStor.CN02 @Policy
Given a cloud api for "{Instance}" in "api"33µs
And I call "{api}" with "GetServiceAPI" using argument "object-storage"37µs
And I refer to "{result}" as "storage"22µs
And I call "{api}" with "GetServiceAPI" using argument "iam"26µs
And I refer to "{result}" as "iamService"22µs
When I attempt policy check "uniform-bucket-level-access" for control "CCC.ObjStor.CN02" assessment requirement "AR01" for service "{ServiceType}" on resource "{ResourceName}" and provider "{Provider}"1s
Then "{result}" is true40µs
📎 Attachments:
policy-result-uniform-bucket-level-access.json
View JSON (1525 bytes)
{
  "policy_path": "/home/runner/work/ccc-cfi-compliance/ccc-cfi-compliance/testing/policy/CCC.ObjStor/CCC.ObjStor.CN02/AR01/uniform-bucket-level-access/azure.yaml",
  "name": "Azure Blob Uniform Access Check",
  "service_type": "object-storage",
  "requirement_text": "The service MUST enforce uniform bucket-level access, preventing ad-hoc object-level permissions.\n",
  "validity_score": 8,
  "validity_commentary": "This query checks if public access is disabled and if the storage account configuration supports uniform access. Azure by default uses RBAC which is uniform at the container level if implemented correctly. Strengths: - Checks for disabling of public access - Focuses on management-level configuration\n",
  "query_template": "az storage account show \\\n  --name ${AzureStorageAccount} \\\n  --resource-group ${AzureResourceGroup} \\\n  --query \"{publicAccess:allowBlobPublicAccess}\" \\\n  --output json\n",
  "query_executed": "az storage account show \\\n  --name stgcfi20260410t090725z \\\n  --resource-group cfi_test_20260410t090725z \\\n  --query \"{publicAccess:allowBlobPublicAccess}\" \\\n  --output json\n",
  "query_output": "{\n  \"publicAccess\": false\n}\n",
  "passed": true,
  "rule_results": [
    {
      "jsonpath": "$.publicAccess",
      "expected_values": [
        "false"
      ],
      "validation_rule": "^false$",
      "description": "Verifies that public access to blobs is disabled at the account level.\n",
      "actual_value": "[false]",
      "passed": true
    }
  ]
}
Feature: CCC.ObjStor.CN02.AR02 - Uniform Bucket-Level Access (Consistent Deny)
Scenario: Uniform bucket-level access prevents object-level deny overrides @PerService @object-storage @CCC.ObjStor @tlp-amber @tlp-red @CCC.ObjStor.CN02 @Policy @Duplicate @object-storage
Given a cloud api for "{Instance}" in "api"46µs
And I call "{api}" with "GetServiceAPI" using argument "object-storage"44µs
And I refer to "{result}" as "storage"26µs
And I call "{api}" with "GetServiceAPI" using argument "iam"33µs
And I refer to "{result}" as "iamService"26µs
Then no-op required27µs
Feature: CCC.ObjStor.CN03.AR01 - Bucket Soft Delete and Recovery
Scenario: Test policy for bucket soft delete @PerService @object-storage @CCC.ObjStor @tlp-amber @tlp-red @CCC.ObjStor.CN03 @Policy
Given a cloud api for "{Instance}" in "api"46µs
And I call "{api}" with "GetServiceAPI" using argument "object-storage"31µs
And I refer to "{result}" as "storage"21µs
When I attempt policy check "bucket-soft-delete" for control "CCC.ObjStor.CN03" assessment requirement "AR01" for service "{ServiceType}" on resource "{ResourceName}" and provider "{Provider}"1s
Then "{result}" is true36µs
📎 Attachments:
policy-result-bucket-soft-delete.json
View JSON (1971 bytes)
{
  "policy_path": "/home/runner/work/ccc-cfi-compliance/ccc-cfi-compliance/testing/policy/CCC.ObjStor/CCC.ObjStor.CN03/AR01/bucket-soft-delete/azure.yaml",
  "name": "Azure Blob Soft Delete Check",
  "service_type": "object-storage",
  "requirement_text": "When an object storage bucket deletion is attempted, the bucket MUST be fully recoverable for a set time-frame after deletion is requested.\n",
  "validity_score": 9,
  "validity_commentary": "Azure Blob Storage supports container soft delete and blob soft delete. This check validates that container soft delete is enabled with a retention period greater than zero days. Strengths: - Directly checks container (bucket-equivalent) soft delete configuration - Azure container soft delete is a native feature for recovery Limitations: - Does not verify the exact minimum retention duration required\n",
  "query_template": "az storage account blob-service-properties show \\\n  --account-name ${AzureStorageAccount} \\\n  --resource-group ${AzureResourceGroup} \\\n  --query \"{containerDeleteRetentionPolicy: containerDeleteRetentionPolicy}\" \\\n  --output json\n",
  "query_executed": "az storage account blob-service-properties show \\\n  --account-name stgcfi20260410t090725z \\\n  --resource-group cfi_test_20260410t090725z \\\n  --query \"{containerDeleteRetentionPolicy: containerDeleteRetentionPolicy}\" \\\n  --output json\n",
  "query_output": "{\n  \"containerDeleteRetentionPolicy\": {\n    \"allowPermanentDelete\": null,\n    \"days\": 7,\n    \"enabled\": true\n  }\n}\n",
  "passed": true,
  "rule_results": [
    {
      "jsonpath": "$.containerDeleteRetentionPolicy.enabled",
      "expected_values": [
        "true"
      ],
      "validation_rule": "^true$",
      "description": "Verifies that container soft delete is enabled on the storage account, allowing deleted containers to be recovered within the retention period.\n",
      "actual_value": "[true]",
      "passed": true
    }
  ]
}
Feature: CCC.ObjStor.CN03.AR02 - Immutable Bucket Retention Policy
Scenario: Test policy for immutable bucket retention lock @PerService @object-storage @CCC.ObjStor @tlp-amber @tlp-red @CCC.ObjStor.CN03 @Policy
Given a cloud api for "{Instance}" in "api"48µs
And I call "{api}" with "GetServiceAPI" using argument "object-storage"236µs
And I refer to "{result}" as "storage"1ms
When I attempt policy check "bucket-retention-lock" for control "CCC.ObjStor.CN03" assessment requirement "AR02" for service "{ServiceType}" on resource "{ResourceName}" and provider "{Provider}"2s
Then "{result}" is true33µs
📎 Attachments:
policy-result-bucket-retention-lock.json
View JSON (2830 bytes)
{
  "policy_path": "/home/runner/work/ccc-cfi-compliance/ccc-cfi-compliance/testing/policy/CCC.ObjStor/CCC.ObjStor.CN03/AR02/bucket-retention-lock/azure.yaml",
  "name": "Azure Blob Immutability Policy Lock Check",
  "service_type": "object-storage",
  "requirement_text": "When an attempt is made to modify the retention policy for an object storage bucket, the service MUST prevent the policy from being modified.\n",
  "validity_score": 9,
  "validity_commentary": "This query validates that an immutability policy is set on the Azure storage container (bucket-equivalent) and that it is in a locked state. Strengths: - A locked immutability policy cannot be shortened or deleted - Directly checks the container-level immutability configuration Limitations: - Requires the container name to be known; uses ResourceName as container - Immutability must be applied at container level in Azure\n",
  "query_template": "az resource show \\\n  --ids \"/subscriptions/${AzureSubscriptionID}/resourceGroups/${AzureResourceGroup}/providers/Microsoft.Storage/storageAccounts/${AzureStorageAccount}/blobServices/default/containers/${ResourceName}/immutabilityPolicies/default\" \\\n  --output json\n",
  "query_executed": "az resource show \\\n  --ids \"/subscriptions/c1cedd8e-bf91-4d7d-a4cc-45700402a2a1/resourceGroups/cfi_test_20260410t090725z/providers/Microsoft.Storage/storageAccounts/stgcfi20260410t090725z/blobServices/default/containers/ccc-test-container-20260410t090725z/immutabilityPolicies/default\" \\\n  --output json\n",
  "query_output": "{\n  \"etag\": \"\\\"8de96e0e1f8a6d4\\\"\",\n  \"extendedLocation\": null,\n  \"id\": \"/subscriptions/c1cedd8e-bf91-4d7d-a4cc-45700402a2a1/resourceGroups/cfi_test_20260410t090725z/providers/Microsoft.Storage/storageAccounts/stgcfi20260410t090725z/blobServices/default/containers/ccc-test-container-20260410t090725z/immutabilityPolicies/default\",\n  \"identity\": null,\n  \"kind\": null,\n  \"location\": null,\n  \"managedBy\": null,\n  \"name\": \"default\",\n  \"plan\": null,\n  \"properties\": {\n    \"allowProtectedAppendWrites\": false,\n    \"allowProtectedAppendWritesAll\": false,\n    \"immutabilityPeriodSinceCreationInDays\": 2,\n    \"state\": \"Locked\"\n  },\n  \"resourceGroup\": \"cfi_test_20260410t090725z\",\n  \"sku\": null,\n  \"tags\": null,\n  \"type\": \"Microsoft.Storage/storageAccounts/blobServices/containers/immutabilityPolicies\"\n}\n",
  "passed": true,
  "rule_results": [
    {
      "jsonpath": "$.properties.state",
      "expected_values": [
        "Locked"
      ],
      "validation_rule": "^Locked$",
      "description": "Verifies that the container immutability policy is in the Locked state, preventing any modification or deletion of the retention configuration.\n",
      "actual_value": "[Locked]",
      "passed": true
    }
  ]
}
Feature: CCC.ObjStor.CN04.AR01
Scenario: Test policy for default object retention @PerService @object-storage @CCC.ObjStor @tlp-clear @tlp-green @tlp-amber @tlp-red @CCC.ObjStor.CN04 @Policy
Given a cloud api for "{Instance}" in "api"43µs
And I call "{api}" with "GetServiceAPI" using argument "object-storage"47µs
And I refer to "{result}" as "storage"28µs
And I call "{api}" with "GetServiceAPI" using argument "iam"29µs
And I refer to "{result}" as "iamService"23µs
When I attempt policy check "object-default-retention" for control "CCC.ObjStor.CN04" assessment requirement "AR01" for service "{ServiceType}" on resource "{ResourceName}" and provider "{Provider}"1s
Then "{result}" is true37µs
📎 Attachments:
policy-result-object-default-retention.json
View JSON (2472 bytes)
{
  "policy_path": "/home/runner/work/ccc-cfi-compliance/ccc-cfi-compliance/testing/policy/CCC.ObjStor/CCC.ObjStor.CN04/AR01/object-default-retention/azure.yaml",
  "name": "Azure Blob Default Immutability Policy Check",
  "service_type": "object-storage",
  "requirement_text": "Objects MUST automatically receive a default retention policy upon upload, protecting critical data from premature deletion or modification.\n",
  "validity_score": 8,
  "validity_commentary": "This query validates that an immutability policy is configured on the Azure storage container with a non-zero retention interval, ensuring uploaded blobs are automatically protected. Strengths: - Container-level immutability policy applies to all blobs within it - Directly checks the immutability interval in days Limitations: - Policy may need to be set per-container in Azure - Does not verify that the policy is locked (see CN03.AR02)\n",
  "query_template": "az storage container immutability-policy show \\\n  --account-name ${AzureStorageAccount} \\\n  --container-name ${ResourceName} \\\n  --resource-group ${AzureResourceGroup} \\\n  --output json\n",
  "query_executed": "az storage container immutability-policy show \\\n  --account-name stgcfi20260410t090725z \\\n  --container-name ccc-test-container-20260410t090725z \\\n  --resource-group cfi_test_20260410t090725z \\\n  --output json\n",
  "query_output": "{\n  \"allowProtectedAppendWrites\": false,\n  \"allowProtectedAppendWritesAll\": false,\n  \"etag\": \"\\\"8de96e0e1f8a6d4\\\"\",\n  \"id\": \"/subscriptions/c1cedd8e-bf91-4d7d-a4cc-45700402a2a1/resourceGroups/cfi_test_20260410t090725z/providers/Microsoft.Storage/storageAccounts/stgcfi20260410t090725z/blobServices/default/containers/ccc-test-container-20260410t090725z/immutabilityPolicies/default\",\n  \"immutabilityPeriodSinceCreationInDays\": 2,\n  \"name\": \"default\",\n  \"resourceGroup\": \"cfi_test_20260410t090725z\",\n  \"state\": \"Locked\",\n  \"type\": \"Microsoft.Storage/storageAccounts/blobServices/containers/immutabilityPolicies\"\n}\n",
  "passed": true,
  "rule_results": [
    {
      "jsonpath": "$.immutabilityPeriodSinceCreationInDays",
      "expected_values": [],
      "validation_rule": "^[1-9][0-9]*$",
      "description": "Verifies that the immutability period is set to a positive number of days, ensuring all blobs uploaded to the container receive retention protection.\n",
      "actual_value": "[2]",
      "passed": true
    }
  ]
}
Feature: CCC.ObjStor.CN04.AR02
Scenario: Test policy for object retention enforcement @PerService @object-storage @CCC.ObjStor @tlp-clear @tlp-green @tlp-amber @tlp-red @CCC.ObjStor.CN04 @Policy
Given a cloud api for "{Instance}" in "api"41µs
And I call "{api}" with "GetServiceAPI" using argument "object-storage"46µs
And I refer to "{result}" as "storage"25µs
And I call "{api}" with "GetServiceAPI" using argument "iam"31µs
And I refer to "{result}" as "iamService"24µs
When I attempt policy check "object-retention-enforcement" for control "CCC.ObjStor.CN04" assessment requirement "AR02" for service "{ServiceType}" on resource "{ResourceName}" and provider "{Provider}"2s
Then "{result}" is true34µs
📎 Attachments:
policy-result-object-retention-enforcement.json
View JSON (3158 bytes)
{
  "policy_path": "/home/runner/work/ccc-cfi-compliance/ccc-cfi-compliance/testing/policy/CCC.ObjStor/CCC.ObjStor.CN04/AR02/object-retention-enforcement/azure.yaml",
  "name": "Azure Blob Object Retention Enforcement Check",
  "service_type": "object-storage",
  "requirement_text": "The service MUST prevent deletion or modification of objects under active retention, maintaining data integrity and compliance requirements.\n",
  "validity_score": 9,
  "validity_commentary": "This query validates that a locked immutability policy is in place on the Azure storage container, preventing deletion or modification of blobs during the retention period. Strengths: - A Locked immutability policy cannot be shortened or removed - Directly verifies the policy state and period Limitations: - Must be configured at the container level in Azure\n",
  "query_template": "az resource show \\\n  --ids \"/subscriptions/${AzureSubscriptionID}/resourceGroups/${AzureResourceGroup}/providers/Microsoft.Storage/storageAccounts/${AzureStorageAccount}/blobServices/default/containers/${ResourceName}/immutabilityPolicies/default\" \\\n  --output json\n",
  "query_executed": "az resource show \\\n  --ids \"/subscriptions/c1cedd8e-bf91-4d7d-a4cc-45700402a2a1/resourceGroups/cfi_test_20260410t090725z/providers/Microsoft.Storage/storageAccounts/stgcfi20260410t090725z/blobServices/default/containers/ccc-test-container-20260410t090725z/immutabilityPolicies/default\" \\\n  --output json\n",
  "query_output": "{\n  \"etag\": \"\\\"8de96e0e1f8a6d4\\\"\",\n  \"extendedLocation\": null,\n  \"id\": \"/subscriptions/c1cedd8e-bf91-4d7d-a4cc-45700402a2a1/resourceGroups/cfi_test_20260410t090725z/providers/Microsoft.Storage/storageAccounts/stgcfi20260410t090725z/blobServices/default/containers/ccc-test-container-20260410t090725z/immutabilityPolicies/default\",\n  \"identity\": null,\n  \"kind\": null,\n  \"location\": null,\n  \"managedBy\": null,\n  \"name\": \"default\",\n  \"plan\": null,\n  \"properties\": {\n    \"allowProtectedAppendWrites\": false,\n    \"allowProtectedAppendWritesAll\": false,\n    \"immutabilityPeriodSinceCreationInDays\": 2,\n    \"state\": \"Locked\"\n  },\n  \"resourceGroup\": \"cfi_test_20260410t090725z\",\n  \"sku\": null,\n  \"tags\": null,\n  \"type\": \"Microsoft.Storage/storageAccounts/blobServices/containers/immutabilityPolicies\"\n}\n",
  "passed": true,
  "rule_results": [
    {
      "jsonpath": "$.properties.state",
      "expected_values": [
        "Locked"
      ],
      "validation_rule": "^Locked$",
      "description": "Verifies that the immutability policy is locked, enforcing retention and preventing blob deletion or modification before the period expires.\n",
      "actual_value": "[Locked]",
      "passed": true
    },
    {
      "jsonpath": "$.properties.immutabilityPeriodSinceCreationInDays",
      "expected_values": [
        "2"
      ],
      "validation_rule": "",
      "description": "Verifies that the immutability period meets the configured minimum (days), confirming objects are actively protected from modification or deletion.\n",
      "actual_value": "[2]",
      "passed": true
    }
  ]
}
Feature: CCC.ObjStor.CN05.AR01 - Versioning with Unique Identifiers
Scenario: Objects are stored with unique version identifiers @PerService @object-storage @CCC.ObjStor @CCC.ObjStor.CN05 @tlp-clear @tlp-green @tlp-amber @tlp-red @Policy
Given a cloud api for "{Instance}" in "api"45µs
And I call "{api}" with "GetServiceAPI" using argument "object-storage"43µs
And I refer to "{result}" as "storage"26µs
When I attempt policy check "object-storage-versioning" for control "CCC.ObjStor.CN05" assessment requirement "AR01" for service "{ServiceType}" on resource "{ResourceName}" and provider "{Provider}"1s
Then "{result}" is true35µs
📎 Attachments:
policy-result-object-storage-versioning.json
View JSON (2254 bytes)
{
  "policy_path": "/home/runner/work/ccc-cfi-compliance/ccc-cfi-compliance/testing/policy/CCC.ObjStor/CCC.ObjStor.CN05/AR01/object-storage-versioning/azure.yaml",
  "name": "Azure Blob Versioning Configuration",
  "service_type": "object-storage",
  "requirement_text": "When an object is uploaded to the object storage bucket, the object MUST be stored with a unique identifier.\n",
  "validity_score": 9,
  "validity_commentary": "This query validates that Azure Blob versioning is enabled. When versioning is enabled, each blob version gets a unique version ID. Strengths: - Directly queries versioning configuration - Azure automatically assigns unique version IDs - Versioning integrates with soft delete for protection Limitations: - Does not validate soft delete configuration - Versioning must be enabled at the storage account level\n",
  "query_template": "az storage account blob-service-properties show \\\n  --account-name ${AzureStorageAccount} \\\n  --resource-group ${AzureResourceGroup} \\\n  --query \"{isVersioningEnabled: isVersioningEnabled, containerDeleteRetentionPolicy: containerDeleteRetentionPolicy, deleteRetentionPolicy: deleteRetentionPolicy}\" \\\n  --output json\n",
  "query_executed": "az storage account blob-service-properties show \\\n  --account-name stgcfi20260410t090725z \\\n  --resource-group cfi_test_20260410t090725z \\\n  --query \"{isVersioningEnabled: isVersioningEnabled, containerDeleteRetentionPolicy: containerDeleteRetentionPolicy, deleteRetentionPolicy: deleteRetentionPolicy}\" \\\n  --output json\n",
  "query_output": "{\n  \"containerDeleteRetentionPolicy\": {\n    \"allowPermanentDelete\": null,\n    \"days\": 7,\n    \"enabled\": true\n  },\n  \"deleteRetentionPolicy\": {\n    \"allowPermanentDelete\": false,\n    \"days\": 7,\n    \"enabled\": true\n  },\n  \"isVersioningEnabled\": true\n}\n",
  "passed": true,
  "rule_results": [
    {
      "jsonpath": "$.isVersioningEnabled",
      "expected_values": [
        "true"
      ],
      "validation_rule": "^true$",
      "description": "Verifies that blob versioning is enabled on the storage account. When enabled, all blobs receive unique version IDs automatically.\n",
      "actual_value": "[true]",
      "passed": true
    }
  ]
}
Feature: CCC.ObjStor.CN05.AR02 - New Version ID on Modification
Scenario: Modified objects receive new version identifiers @PerService @object-storage @CCC.ObjStor @CCC.ObjStor.CN05 @tlp-clear @tlp-green @tlp-amber @tlp-red @Policy @Duplicate
Given a cloud api for "{Instance}" in "api"43µs
And I call "{api}" with "GetServiceAPI" using argument "object-storage"45µs
And I refer to "{result}" as "storage"24µs
Then no-op required27µs
Feature: CCC.ObjStor.CN05.AR03 - Recovery of Previous Versions
Scenario: Previous object versions can be recovered @PerService @object-storage @CCC.ObjStor @CCC.ObjStor.CN05 @tlp-clear @tlp-green @tlp-amber @tlp-red @Policy
Given a cloud api for "{Instance}" in "api"37µs
And I call "{api}" with "GetServiceAPI" using argument "object-storage"38µs
And I refer to "{result}" as "storage"23µs
Then no-op required67µs
Feature: CCC.ObjStor.CN05.AR04 - Retain Versions on Delete
Scenario: Object versions are retained after deletion @PerService @object-storage @CCC.ObjStor @CCC.ObjStor.CN05 @tlp-clear @tlp-green @tlp-amber @tlp-red @Policy @Duplicate
Given a cloud api for "{Instance}" in "api"45µs
And I call "{api}" with "GetServiceAPI" using argument "object-storage"40µs
And I refer to "{result}" as "storage"26µs
Then no-op required23µs