# Cross-account lake query checklist

Run this in order when a consumer account reports `AccessDenied` on a shared table.
Most failures are Lake Formation grant gaps — not IAM policy typos.

## Producer account (data owner)

- [ ] S3 bucket registered as a Lake Formation data lake location
- [ ] `IAMAllowedPrincipals` revoked on registered databases/tables (LF-only mode)
- [ ] LF-Tags assigned to target databases/tables (one value per key per resource)
- [ ] Cross-account grant issued (LF-Tag expression or named resource) with `DESCRIBE` + `SELECT`
- [ ] Cross-account version upgraded to **v5** if sharing 1,000+ tables (Feb 2026 feature)
- [ ] RAM resource share visible to consumer account or OU
- [ ] S3 bucket policy allows consumer roles **only if** LF also grants (LF is authoritative on registered paths)
- [ ] KMS key policy allows consumer roles if tables use SSE-KMS

## Consumer account (analyst)

- [ ] RAM invitation accepted (Organizations same-org shares auto-accept)
- [ ] Resource link created for each shared database/table used in queries
- [ ] Athena workgroup uses IAM role registered as Lake Formation **data lake admin** or **analyst** with LF permissions
- [ ] Glue catalog ID in queries references **resource link** name, not producer database name directly
- [ ] LF `GetDataAccess` succeeds — check Lake Formation → Permissions → Data lake permissions

## Org-level guardrails

- [ ] RCP on producer OU tested in NonProd — partner integrations not silently denied
- [ ] SCP does not block `lakeformation:GrantPermissions` for data platform roles
- [ ] CloudTrail Lake Formation events enabled for grant changes

## Quick diagnosis commands

Context: AWS CLI 2.x, run from consumer account with the analyst role.

```bash
# List LF grants visible to this principal
aws lakeformation list-permissions --catalog-id <PRODUCER_ACCOUNT_ID>

# Confirm resource link exists
aws glue get-database --name <RESOURCE_LINK_DB_NAME>

# Minimal Athena probe (replace workgroup and link names)
aws athena start-query-execution \
  --query-string 'SELECT 1 FROM <link_db>.<link_table> LIMIT 1' \
  --work-group primary
```

Expected: query succeeds or returns a **SQL** error — not `AccessDenied` on Glue or S3.

## When to escalate

- Partner account **outside** the organization → named-resource share + explicit bucket/KMS policies; RCP may block — test first.
- Row-level security in QuickSight → out of scope for LF grants alone; needs SPICE or RLS dataset rules.
- Redshift consumers → use **datashares**, not LF resource links.
