aws-opensearch-cross-account-access-policy

Domain access policy grants es:ESHttp* to a principal in a foreign AWS account, enabling cross-account data access without a role assumption.

derived aws emits CrossAccountTrust

match (record)

{ "field": "AccessPolicies", "resource_type": "AWS::OpenSearchService::Domain" }

where

access policy Principal.AWS contains a principal in a different account than the domain the named principal has an Allow for es:ESHttp* actions

emit

source typeResourcePolicy
target typeAccount
source<domain access policy (ResourcePolicy)>
target<foreign account or ExternalIdentity>
permissionses:ESHttpGet es:ESHttpPost es:ESHttpPut es:ESHttpDelete es:ESHttpHead
conditionsresource_policy condition_expression
state logicACTIVE when the domain access policy explicitly allows es:ESHttp* for a principal ARN or account in a different AWS account with no conditions (or conditions the foreign principal can satisfy, e.g. aws:PrincipalOrgID is the same org). CONDITIONAL(condition_expression) when an aws:PrincipalOrgID, aws:SourceIp, or aws:SourceVpc condition restricts the grant. BLOCKED if a corresponding Deny statement at the domain level overrides the Allow.

Narrative

The domain access policy for {domain.name} grants es:ESHttp* to {foreign_principal.name} in account {foreign_account}, enabling direct data access from that account without a cross-account role assumption - the foreign principal can read/write search indices without entering this account via STS.

Raw rule rules/derived/aws/opensearch.yaml

id: aws-opensearch-cross-account-access-policy
emits: CrossAccountTrust
description: Domain access policy grants es:ESHttp* to a principal in a foreign AWS account, enabling
  cross-account data access without a role assumption.
match_record:
  resource_type: AWS::OpenSearchService::Domain
  field: AccessPolicies
where:
- access policy Principal.AWS contains a principal in a different account than the domain
- the named principal has an Allow for es:ESHttp* actions
emit:
  source_type: ResourcePolicy
  target_type: Account
  source: <domain access policy (ResourcePolicy)>
  target: <foreign account or ExternalIdentity>
  permissions:
  - es:ESHttpGet
  - es:ESHttpPost
  - es:ESHttpPut
  - es:ESHttpDelete
  - es:ESHttpHead
  conditions:
  - resource_policy
  - condition_expression
  state_logic: ACTIVE when the domain access policy explicitly allows es:ESHttp* for a principal ARN or
    account in a different AWS account with no conditions (or conditions the foreign principal can satisfy,
    e.g. aws:PrincipalOrgID is the same org). CONDITIONAL(condition_expression) when an aws:PrincipalOrgID,
    aws:SourceIp, or aws:SourceVpc condition restricts the grant. BLOCKED if a corresponding Deny statement
    at the domain level overrides the Allow.
  false_positive_note: "Distinguish account IDs carefully: a principal ARN in the SAME account as the\
    \ domain is not cross-account (it is intra-account IAM access). Only emit CrossAccountTrust when the\
    \ principal account ID differs from the domain account ID. Honor aws:PrincipalOrgID conditions \u2014\
    \ if the condition requires the caller to be in the same AWS Organization, the trust is scoped to\
    \ org members (emit CONDITIONAL, not ACTIVE for arbitrary foreign accounts). aws:ResourceAccount is\
    \ a receiver-side condition, not a cross-account gate."
  narrative: "The domain access policy for {domain.name} grants es:ESHttp* to {foreign_principal.name}\
    \ in account {foreign_account}, enabling direct data access from that account without a cross-account\
    \ role assumption \u2014 the foreign principal can read/write search indices without entering this\
    \ account via STS."
move · open · esc close