aws-lf-cross-account-grant

An LF admin (or GRANT OPTION holder) granting Lake Formation SELECT / INSERT / DATA_LOCATION_ACCESS to a principal ARN in a foreign AWS account creates cross- account data-lake trust: the external principal can query this account's governed data via their own analytics services.

derived aws emits CrossAccountTrust

match

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

{'principal': None} CanGrantPermission {'data_lake': None}

where

node_type(?data_lake) == DataLake ?data_lake.provider_type == 'AWS::LakeFormation::DataLake' ?principal grants (or can grant) LF permissions (SELECT, INSERT, ALL, DATA_LOCATION_ACCESS) to a Principal whose account != account(?data_lake); confirmed by ListPermissions showing a grant to an ARN in a different account (explicit rule aws-lf-existing-grants) OR by lakeformation:GrantPermissions being ACTIVE for ?principal (rule 1) AND evidence of cross-account recipient in the data lake's permission records or RAM resource shares.

emit

source typeResourcePolicy
target typeAccount
source<LF permission grant record for the foreign principal>
target<the foreign AWS account named in the LF grant>
permissionslakeformation:GrantPermissions lakeformation:BatchGrantPermissions
conditionsresource_policy condition_expression
state logicACTIVE when ListPermissions confirms an existing grant to a Principal ARN in a foreign account AND (?principal is an LF admin OR holds GRANT OPTION on the specific resource). CONDITIONAL(resource_policy) when CanGrantPermission (rule 1) is the source (the cross-account grant has not yet been executed but the principal can execute it). CONDITIONAL(condition_expression) when the cross- account grant is scoped by an aws:PrincipalOrgID or aws:PrincipalAccount condition that restricts which foreign accounts qualify. BLOCKED by an SCP that denies lakeformation:GrantPermissions to external accounts (aws:PrincipalOrgID condition on SCP). This edge asserts the TRUST; the foreign principal's CanReadData cross-boundary requires the receiving account to accept the RAM share and hold the analytics service IAM permissions.

Narrative

{principal.name} (or an existing grant) grants Lake Formation SELECT permissions to a principal in foreign account {foreign_account}. That external principal can now query the governed data lake's tables from their own AWS account using their own analytics services (Athena / Glue / EMR), provided they have accepted the cross-account catalog share and hold the analytics service IAM permissions. This is cross-account data exfiltration trust.

Raw rule rules/derived/aws/lakeformation.yaml

id: aws-lf-cross-account-grant
emits: CrossAccountTrust
description: 'An LF admin (or GRANT OPTION holder) granting Lake Formation SELECT / INSERT / DATA_LOCATION_ACCESS
  to a principal ARN in a foreign AWS account creates cross- account data-lake trust: the external principal
  can query this account''s governed data via their own analytics services.'
match:
- - principal: null
  - CanGrantPermission
  - data_lake: null
where:
- node_type(?data_lake) == DataLake
- ?data_lake.provider_type == 'AWS::LakeFormation::DataLake'
- ?principal grants (or can grant) LF permissions (SELECT, INSERT, ALL, DATA_LOCATION_ACCESS) to a Principal
  whose account != account(?data_lake); confirmed by ListPermissions showing a grant to an ARN in a different
  account (explicit rule aws-lf-existing-grants) OR by lakeformation:GrantPermissions being ACTIVE for
  ?principal (rule 1) AND evidence of cross-account recipient in the data lake's permission records or
  RAM resource shares.
emit:
  source_type: ResourcePolicy
  target_type: Account
  source: <LF permission grant record for the foreign principal>
  target: <the foreign AWS account named in the LF grant>
  permissions:
  - lakeformation:GrantPermissions
  - lakeformation:BatchGrantPermissions
  conditions:
  - resource_policy
  - condition_expression
  state_logic: ACTIVE when ListPermissions confirms an existing grant to a Principal ARN in a foreign
    account AND (?principal is an LF admin OR holds GRANT OPTION on the specific resource). CONDITIONAL(resource_policy)
    when CanGrantPermission (rule 1) is the source (the cross-account grant has not yet been executed
    but the principal can execute it). CONDITIONAL(condition_expression) when the cross- account grant
    is scoped by an aws:PrincipalOrgID or aws:PrincipalAccount condition that restricts which foreign
    accounts qualify. BLOCKED by an SCP that denies lakeformation:GrantPermissions to external accounts
    (aws:PrincipalOrgID condition on SCP). This edge asserts the TRUST; the foreign principal's CanReadData
    cross-boundary requires the receiving account to accept the RAM share and hold the analytics service
    IAM permissions.
  confidence: min(contributing_confidences) * 0.90
  derived_from:
  - ?principal CanGrantPermission ?data_lake (rule aws-lf-grant-permissions-self)
  - ListPermissions evidence of grant to foreign-account principal
  false_positive_note: "Cross-account LF data access has THREE required conditions \u2014 all must hold:\
    \ (1) the granting account's LF GrantPermissions to the foreign principal is in place (ListPermissions\
    \ confirms the grant record, or RAM resource share of Glue catalog resources to foreign account is\
    \ confirmed); (2) the receiving account must accept the cross-account catalog access (via RAM share\
    \ acceptance / CreateLakeFormationOptIn in the receiving account \u2014 lakeformation:ListLakeFormationOptIns\
    \ in the receiving account confirms this); (3) the foreign principal must hold IAM permissions to\
    \ call the analytics service IN THEIR OWN ACCOUNT. Without all three, the foreign principal cannot\
    \ read data. Emit CrossAccountTrust ACTIVE only when (1) is confirmed; (2) and (3) yield CONDITIONAL(resource_policy)\
    \ on the downstream CanReadData that can-control then evaluates. An SCP in the GRANTING account blocking\
    \ lakeformation:GrantPermissions to external accounts (using aws:PrincipalOrgID conditions) prevents\
    \ this pattern entirely -> BLOCKED. ADDITIONAL: Cross-account grants via AWS RAM require the granting\
    \ account to call ram:CreateResourceShare with Glue database/table resources in the ResourceArns array.\
    \ A principal with both lakeformation:GrantPermissions + ram:CreateResourceShare can establish cross-account\
    \ catalog access without explicit LF grant records (the RAM share implicitly grants access). Check\
    \ ram:ListResources and ram:GetResourceShareAssociations in both accounts for evidence of shares."
  narrative: '{principal.name} (or an existing grant) grants Lake Formation SELECT permissions to a principal
    in foreign account {foreign_account}. That external principal can now query the governed data lake''s
    tables from their own AWS account using their own analytics services (Athena / Glue / EMR), provided
    they have accepted the cross-account catalog share and hold the analytics service IAM permissions.
    This is cross-account data exfiltration trust.'
move · open · esc close