Join our Newsletter — 33% off our NHI Course
Home› Guides› AWS Lambda Security Guide: Execution Roles, Function URLs,…
Guide Cloud Security

AWS Lambda Security Guide: Execution Roles, Function URLs, Layers and Detection

PDF for newsletter subscribers · free to read online

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 27 October 2026 14 min read
On this page

Every AWS Lambda function is a non-human identity with its own IAM role, and the most damaging Lambda incidents come from that role being too broad, the function being callable by the wrong principal, or attackers creating functions of their own. This guide goes deeper than our cross-vendor Serverless Security Guide and focuses only on AWS Lambda: execution roles and iam:PassRole, resource-based policies and the confused deputy problem, function URL auth types, layers, environment variable encryption, code signing, CloudTrail data events and GuardDuty Lambda Protection. It is written for AWS platform engineers, cloud security teams and developers who own production functions.

Key takeaways

  • The execution role is the blast radius. Lambda assumes it on every invocation, so a code injection flaw inherits everything the role can do. Generate least-privilege policies from CloudTrail activity with IAM Access Analyzer before production.
  • Two policies decide access. The execution role controls what the function can reach; the function's resource-based policy controls who can invoke or manage it. Service grants without aws:SourceArn or aws:SourceAccount let other customers' resources trigger your function.
  • Function URLs with AuthType NONE are public. Enforce AWS_IAM with the lambda:FunctionUrlAuthType condition key in a service control policy, and remember that deleting a NONE URL does not delete its public resource policy.
  • Invocations are not logged by default. Invoke is a CloudTrail data event; enable it with advanced event selectors for sensitive functions, and alert on CreateFunction, UpdateFunctionCode and AddPermission management events.
  • Attackers use Lambda as a platform. In the 230 million AWS environments campaign, stolen keys were used to create an administrator role and deploy a scanning function to every region. Restrict who can create functions and pass roles.

How identity and access work in AWS Lambda

Lambda has three identity layers, and reviews often check only the first.

LayerWhat it controlsWhere it is definedMain risk
Execution roleWhat the function's code can do in AWSIAM role trusting the lambda.amazonaws.com service principalOver-permissive role turns any code flaw into account compromise
Resource-based policyWhich principals and services can invoke or manage the function, version or aliasFunction policy (put-resource-policy or add-permission)Unconditioned service or wildcard principals
Caller identity policiesWhich developers, pipelines and services can create, update or invoke functionsIAM identity policies, SCPs, permission boundarieslambda:UpdateFunctionCode or iam:PassRole held too widely

Execution role. AWS documents that the role's trust policy must name lambda.amazonaws.com and that Lambda assumes the role automatically on invocation, so code should not call sts:AssumeRole itself. The console's default role includes the managed policy AWSLambdaBasicExecutionRole, which grants permission to write to CloudWatch Logs. The runtime provides the role's temporary credentials to the code in the AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN environment variables, so any vulnerability that reads environment variables (server-side request forgery to a debug endpoint, a dependency that logs its environment, path traversal to /proc) exposes them. Those credentials are short-lived, which limits but does not remove the damage. AWS recommends reducing development-era permissions before production and using IAM Access Analyzer to generate a policy template from CloudTrail logs for a chosen date range, listing only the actions the function actually used.

Resource-based policy. Each function, version or alias can carry a policy granting other accounts, roles, organisations or services the right to call Lambda actions. AWS recommends full JSON policies through put-resource-policy over individual add-permission statements, because JSON policies support all IAM global condition keys, multiple principals and explicit Deny statements, while individual permissions support only aws:SourceArn, aws:SourceAccount and aws:PrincipalOrgID.

For role design patterns, see the AWS IAM Policies and Roles Guide.

Admin roles and privileged access

Several Lambda and IAM actions are privilege escalation paths, because they let a principal run code as a more powerful role.

PermissionWhy it is privilegedControl
iam:PassRole plus lambda:CreateFunctionCreates a function that runs with any role the caller can pass, including administrator rolesScope iam:PassRole to named Lambda roles and add the iam:PassedToService condition for lambda.amazonaws.com
lambda:UpdateFunctionCodeReplaces code running under an existing, possibly powerful, roleGrant only to the deployment pipeline role; enforce code signing
lambda:UpdateFunctionConfigurationCan change the role, layers, environment variables and VPC settingsPipeline-only; alert on use outside the pipeline
lambda:AddPermission and lambda:PutResourcePolicyOpens invocation to new accounts or the publicRestrict; Security Hub control Lambda.1 detects public function policies
lambda:CreateFunctionUrlConfig and lambda:UpdateFunctionUrlConfigCan create an unauthenticated HTTPS endpointSCP requiring lambda:FunctionUrlAuthType AWS_IAM
iam:CreateRole and iam:AttachRolePolicyLets a principal create a new execution role with any policyPermission boundaries for roles created by developers

The 230 Million AWS Cloud Environments Campaign shows the chain in practice: an IAM user's leaked keys could create roles and attach policies, the attackers created a role named lambda-ex with AdministratorAccess, and when EC2 launches failed they deployed a Lambda function named ex to every enabled region to scan for further exposed .env files. Separating role creation, PassRole and function creation would have broken that chain. See the AWS Organizations and SCPs Guide for organisation-level guardrails.

  • Human access: developers should deploy through a pipeline, not the console, in production accounts. Give humans read-only Lambda access plus break-glass for incidents.
  • One role per function: sharing an execution role across functions combines their permissions. A role per function also makes Access Analyzer's policy generation accurate.
  • Permission boundaries: where teams create their own execution roles, require a permission boundary so that no function role can exceed an agreed ceiling.

Integrations, API tokens and service accounts

Event sources and the confused deputy

Services such as Amazon S3, SNS and EventBridge invoke functions through a Service principal. A service principal acts for many customers, so a grant to s3.amazonaws.com without conditions could let another account's bucket trigger your function. AWS's examples scope such grants with aws:SourceAccount and aws:SourceArn, and show an explicit Deny for a specific bucket. For organisation-wide access, use aws:PrincipalOrgID (or aws:PrincipalOrgPaths for specific organisational units) rather than listing accounts or using an unconditioned wildcard. For event source mappings (SQS, Kinesis, DynamoDB streams), the execution role needs read permissions on the source; scope them to the specific queue or stream ARN. For messaging patterns, see the Amazon EventBridge, SNS and SQS Security Guide.

Function URLs

AuthTypeBehaviourUse for
AWS_IAMRequests must be SigV4-signed; access decided by the caller's identity policy and the function's resource policyService-to-service calls, internal tools
NONELambda performs no authentication; with a public resource policy, "any unauthenticated user with your function URL can invoke your function"Public webhooks only, with authentication in code (for example verifying a signature)

AWS states that from October 2025 new function URLs require both lambda:InvokeFunctionUrl and lambda:InvokeFunction permissions; without both, callers get 403 Forbidden even under NONE. The console and AWS SAM create the public policy for NONE automatically, with conditions lambda:FunctionUrlAuthType NONE and lambda:InvokedViaFunctionUrl true; the CLI, CloudFormation and the API do not. Deleting a NONE function URL does not delete that resource-based policy, so remove it manually. To block unauthenticated URLs organisation-wide, deny lambda:CreateFunctionUrlConfig and lambda:UpdateFunctionUrlConfig in an SCP when lambda:FunctionUrlAuthType is not AWS_IAM. If you need throttling, authorisers or WAF in front of a function, put it behind an API gateway instead. See the API Gateway Security Guide.

Secrets and environment variables

Lambda always encrypts environment variables at rest with a KMS key: by default an AWS managed key, optionally a customer managed key, in which case only users with access to that key can view or manage the variables. Users without kms:Decrypt can still manage the function but cannot see its variables. Encryption at rest does not make environment variables a secrets store: anyone with lambda:GetFunctionConfiguration and decrypt rights reads them in clear text. AWS recommends Secrets Manager rather than environment variables for database credentials. Store the secret's ARN in the environment variable, grant the execution role secretsmanager:GetSecretValue on that ARN only, and cache it in the function. CloudTrail omits the Environment parameter from CreateFunction and UpdateFunctionConfiguration records, which keeps values out of logs but also means CloudTrail cannot show you what was set. See the Cloud Secrets Managers Guide.

Layers

Layers are code that runs inside your function with its execution role, so a layer from another account is a supply chain dependency with full access to that role's credentials. Facts that matter for review: up to five layers per function; layer versions are immutable and must be referenced by exact version ARN; contents are extracted to /opt; using a layer requires lambda:GetLayerVersion, and cross-account use requires the owner to grant your account in the layer version's resource-based policy. Functions already using a layer version keep working if the version is deleted or your access is revoked, but new functions cannot use a deleted version. Layers only apply to .zip packages. Pin versions, prefer layers published from your own accounts, inventory every third-party layer ARN, and when code signing is enabled, AWS requires every added layer to be signed by an allowed profile.

Logging and detection

SourceWhat it recordsDetection use
CloudTrail management events (on by default)CreateFunction, UpdateFunctionCode, UpdateFunctionConfiguration, AddPermission, CreateFunctionUrlConfig, PublishLayerVersion, PutFunctionCodeSigningConfig, event source mapping changesAlert on changes outside the pipeline role, new public permissions, new URLs with NONE
CloudTrail data events (opt-in, charged)Invoke on AWS::Lambda::Function, filterable by resources.ARNWho invoked sensitive functions; unusual callers
LambdaESMDisabled (logged by default)Event source mapping for SQS, DynamoDB or Kinesis moved to Disabled, with codes such as AUTHORIZATION_ERRORPermission tampering or broken processing
GuardDuty Lambda ProtectionLambda network activity logs, including functions not attached to a VPC; no need to enable VPC Flow LogsFindings for suspicious network traffic such as cryptomining or command and control
Code signingSignatureValidationErrors CloudWatch metric and a CloudTrail warningUnsigned or untrusted deployment attempts
Security Hub CSPMLambda.1 public function policies; Lambda.2 supported runtimes; Lambda.3 in a VPC; Lambda.5 multiple Availability Zones; Lambda.6 tagged; Lambda.7 X-Ray active tracingPosture drift

CloudTrail event names carry a version suffix, for example UpdateFunctionCode20150331v2 and AddPermission20150331v2, so match on a prefix in detection rules. GuardDuty Lambda Protection does not cover Lambda@Edge. See the AWS CloudTrail Guide and the Amazon GuardDuty Guide.

Metrics:

  1. Percentage of execution roles generated or reviewed with Access Analyzer within the last 90 days, and count of roles with wildcard actions.
  2. Number of function URLs with AuthType NONE, each with a documented owner and in-code authentication.
  3. Number of resource policies with service principals lacking aws:SourceArn or aws:SourceAccount.
  4. Percentage of production functions with code signing in Enforce mode.
  5. Count of UpdateFunctionCode or UpdateFunctionConfiguration events not made by the pipeline role, target zero.
  6. Functions on deprecated runtimes (Security Hub Lambda.2 failures).

Hardening baseline

Roll out in this order. Each step can be piloted in a non-production account first.

  1. Inventory: list functions, roles, URLs, resource policies and layer ARNs across all regions (attackers deploy in regions you do not use). Enable Security Hub Lambda controls to get a baseline.
  2. Guardrails first: apply SCPs denying non-AWS_IAM function URLs, denying Lambda in unused regions, and restricting iam:PassRole for Lambda to the pipeline. Test in a sandbox organisational unit; roll back by detaching the SCP.
  3. Right-size roles: one role per function, generate a policy with IAM Access Analyzer from 30 to 90 days of CloudTrail activity, deploy it in a staging environment, run the test suite and watch for AccessDenied errors before production.
  4. Fix resource policies: add aws:SourceArn and aws:SourceAccount to every service grant and replace wildcard principals with aws:PrincipalOrgID.
  5. Move secrets: replace secrets in environment variables with Secrets Manager references and use a customer managed KMS key where you need to restrict who can read configuration.
  6. Code signing: create a code signing configuration with your Signer profiles in Warn mode, monitor SignatureValidationErrors, then switch to Enforce. Configurations only block new deployments, so redeploy signed packages to bring existing functions into scope. Roll back by switching to Warn.
  7. Detection: enable GuardDuty Lambda Protection, CloudTrail Invoke data events for sensitive functions, and alerts on the management events above.
  8. Runtime hygiene: keep functions on supported runtimes, use reserved concurrency to cap cost exposure, and set timeouts to what the function needs.

Small versus large estates: a team with a handful of functions can review roles by hand and rely on SCPs and Security Hub. Large estates should generate roles from templates with permission boundaries, block console deployment in production, and treat third-party layers as an approved software list.

Framework mapping

Lambda controlNIST SP 800-53 Rev 5NIST CSF 2.0MITRE ATT&CK risk addressed
Least-privilege execution roles, PassRole limitsAC-6 Least PrivilegePR.AA-05T1078.004 Cloud Accounts; T1098 Account Manipulation
Restrict function creation and unused regionsCM-7 Least FunctionalityPR.PS-01T1648 Serverless Execution; T1496 Resource Hijacking
Code signing, pinned layersSI-7 Software, Firmware, and Information Integrity; SR-11 Component AuthenticityPR.PS-01Supply chain tampering of function code
Secrets Manager, KMS for variablesSC-28 Protection of Information at RestPR.DS-01T1552.001 Credentials In Files
Function URL auth, API gatewayAC-3 Access EnforcementPR.AA-05T1190 Exploit Public-Facing Application
CloudTrail data events, GuardDutyAU-12 Audit Record GenerationDE.CM-09Detection of all of the above

In CIS Controls v8.1 these map mainly to Control 6 (Access Control Management), Control 16 (Application Software Security) and Control 8 (Audit Log Management); in ISO/IEC 27001:2022 to A.8.2 Privileged access rights, A.8.9 Configuration management and A.8.15 Logging.

Common misconfigurations

  • Shared admin-like roles: one execution role with broad permissions reused across many functions, often a development-era role nobody reduced.
  • Unconditioned service grants: lambda:InvokeFunction granted to s3.amazonaws.com or sns.amazonaws.com without aws:SourceArn or aws:SourceAccount.
  • Orphaned public policies: a NONE function URL deleted but its public resource-based policy left in place, or a URL created by SAM for a prototype and never removed.
  • Secrets in plain sight: API keys and database passwords in environment variables readable by every developer with GetFunctionConfiguration.
  • Unpinned third-party layers: layers from accounts nobody has assessed, running with the function's role credentials.
  • Blind spots: no Invoke data events, no alert on CreateFunction in unused regions, and GuardDuty Lambda Protection never enabled, so attacker-created functions run unnoticed.

Practitioner checklist

  • Give every function its own execution role and generate its policy from CloudTrail activity with IAM Access Analyzer.
  • Restrict iam:PassRole for Lambda roles, lambda:CreateFunction and lambda:UpdateFunctionCode to the deployment pipeline.
  • Add aws:SourceArn and aws:SourceAccount to all service principal grants and use aws:PrincipalOrgID instead of wildcards.
  • Deny function URLs that are not AWS_IAM with an SCP, and list any approved NONE exceptions.
  • Move secrets from environment variables to Secrets Manager and use customer managed KMS keys where needed.
  • Enable code signing in Enforce mode for production and pin layer versions from approved accounts.
  • Turn on GuardDuty Lambda Protection and CloudTrail Invoke data events for sensitive functions.
  • Alert on Lambda management events made outside the pipeline and on any function created in an unused region.
  • Track Security Hub Lambda.1 and Lambda.2 findings to zero.

Standards and references

Related NHI Mgmt Group resources: Serverless Security Guide · IAM Access Analyzer Guide · AWS IAM Policies and Roles Guide · Cloud Secrets Managers Guide · AWS Security Guide

PDF for subscribers

Take this guide with you

Every section, table and checklist in one PDF, with links to the sources and related guides. Subscribe to our weekly NHI & AI Identity Journal and we’ll email you a download link.

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 27 October 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org

PDF Downloads for Newsletter Subscribers

Get the guide

Enter your details and we’ll email you a download link.

The full guide is free to read online. The PDF is a thank you for subscribing.

Fill in all fields marked * and tick the PDF box to continue.