azure-devops-variable-group-can-read-secret

A pipeline that references a non-Key Vault variable group has the group's secret variables injected into every job's environment; pipeline code can read and log them.

derived azure emits CanReadSecret

match

A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.

{'pipeline': None} HasPolicy {'variable_group': None}

where

node_type(?pipeline) == BuildWorker node_type(?variable_group) == Secret ?variable_group.provider_type == Microsoft.DevOps/variablegroups NOT (?variable_group.linkType == AzureKeyVault) ?variable_group is referenced in ?pipeline's YAML variables: block or classic-pipeline variable group

emit

source typeBuildWorker
target typeSecret
source?pipeline
target?variable_group
permissionsUse permission on variable group (DevOps Library namespace)
state logicACTIVE when the variable group is accessible to the pipeline (pipeline granted 'Use' permission on the VG in DevOps Library) and the variable group contains at least one secret variable. Exclude Key Vault-linked VGs; those are handled by azure-devops-kv-variable-group-can-read-secret.

Narrative

{pipeline.name} references variable group {variable_group.name}; all secret variables in the group are injected as environment variables into pipeline job steps and are fully readable by pipeline code (DevOps log masking is not a security boundary).

Raw rule rules/derived/azure/devops.yaml

id: azure-devops-variable-group-can-read-secret
emits: CanReadSecret
description: A pipeline that references a non-Key Vault variable group has the group's secret variables
  injected into every job's environment; pipeline code can read and log them.
applies_to:
- azure
match:
- - pipeline: null
  - HasPolicy
  - variable_group: null
where:
- node_type(?pipeline) == BuildWorker
- node_type(?variable_group) == Secret
- ?variable_group.provider_type == Microsoft.DevOps/variablegroups
- NOT (?variable_group.linkType == AzureKeyVault)
- '?variable_group is referenced in ?pipeline''s YAML variables: block or classic-pipeline variable group'
emit:
  source_type: BuildWorker
  target_type: Secret
  source: ?pipeline
  target: ?variable_group
  permissions:
  - Use permission on variable group (DevOps Library namespace)
  conditions: []
  state_logic: ACTIVE when the variable group is accessible to the pipeline (pipeline granted 'Use' permission
    on the VG in DevOps Library) and the variable group contains at least one secret variable. Exclude
    Key Vault-linked VGs; those are handled by azure-devops-kv-variable-group-can-read-secret.
  confidence: 0.9
  derived_from: []
  false_positive_note: "DevOps secret variable masking does NOT constitute a security boundary \u2014\
    \ the mask only prevents the value from appearing in UI logs. Code can still print the value to a\
    \ file, send it over the network, or read it via $env:VAR_NAME. Do NOT treat masking as access control.\
    \ This rule applies only to non-Key Vault VGs; Key Vault- linked VGs have resource_policy gates (RBAC\
    \ on the Key Vault) \u2014 do not emit ACTIVE for them here."
  narrative: '{pipeline.name} references variable group {variable_group.name}; all secret variables in
    the group are injected as environment variables into pipeline job steps and are fully readable by
    pipeline code (DevOps log masking is not a security boundary).'
move · open · esc close