What it is
AWS Identity and Access Management, IAM, controls who and what can use AWS resources. People and services get users or roles, and policies list exactly which actions they may take on which resources. Everything else is denied. Roles are how AWS code gets permissions without storing keys: a Lambda function assumes its role when it runs.
Origin Access Control, OAC, is a CloudFront feature that signs every request CloudFront sends to an origin with AWS Signature Version 4. The origin, an S3 bucket or a Lambda function URL, then accepts requests only from that distribution. The bucket or function is never reachable directly, so the CDN and its security headers cannot be bypassed.
How I use it
- Every Lambda function on mervinc.com has its own least-privilege IAM role. The agent's role names the Bedrock inference profile and model, nothing broader.
- Function URLs use IAM auth and accept requests only from this CloudFront distribution, SigV4-signed with the payload hash checked.
- The site's pages sit in a private S3 bucket, served only through CloudFront with origin access control.
- Separate AWS accounts per business, and narrowly scoped IAM users for the scripts that deploy them. Lend Pilot runs in its own account.
IAM is not optional on AWS, but least privilege takes deliberate work: one role per function, naming only what that function touches. OAC is the right tool whenever CloudFront fronts S3 or Lambda, because it makes the CDN the only door. I use both so a mistake in one function cannot reach the rest.
Questions
What is least privilege on AWS?
Each piece of code gets a role that allows only the actions and resources it needs. On my site every function has its own role, so one bug cannot reach the others.
How do you keep a Lambda function URL private?
Use IAM auth on the URL and an origin access control on CloudFront. The function then answers only signed requests from that one distribution.