Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions skills/cloud/azure-review/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,25 @@ For detailed CIS benchmark checklist items with specific Terraform patterns, Bic

---

### Step 10A: Storage Bearer Access Evidence

After the CIS storage checks, review Azure Storage access paths that are not captured by public access, TLS, or network-rule settings. Private containers can still be exposed through broad shared access signatures (SAS), Shared Key authorization, external RBAC principals, or ADLS Gen2 ACLs.

Collect and report the following evidence for each storage account that stores sensitive or externally shared data:

- **Shared Key authorization:** `allowSharedKeyAccess` / `shared_access_key_enabled` value and whether account key access is explicitly disabled.
- **SAS type inventory:** account SAS, service SAS, and user delegation SAS usage from Azure Monitor logs or operational inventory.
- **SAS expiry and scope:** maximum permitted expiry, observed expiry dates, allowed services/resource types, and permissions such as `rwdlacupiytfx`.
- **Stored access policies:** whether service SAS tokens are bound to stored access policies, whether policies are stale, and whether account SAS exceptions require key rotation for revocation.
- **User delegation preference:** whether Blob/Data Lake workflows prefer Microsoft Entra ID-backed user delegation SAS over account/service SAS where supported.
- **External principals:** guest users, external groups, service principals, and cross-tenant identities with `Storage Blob Data Owner`, `Storage Blob Data Contributor`, or equivalent roles.
- **ADLS Gen2 ACL parity:** effective RBAC plus access/default ACL permissions for containers, directories, and files; include recursive ACL evidence for existing child paths.
- **Logging and revocation evidence:** diagnostic logs for `AuthenticationType in ("AccountKey", "SAS")`, key rotation history, SAS revocation playbook, and exception owner/expiry.

**Finding classification:** Long-lived account SAS with broad permissions and no revocation path is **High**. Shared Key access enabled on sensitive storage without migration/exception evidence is **High**. External contributor access without access-review evidence is **High**. ADLS Gen2 ACL/RBAC divergence that grants unintended write or read access is **High** for sensitive data and **Medium** otherwise. Missing SAS inventory or logging is **Medium**.

---


---

Expand Down Expand Up @@ -154,6 +173,12 @@ Produce the final report using the structure defined in the Output Format sectio
- **Evidence:** <specific configuration or code snippet>
- **Remediation:** <specific fix with code example>

### Storage Bearer Access Review

| Storage Account | Shared Key Disabled | SAS Type(s) | Max SAS Expiry | Stored Access Policy | External Principals | ADLS ACL/RBAC Parity | Status |
|-----------------|---------------------|-------------|----------------|----------------------|---------------------|----------------------|--------|
| <name> | Yes/No/Unknown | Account/Service/User Delegation/Unknown | <duration> | Present/Missing/N/A | Reviewed/Unreviewed | Matched/Divergent/N/A | Pass/Fail/Not Evaluable |

### Prioritized Remediation Plan

1. **[Critical]** CIS X.Y.Z -- <action item>
Expand Down Expand Up @@ -223,6 +248,10 @@ Produce the final report using the structure defined in the Output Format sectio
- Microsoft Defender for Cloud Documentation: https://learn.microsoft.com/en-us/azure/defender-for-cloud/
- Microsoft Entra ID Security: https://learn.microsoft.com/en-us/entra/identity/
- Azure Storage Security: https://learn.microsoft.com/en-us/azure/storage/common/storage-security-guide
- Prevent Shared Key authorization: https://learn.microsoft.com/en-us/azure/storage/common/shared-key-authorization-prevent
- Configure a SAS expiration policy: https://learn.microsoft.com/en-us/azure/storage/common/sas-expiration-policy
- Define a stored access policy: https://learn.microsoft.com/en-us/rest/api/storageservices/define-stored-access-policy
- ADLS Gen2 access control lists: https://learn.microsoft.com/en-us/azure/storage/blobs/data-lake-storage-access-control
- Azure Key Vault Best Practices: https://learn.microsoft.com/en-us/azure/key-vault/general/best-practices
- Azure App Service Security: https://learn.microsoft.com/en-us/azure/app-service/overview-security
- Terraform AzureRM Provider Documentation: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs
Expand Down
54 changes: 54 additions & 0 deletions skills/cloud/azure-review/benchmark-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,60 @@ resource "azurerm_storage_account" {
}
```

### Supplemental Storage Access -- SAS, Shared Key, and Effective Principals

These checks reduce false assurance where storage accounts pass public-access, HTTPS, TLS, and network-rule controls but still expose data through bearer tokens or effective data-plane permissions.

#### Shared Key authorization

Check for explicit Shared Key disablement on sensitive storage accounts:

```hcl
resource "azurerm_storage_account" "records" {
shared_access_key_enabled = false
}
```

For ARM/Bicep or exported configuration, verify `allowSharedKeyAccess` is explicitly `false`. Treat a missing/null value as permitting Shared Key authorization unless an Azure Policy or live setting proves otherwise.

**Flag as High** when sensitive or externally shared storage permits Shared Key access and there is no migration plan, compatibility exception, owner, or expiry.

#### SAS token inventory and expiry

Review operational evidence for account SAS, service SAS, and user delegation SAS usage:

- Azure Monitor logs or equivalent evidence for requests where `AuthenticationType` is `AccountKey` or `SAS`.
- Maximum SAS expiry policy and observed SAS token expiry.
- SAS permissions and resource scope: broad combinations such as read/write/delete/list/add/create/update/process across blob/file services should be justified.
- Whether Blob/Data Lake workflows prefer user delegation SAS where supported.

**Flag as High** when an account SAS or service SAS is long-lived, grants broad permissions, and is not backed by a revocation path. **Flag as Medium** when SAS usage exists but logging cannot identify token type, caller, or expiry.

#### Stored access policies and revocation

For service SAS tokens, check whether a stored access policy is used to support revocation without rotating account keys:

```bash
az storage container policy list \
--account-name <storage-account> \
--container-name <container>
```

Stored access policies do not apply to account SAS or user delegation SAS. If account SAS is used, require key rotation evidence and an emergency revocation playbook.

**Flag as High** when broad service SAS tokens are not bound to stored access policies and no alternative revocation evidence exists. **Flag stale policies as Medium** when they have no owner, review date, or expiry.

#### External principals and ADLS Gen2 ACL parity

Private containers can still be accessible through data-plane RBAC, guest groups, service principals, and ADLS Gen2 ACLs. Verify:

- Role assignments for `Storage Blob Data Owner`, `Storage Blob Data Contributor`, `Storage Blob Data Reader`, and custom roles with data actions.
- Guest users, external groups, cross-tenant service principals, and managed identities with data-plane access.
- ADLS Gen2 access ACLs and default ACLs on directories and files, not just container-level RBAC.
- Recursive ACL evidence for existing child items when default ACLs changed after data was created.

**Flag as High** when external or stale principals retain contributor/owner access to sensitive data without access-review evidence. **Flag ACL/RBAC divergence as High** for sensitive data when write or broad read access is granted outside the approved access model.

---

## Section 4 -- Database Services
Expand Down
102 changes: 102 additions & 0 deletions skills/cloud/azure-review/tests/storage-sas-policy-edge-cases.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Azure Storage SAS and Effective Access Edge Cases

These fixtures cover storage accounts that pass common CIS-style storage controls but remain exposed through SAS bearer tokens, Shared Key authorization, external principals, or ADLS Gen2 ACL divergence.

## Case 1: Private Storage With Long-Lived Account SAS

Input evidence:

```hcl
resource "azurerm_storage_account" "records" {
name = "prodrecords"
enable_https_traffic_only = true
min_tls_version = "TLS1_2"
allow_nested_items_to_be_public = false
shared_access_key_enabled = true
}
```

Operational export:

```text
sv=2025-01-01&ss=bf&srt=sco&sp=rwdlacupiytfx&se=2028-12-31T23:59:59Z
```

Expected review:

- CIS public-access/TLS checks may pass.
- Storage Bearer Access Review fails because Shared Key is enabled and an account SAS is broad and long-lived.
- Severity is High when the account stores sensitive or externally shared data.
- Remediation requires migration to Microsoft Entra ID/user delegation SAS where possible, maximum expiry policy, and key rotation or revocation plan.

## Case 2: Service SAS Without Stored Access Policy

Input evidence:

```yaml
storage_account: auditlogs
container: exports
service_sas:
permissions: rwdl
expiry: 180d
stored_access_policy: null
diagnostic_logs:
authentication_types:
- SAS
```

Expected review:

- Finding is High if the SAS grants write/delete/list to sensitive exports and no stored access policy or alternative revocation evidence exists.
- Finding is Medium if logs show SAS usage but do not identify caller, token class, or expiry.
- The report records `Stored Access Policy` as `Missing` and `Status` as `Fail`.

## Case 3: User Delegation SAS With Bounded Scope

Input evidence:

```yaml
storage_account: datalakecurated
allow_shared_key_access: false
user_delegation_sas:
service: blob
permissions: rl
expiry: 4h
requester: managed_identity_exporter
diagnostic_logs:
authentication_types:
- OAuth
- SAS
```

Expected review:

- User delegation SAS is preferred for Blob/Data Lake when bounded and backed by Microsoft Entra ID.
- The review still records expiry, scope, and caller evidence.
- No High finding is created solely because SAS exists.

## Case 4: External Guest Group and ADLS ACL Divergence

Input evidence:

```yaml
rbac:
- principal: external-audit-guests
principal_type: group
role: Storage Blob Data Contributor
scope: /subscriptions/000/resourceGroups/prod/providers/Microsoft.Storage/storageAccounts/lake
access_review:
last_completed: null
adls_acl:
path: /finance/raw
access_acl:
- group:external-audit-guests:rwx
default_acl:
- group:external-audit-guests:rwx
```

Expected review:

- Finding is High for stale external contributor access without access-review evidence.
- The report records external principals as `Unreviewed`.
- The ADLS ACL/RBAC parity column is `Divergent` if the approved model does not allow external write access to `/finance/raw`.