Skip to content

feat(scanner): migrate storage rules AZ-STOR-001 to 010 to the evaluate() contract #370

Description

@parthrohit22

What problem does this solve?

The 10 storage rules (AZ-STOR-001 to AZ-STOR-010) only implement scan(), so the engine reports their coverage as UNKNOWN / LEGACY_RULE_NOT_MIGRATED. Storage controls map to many CIS, NIST CSF, ISO 27001 and SOC 2 controls, so this family has the largest effect on report quality. It also serves as the reference implementation that later family migrations copy.

Describe the solution

Migrate every rule below to the evaluate() contract, using AzureClient.list_storage_accounts() and the shared helpers from the foundation issue.

Rule Non-trivial branches that need an explicit status
az_stor_001 public blob access —
az_stor_002 HTTPS-only —
az_stor_003 lifecycle policy get_storage_lifecycle_policy() returns None → UNKNOWN; missing id / name / resource group → UNKNOWN
az_stor_004 diagnostic logging get_storage_service_logging() returns None → UNKNOWN
az_stor_005 geo-redundant replication skipped accounts → explicit status
az_stor_006 shared key access None is treated as enabled, so it stays FAIL (documented Azure default)
az_stor_007 minimum TLS missing value → UNKNOWN
az_stor_008 customer-managed key tag not set → NOT_APPLICABLE / POLICY_NOT_REQUIRED; approved exception → APPROVED_EXCEPTION
az_stor_009 blob immutability as 008, plus get_blob_containers() returns None → UNKNOWN
az_stor_010 private endpoint public access disabled → NOT_APPLICABLE / PUBLIC_ACCESS_DISABLED; connections unavailable → UNKNOWN

Status mapping

Every path that scan() currently handles with a silent continue must become an explicit status:

Situation Status reason_code
Inventory call failed (returned None) ERROR INVENTORY_UNAVAILABLE
Inventory succeeded but is empty NOT_APPLICABLE NO_RESOURCES_FOUND
Setting is compliant PASS —
Setting is a violation FAIL + the existing finding dict —
A per-resource detail call returned None, or a required field is missing UNKNOWN EVIDENCE_UNAVAILABLE / MISSING_PROPERTIES
Opt-in policy tag not set (policy_required(...) is false) NOT_APPLICABLE POLICY_NOT_REQUIRED
Approved exception tag set NOT_APPLICABLE APPROVED_EXCEPTION

A failed inventory call must never produce PASS or NOT_APPLICABLE.

Acceptance criteria

  • Each rule in scope exposes evaluate(azure_client, subscription_id) -> List[RuleEvaluation] using the shared helpers in scanner/evaluation.py.
  • scan() becomes a thin wrapper returning the findings attached to FAIL evaluations.
  • Detection is unchanged: for the existing test fixtures, scan() returns exactly the same findings as before the change.
  • Each FAIL / PASS evaluation records the inspected value(s) in evidence, for example {"allow_blob_public_access": true}.
  • New tests cover the PASS, FAIL, UNKNOWN, NOT_APPLICABLE and inventory-failure paths for every rule in scope.
  • The rules are picked up automatically by tests/test_rule_evaluation_contract.py and it passes.
  • pytest, ruff check . and ruff format --check . pass.
  • CHANGELOG.md updated under Unreleased.

Alternatives considered

Migrating storage alongside the foundation PR was considered. It is kept separate so the engine and contract changes can be reviewed on their own.

Additional context

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

coreCore team ownership not for studentsenhancementNew feature or requestpriority: highImportant, should be fixed in the current sprintpythonPull requests that update python coderoadmapPlanned feature track, not a current bug

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions