Applying Authorization Mechanisms: Lake Formation, IAM, and Redshift
Authorization on AWS decides what an authenticated principal may do, and for data engineers it happens at two distinct layers: IAM policies govern API-level actions on services and resources, while AWS Lake Formation governs data-level access — databases, tables, columns, rows, and cells in your data lake — with grants that Amazon Athena, Amazon Redshift, and Amazon EMR all enforce consistently. The DEA-C01 exam tests whether you can pick the right layer and the right model: writing custom IAM policies when managed policies are too broad, storing credentials in AWS Secrets Manager or Systems Manager Parameter Store, granting database users, groups, and roles authority inside Amazon Redshift, and choosing between role-based, tag-based, and attribute-based access control. This lesson covers all of it, including LF-Tags for scalable lake permissions, fine-grained column, row, and cell filtering, and the habits that keep every policy you write at least privilege.
On this page9 sections
- Two authorization layers: IAM and Lake Formation
- Custom IAM policies when managed policies fall short
- Constructing least-privilege policies
- Storing credentials: Secrets Manager versus Parameter Store
- Database authorization in Amazon Redshift: users, groups, and roles
- Managing lake permissions with AWS Lake Formation
- Cross-account Lake Formation sharing, step by step
- LF-Tags and fine-grained access: columns, rows, and cells
- Scenario: least-privilege authorization for a multi-team platform
- Contrast IAM policy authorization with AWS Lake Formation permissions and pick the right layer for a scenario
- Predict policy evaluation outcomes for same-account and cross-account requests, including explicit Deny conditions, SCPs and permissions boundaries
- Write least-privilege custom IAM policies with correct S3 resource scoping, ABAC conditions and permissions-boundary delegation, using IAM Access Analyzer evidence
- Choose between AWS Secrets Manager and Systems Manager Parameter Store, and share a secret across accounts correctly
- Grant Amazon Redshift users, groups and roles access to existing and future tables, and apply row-level security
- Enforce Lake Formation permissions by replacing IAM-only defaults, and share lake data across accounts with resource links
- Apply role-based, tag-based and attribute-based authorization models to match business needs
Custom IAM policies when managed policies fall short
AWS managed policies get you started, but they are deliberately generic — AmazonS3ReadOnlyAccess grants read access to every bucket in the account, and the exam expects you to recognize that as a least-privilege failure. You write a custom (customer managed) policy whenever a managed policy is too broad, too narrow, or missing a condition your business requires. Customer managed policies are reusable across principals, versioned (you can roll back), and yours to scope precisely; inline policies embed in a single principal and are best reserved for one-off exceptions you never want reused.
A policy statement has four load-bearing parts: Effect (Allow or Deny), Action (the API calls), Resource (the ARNs), and optional Condition blocks. Evaluation logic is a favorite exam trap: everything is implicitly denied by default, any applicable Allow grants access, and an explicit Deny anywhere always wins — across identity policies, resource policies, permissions boundaries, and service control policies. Explicit Deny is therefore your guardrail tool: for example, deny s3:PutObject unless the request includes the correct encryption header, or deny all actions when aws:SourceVpce does not match your VPC endpoint.
How the policies combine: same account versus cross-account
Whether a request succeeds depends on which account owns the resource. Within one account, an Allow in either the caller's identity policy or the resource's policy (such as a bucket policy) is enough — for S3 and most services with resource policies. The exceptions are AWS KMS keys and IAM role trust policies: there the key policy or trust policy itself must allow the access, so an identity-policy Allow alone is not enough. Across accounts, the request needs an Allow on both sides: the caller's identity policy in its own account and the resource policy in the owner's account. Service control policies (SCPs) and permissions boundaries are filters, not grants — they can only remove permissions, so neither one ever makes a request succeed on its own.
| Situation | Identity policy Allow | Resource policy Allow | Outcome |
|---|---|---|---|
| Same account | Yes | No (silent) | Allowed |
| Same account | No | Yes, naming the principal | Allowed |
| Cross-account | Yes | No | Denied |
| Cross-account | No | Yes | Denied |
| Cross-account | Yes | Yes | Allowed |
| Any | Any | Any, plus an explicit Deny that matches | Denied |
The last row is the one that surprises people. Suppose a pipeline role's identity policy allows s3:* on every bucket, and a bucket in the same account carries a statement that denies all S3 actions to every principal when aws:SecureTransport is false. A call made over plain HTTP matches that condition, so the Deny applies and the call fails — the broad identity Allow does not matter, because policies are not evaluated in an order where an earlier Allow wins. The same call over HTTPS does not match the Deny and succeeds on the identity Allow. Any condition key behaves this way (aws:SourceVpce, aws:PrincipalOrgID, aws:SourceIp): work out whether the request matches the Deny's condition first, and only then look for an Allow. Cross-account S3 reads with bucket owner enforced Object Ownership (ACLs disabled) follow the same rule: the bucket policy must allow the other account's role, and that role's identity policy must allow the S3 actions; ACLs play no part.
A concrete data-engineering example: a Glue job must read raw data from one prefix and write curated Parquet to another. The custom policy allows s3:GetObject on the raw prefix ARN, s3:PutObject on the curated prefix ARN, and s3:ListBucket on the bucket with an s3:prefix condition — nothing account-wide, no s3 wildcard actions. Remember that object actions take object-level ARNs with a path, while ListBucket takes the bucket ARN; mixing those up is a classic reason a scoped policy mysteriously fails.
Constructing least-privilege policies
Least privilege means every principal holds exactly the permissions its job requires — no wildcard actions, no account-wide resources, no permanent grants for temporary needs. In practice you construct it iteratively: start from what the workload actually calls, scope Resource to specific ARNs and prefixes, then tighten with conditions. Useful condition keys for data work include aws:SourceVpce and aws:SourceVpc (require the private path), aws:PrincipalTag and aws:ResourceTag (attribute-based control), s3:prefix (limit listing), and aws:SecureTransport (refuse unencrypted connections).
Scoping S3 permissions to a prefix
S3 actions split by resource type, and a least-privilege policy has to respect the split. Object actions such as s3:GetObject and s3:PutObject act on object ARNs, so they are scoped to a path like arn:aws:s3:::lake-bucket/raw/sales/*. s3:ListBucket acts on the bucket ARN (arn:aws:s3:::lake-bucket, no path), so you narrow it with a Condition on the s3:prefix key, for example StringLike s3:prefix raw/sales/*. Putting ListBucket on the object path, or GetObject on the bare bucket ARN, matches nothing and the call is denied.
AWS gives you tooling so least privilege is not guesswork. IAM Access Analyzer can generate a policy from the CloudTrail activity of a role — run the pipeline for a while, then generate a policy that permits only what it actually did. Its unused access findings report roles, access keys and permissions that have gone unused over a tracking period, which tells you what to remove; policy generation tells you what to keep. Do not confuse these with external access findings, which answer a different question — which resources are shared with principals outside your zone of trust — and say nothing about whether a role uses its permissions. Access Analyzer also validates policies against best practices, and the last accessed information on roles shows which granted services have never been called. The IAM policy simulator, by contrast, only tests what a policy text allows; it has no usage evidence.
Permissions boundaries for delegated role creation
A permissions boundary is a managed policy set as the ceiling on a user's or role's permissions: the effective permissions are the overlap of the identity policy and the boundary. Its main use is safe delegation. When a platform team lets data teams create their own pipeline roles, it allows iam:CreateRole (and iam:PutRolePolicy, iam:AttachRolePolicy) only with a Condition that iam:PermissionsBoundary equals the ARN of the approved boundary policy, and denies removing or changing that boundary. Every role the data team creates is then capped, whatever policy they attach to it. The alternatives do not fit this goal: an SCP applies to every principal in the account, not just the roles a team creates, and a session policy limits only the session of whoever passes it — it places no ceiling on the roles that person creates.
Two habits close the loop. First, prefer temporary elevation over standing privilege: an engineer who occasionally needs to delete lake objects should assume a scoped role for that task, not carry the permission daily. Second, remember iam:PassRole: any policy that lets a user hand a role to Glue, Lambda, or CloudFormation must restrict which roles can be passed, or the user can escalate by passing an administrator role to a service they control. Exam options that casually include iam:PassRole on Resource star are showing you the wrong answer.
Storing credentials: Secrets Manager versus Parameter Store
Authorization extends to the credentials your applications use, and skill 4.2.2 names the two stores you must be able to choose between. AWS Secrets Manager is purpose-built for secrets: encryption with AWS KMS is mandatory, automatic rotation is built in (managed rotation for RDS, Aurora, Redshift, and DocumentDB, or a custom rotation Lambda), secrets can be replicated to other Regions, and resource policies on individual secrets enable clean cross-account sharing. AWS Systems Manager Parameter Store is a general configuration store: String and StringList parameters for plain settings, SecureString parameters (KMS-encrypted) for sensitive ones, organized in hierarchical paths, with a standard tier that costs nothing.
| Capability | Secrets Manager | Parameter Store |
|---|---|---|
| Automatic rotation | Built in, plus managed rotation for AWS databases | None built in |
| Encryption | Always encrypted with KMS | Optional via SecureString |
| Cross-account access | Yes, via resource policies on secrets | Limited; advanced-tier parameters support sharing via AWS RAM |
| Cost | Per secret per month plus API calls | Standard tier free; advanced tier paid |
| Best for | Database passwords, API keys, anything that must rotate | Configuration values, feature flags, non-rotating settings |
The exam decision rule is short: rotation or cross-account secrets means Secrets Manager; cheap configuration means Parameter Store. Authorization applies identically to both — grant secretsmanager:GetSecretValue or ssm:GetParameter on specific ARNs only, and use path-based ARNs (for example a /prod/etl/ parameter hierarchy) so one policy statement cleanly covers a team's parameters without exposing anyone else's. Both services log retrievals to CloudTrail, which is what turns credential access into something you can audit.
Sharing a secret with another account
Cross-account secret access needs three Allows to line up. The secret's resource policy in the owning account must allow the other account's role secretsmanager:GetSecretValue; the role's identity policy in its own account must allow GetSecretValue on the secret ARN and kms:Decrypt on the key; and the secret must be encrypted with a customer managed KMS key whose key policy allows that role to decrypt. A secret encrypted with the AWS managed key aws/secretsmanager cannot be read from another account, because an AWS managed key's policy cannot be edited to admit outside principals — re-encrypt the secret with a customer managed key first. Secret replication does not help here: it copies a secret to other Regions within the same account, not to other accounts.
Managing lake permissions with AWS Lake Formation
Lake Formation centralizes data-lake authorization in three moves. First, you register S3 locations with Lake Formation, handing it responsibility for those paths; registration uses a role Lake Formation assumes to access the data. Second, you define databases and tables over that data in the Glue Data Catalog. Third, you grant permissions — SELECT, INSERT, DESCRIBE, ALTER and so on — to principals (IAM users and roles, and cross-account principals) on catalog resources, using the console, the GRANT-style API, or LF-Tags. A separate data location permission controls who may create databases and tables that point at a registered S3 location; it governs catalog creation, not who can read the data. Data lake administrators manage grants; you can also delegate grant authority itself with grantable permissions.
Enforcement is what makes this powerful. When an integrated engine — Amazon Athena, Redshift Spectrum, Amazon EMR (with runtime roles on EMR on EC2, and in EMR Serverless jobs), AWS Glue, or Amazon QuickSight — reads a governed table, Lake Formation checks the principal's grants and vends temporary S3 credentials scoped to exactly the permitted data. The querying principal needs no direct S3 policy on the lake buckets at all, which eliminates the bucket-policy sprawl that plagues IAM-only lakes.
Default settings and the IAM bypass
A freshly set-up Lake Formation does not enforce its own grants. For backward compatibility, the default Data Catalog settings use only IAM access control for new databases and tables, which they implement by granting Super to the IAMAllowedPrincipals group on each new resource. While that grant exists, anyone whose IAM policy allows the Glue and S3 calls can read the whole table, and a column-limited Lake Formation grant appears to do nothing. To enforce Lake Formation, revoke IAMAllowedPrincipals on the existing databases and tables and clear the defaults that would re-create it: the account-level settings for new databases and tables, and the per-database option Use only IAM access control for new tables in this database. The per-database option matters because it is stamped onto each table at creation: if it stays selected, tables created in that database later are granted to IAMAllowedPrincipals again, however carefully the existing ones were locked down.
Even with IAMAllowedPrincipals gone, Lake Formation enforces grants only on reads that go through integrated engines with vended credentials. It does not intercept S3 API calls: an analyst whose IAM policy still allows s3:GetObject on the lake bucket can download whole files with the AWS CLI. Removing direct S3 permissions from analyst roles is part of the cutover. Hybrid access mode exists for gradual migrations: on a location registered in hybrid mode, principals you opt in are governed by Lake Formation grants, while others keep their existing IAM access — useful for moving teams over one at a time, not a way to block direct S3 reads.
Cross-account Lake Formation sharing, step by step
Cross-account sharing lets a producer account grant catalog permissions to a consumer account without copying data or writing cross-account bucket policies; it takes a grant in the producer, acceptance and a resource link in the consumer, and local grants by the consumer's administrator.
- Producer grants to the account. The producer's data lake administrator grants, for example, SELECT (with grant option) on a table to the consumer's account ID. With the named-resource method, Lake Formation shares the resource through AWS Resource Access Manager (AWS RAM).
- Consumer accepts. The consumer's data lake administrator accepts the AWS RAM invitation (accounts in the same organization with RAM sharing enabled do not need to).
- Consumer creates a resource link. Shared tables live in the producer's catalog (they are listed in the consumer's Lake Formation console under the producer's catalog ID), so engines such as Athena and Redshift Spectrum cannot query them until the consumer creates a link in its own catalog. The consumer administrator creates a resource link — a local catalog object that points at the shared table or database.
- Consumer grants to local principals. Analysts need DESCRIBE on the resource link, so they can see it, and SELECT on the link's target (the shared table), so they can query it. A resource link accepts only DESCRIBE and DROP; granting SELECT on the link itself is not how data access is given.
The producer manages only account-level grants; the consumer administrator decides which of its own principals get access. Revoking the producer's grant cuts the whole consumer account off at once.
A concrete scenario: your central data platform account owns the curated lake. The marketing account's analysts need three tables, one of which contains customer PII columns they must not see. With Lake Formation you share the tables cross-account with column-level exclusions, the marketing admin grants their analysts SELECT, and every Athena query in the marketing account automatically respects the column filter. No bucket policies changed hands, no data was copied, and revoking the share instantly cuts access. That single-point-of-control story — grant once, enforced by every engine — is the recurring reason Lake Formation is the correct exam answer over hand-built IAM plumbing.
Tip. Expect to choose between IAM and Lake Formation for a stated granularity requirement, to predict whether a request succeeds given identity policies, bucket policies and explicit Deny conditions in the same or another account, and to spot least-privilege violations — wildcard resources, wrongly scoped S3 ARNs, unrestricted iam:PassRole. Also expect to choose an evidence source for trimming permissions to least privilege and a way to cap the permissions of roles that delegated teams create. Secrets Manager versus Parameter Store appears as a rotation, cost and cross-account decision. Redshift questions test roles, default privileges for future tables and row-level security with IGNORE RLS. Lake Formation questions test IAMAllowedPrincipals defaults, the direct-S3 bypass, cross-account resource links, and LF-Tags versus wildcard grants; ABAC questions test writing a tag-matching condition between principal and resource.
- IAM authorizes API actions; Lake Formation authorizes data — its grants are enforced identically by Athena, Redshift Spectrum, EMR, and Glue via vended temporary S3 credentials.
- Same-account access needs an Allow in the identity or the resource policy (KMS key policies and role trust policies must allow themselves); cross-account needs both; SCPs and permissions boundaries never grant, and any matching explicit Deny wins.
- Scope S3 object actions to bucket/prefix/* ARNs and s3:ListBucket to the bucket ARN with an s3:prefix condition; use Access Analyzer unused access findings and policy generation for evidence.
- Delegate role creation safely by allowing iam:CreateRole only with an iam:PermissionsBoundary condition naming the approved boundary.
- Secrets Manager for anything that must rotate or cross accounts — cross-account reads need the secret's resource policy and a customer managed KMS key, never aws/secretsmanager.
- In Redshift, GRANT ON ALL TABLES covers existing tables; ALTER DEFAULT PRIVILEGES FOR USER the creator covers future ones. RLS is deny-by-default once on; IGNORE RLS exempts a role.
- Lake Formation grants do nothing while IAMAllowedPrincipals holds Super — revoke it, clear the default settings including the per-database option, and remove direct S3 access.
- Cross-account sharing: producer grants to the account via AWS RAM, consumer accepts, creates a resource link, and grants DESCRIBE on the link plus SELECT on its target.
- LF-Tags scale lake grants by sensitivity; a table wildcard covers new tables but ignores sensitivity. Data filters combine row and column restrictions for cell-level security. ABAC matches aws:ResourceTag to ${aws:PrincipalTag}.
Frequently asked questions
When is Lake Formation the right answer instead of IAM and bucket policies?
Whenever the scenario needs data-level granularity — column, row, or cell restrictions — or one place to grant and revoke analyst access that multiple engines must respect. S3 bucket policies cannot express column- or row-level rules, and maintaining per-team policies across many buckets does not scale. If the scenario is a pipeline role reading a prefix or a service calling an API, plain IAM is sufficient and simpler.
Do users still need S3 permissions when Lake Formation governs the data?
Not on registered lake locations. Lake Formation vends temporary, scoped-down S3 credentials to integrated engines like Athena, Redshift Spectrum, and EMR when a query is authorized, so the querying principal needs no direct S3 policy for that data. They still need IAM permissions to use the engine itself — for example, permission to run Athena queries and read the Glue Data Catalog.
What is the difference between RBAC, ABAC, and tag-based access control?
RBAC attaches permissions to roles that map to job functions — simple, but roles and grants multiply as the organization grows. ABAC decides access by comparing attributes, such as an IAM condition matching aws:PrincipalTag to aws:ResourceTag, so one policy serves many teams. Tag-based access control in Lake Formation (LF-Tags) applies the same idea to data: permissions follow classification tags on databases, tables, and columns, and new resources inherit governance automatically.
How do I give Redshift analysts access without managing passwords?
Use IAM-based temporary database credentials: principals with the appropriate IAM permissions request short-lived credentials for a database user, which can be auto-created and joined to groups at login, and Redshift Serverless supports IAM-based sign-in directly. Pair this with database groups or RBAC roles that carry the actual GRANTs, and integrate IAM Identity Center if you want warehouse access tied to workforce single sign-on.
Why does explicit Deny matter so much in policy evaluation?
Because it is absolute: an explicit Deny in any applicable policy — identity, resource, permissions boundary, or service control policy — overrides every Allow, with no exceptions. That makes Deny statements the mechanism for non-negotiable guardrails, such as refusing S3 writes without encryption or blocking access from outside your VPC endpoint. It is also a debugging clue: if a correctly allowed action fails, look for a Deny elsewhere in the evaluation chain.
Should I use views instead of Lake Formation data filters for row-level security?
Views can filter rows, but you must create and maintain one per audience, per engine, and keep their logic synchronized as requirements change — and a principal with direct table access bypasses them. Lake Formation data filters attach the restriction to the table's permissions themselves, so every integrated engine enforces the same row and cell rules automatically, and revoking access is a single permission change.
Why do my Lake Formation grants seem to have no effect?
Usually because Lake Formation is still on its default settings, which grant Super to the IAMAllowedPrincipals group on new databases and tables so that IAM policies alone decide access. Revoke IAMAllowedPrincipals on the existing resources and clear the IAM-only defaults at account level and in each database's settings, or newly crawled tables will be IAM-governed again. Also remove direct s3:GetObject permissions from analyst roles, because Lake Formation does not intercept direct S3 API calls.
Why can't consumer-account analysts see a table shared with Lake Formation?
A table shared from another account lives in the producer's Data Catalog, so engines such as Amazon Athena cannot query it until the consumer's data lake administrator accepts the AWS RAM share and creates a resource link pointing to it. The administrator then grants analysts DESCRIBE on the resource link and SELECT on the link's target table; a resource link itself accepts only DESCRIBE and DROP.
Source
This lesson covers the "Data Security and Governance" domain of the official DEA-C01 exam guide. Vendors revise their guides — check the source for the current version.
- AWS Certified Data Engineer – Associate (DEA-C01) exam guide — Amazon Web Services
Sign up free to mark lessons complete, bookmark topics and track your exam readiness.