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.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
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. |
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.'