aws-secretsmanager-cross-account-read

Gates the existing explicit cross-account CanReadSecret edge on the secret resource policy AND the CMK key policy.

derived aws emits

match

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

{'external': None} CanReadSecret {'secret': None}

where

node_class(?secret) == Secret ?external.account != ?secret.account ?secret resource policy grants secretsmanager:GetSecretValue to ?external ?secret is CMK-encrypted (cross-account reads cannot use aws/secretsmanager)

optional

Present → upgrade the emitted state; absent → downgrade (not a hard requirement).

{'external': None} CanDecrypt {'cmk': None}

emit

Raw rule rules/derived/aws/secretsmanager.yaml

id: aws-secretsmanager-cross-account-read
kind: state_annotation
annotates: CanReadSecret
description: Gates the existing explicit cross-account CanReadSecret edge on the secret resource policy
  AND the CMK key policy.
match:
- - external: null
  - CanReadSecret
  - secret: null
where:
- node_class(?secret) == Secret
- ?external.account != ?secret.account
- ?secret resource policy grants secretsmanager:GetSecretValue to ?external
- ?secret is CMK-encrypted (cross-account reads cannot use aws/secretsmanager)
optional:
- - external: null
  - CanDecrypt
  - cmk: null
annotation:
  target_edge:
  - external: null
  - CanReadSecret
  - secret: null
  set_state: CONDITIONAL
  set_conditions:
  - resource_policy
  - key_permission
  - iam_permission
  state_logic: 'if the resource policy grants GetSecretValue to ?external AND matched(optional[0]) with
    ?cmk == wrapping CMK (CMK key policy grants kms:Decrypt to ?external): set ACTIVE; else CONDITIONAL(resource_policy,
    key_permission). BLOCKED on any Deny in the resource policy, CMK key policy, or an SCP on either account.'
  derived_from:
  - <explicit CanReadSecret(GetSecretValue) edge_id>
  - <CrossAccountTrust(resource policy) edge_id>
  - <CanDecrypt(?cmk) edge_id?>
  false_positive_note: Cross-account access requires BOTH the secret resource policy AND the CMK key policy
    to allow the external principal AND the external principal's own identity policy to allow GetSecretValue
    (three-way AND). The AWS-managed key CANNOT be shared cross-account, so a cross-account grant on a
    managed-key secret does not actually work -> do not set ACTIVE. Honor SourceArn/ aws:PrincipalOrgID
    conditions on the resource policy. Produces no edge.
  narrative: '{external.name} (account {external.account}) is granted secretsmanager:GetSecretValue on
    {secret.name} by its resource policy; with kms:Decrypt on the wrapping CMK it can read the cross-account
    credential.'
move · open · esc close