azure-arm-deployment-outputs-secret

Principal with deployments/read can retrieve sensitive values (listKeys results, Key Vault references) stored in deployment output history.

derived azure emits CanReadSecret

match (effective permission)

{ "action": "Microsoft.Resources/deployments/read", "scope_type": "resource|resourceGroup|subscription" }

where

at least one deployment in scope has output values carrying credential material (listKeys() / listSecrets() results, or reference() Key Vault secret inline values) output is NOT of secureString type (those are redacted in history)

emit

source typeIdentity
target typeSecret
source<principal>
target<secret / credential value in deployment output>
permissionsMicrosoft.Resources/deployments/read
conditionsiam_permission
state logicACTIVE when the principal holds deployments/read AND the deployment output contains unredacted credential material (listKeys result, raw connection string, resolved Key Vault inline value written as a non-secure output type). CONDITIONAL(iam_permission) when deployment output content has not been confirmed to carry credentials — emit POTENTIAL(iam_permission) as a recon flag and upgrade to ACTIVE when evidence confirms credential-bearing outputs. BLOCKED if a deny assignment covers deployments/read.

Narrative

{principal.name} holds deployments/read at {target.name}'s resource group scope and can retrieve the deployment output, which contains credential material (e.g. storage account keys from listKeys(), connection strings) - an indirect credential harvest without direct access to the downstream service.

Raw rule rules/derived/azure/arm-deployments.yaml

id: azure-arm-deployment-outputs-secret
emits: CanReadSecret
description: Principal with deployments/read can retrieve sensitive values (listKeys results, Key Vault
  references) stored in deployment output history.
match_effective_permission:
  action: Microsoft.Resources/deployments/read
  scope_type: resource|resourceGroup|subscription
where:
- at least one deployment in scope has output values carrying credential material
- (listKeys() / listSecrets() results, or reference() Key Vault secret inline values)
- output is NOT of secureString type (those are redacted in history)
emit:
  source_type: Identity
  target_type: Secret
  source: <principal>
  target: <secret / credential value in deployment output>
  permissions:
  - Microsoft.Resources/deployments/read
  conditions:
  - iam_permission
  state_logic: "ACTIVE when the principal holds deployments/read AND the deployment output contains unredacted\
    \ credential material (listKeys result, raw connection string, resolved Key Vault inline value written\
    \ as a non-secure output type). CONDITIONAL(iam_permission) when deployment output content has not\
    \ been confirmed to carry credentials \u2014 emit POTENTIAL(iam_permission) as a recon flag and upgrade\
    \ to ACTIVE when evidence confirms credential-bearing outputs. BLOCKED if a deny assignment covers\
    \ deployments/read."
  false_positive_note: "secureString and secureObject typed outputs/parameters ARE redacted in deployment\
    \ history and the ARM API \u2014 do NOT emit CanReadSecret for those. Only `listKeys()` results, inline\
    \ plaintext connection strings, Key Vault secret references whose value was materialized into a non-secure\
    \ output, or raw storage account keys surface as readable.  Collect and inspect the `properties.outputs`\
    \ map before emitting ACTIVE \u2014 if outputs are absent or all typed secureString, do NOT emit.\
    \  credential-chains.yaml read-secret-yields-identity collapses CanReadSecret + CredentialsFor(secret\
    \ -> identity) into CanImpersonate \u2014 cite, do not re-derive."
  narrative: "{principal.name} holds deployments/read at {target.name}'s resource group scope and can\
    \ retrieve the deployment output, which contains credential material (e.g. storage account keys from\
    \ listKeys(), connection strings) \u2014 an indirect credential harvest without direct access to the\
    \ downstream service."
  derived_from:
  - <deployments/read effective permission>
  - "credential-chains.yaml: read-secret-yields-identity (CanReadSecret + CredentialsFor => CanImpersonate\
    \ \u2014 cited)"
move · open · esc close