Skip to main content
cd ../config-traps
risk/register/lambda-execution-role-changes-never-revoke-resource-policy-invoke-access.html
AWS Lambda IAMhigh severityAmazon Web Services

Lambda Role Changes Don't Revoke Resource-Policy Invoke Access

Severity
high
Reviewed
17 Aug 2026
Remediation
~20 minutes
Overview

A team revokes an external partner's Lambda access by editing the execution role, but the invoke grant actually lives in a separate resource-based policy and remains active until removed directly.

Operational summary

At a glance

Symptom
An AWS account team revokes an external partner's access to a production Lambda function by stripping a policy statement from the function's execution role…
Likely cause
AWS Lambda enforces two independent permission layers, and only one of them was touched.
Impact
The blast radius is high because the retained invoke grant keeps a function callable by a principal the team believed had been cut off, and every successful invocation…
Verification signal
Validation is complete only when the resource-based policy no longer lists the removed statement and the previously authorised principal is actually denied on attempted invocation.Re-run aws lambda get-policy…
Safe correction
The fix is to remove the specific invoke-permission statement from the function's resource-based policy, not to make further changes to the execution role.aws lambda remove-permission --function-name payment-webhook-handler --statement-id…
Rollback or recovery
Rollback means restoring the exact resource-based policy statement that was removed, using the JSON captured before the change.aws lambda add-permission --function-name payment-webhook-handler --statement-id partner-invoke-2024 --action lambda:InvokeFunction --principal --source-arn…

Symptom

An AWS account team revokes an external partner’s access to a production Lambda function by stripping a policy statement from the function’s execution role, yet the partner’s system keeps invoking the function successfully days later. CloudTrail shows continued lambda:InvokeFunction calls from the partner’s AWS account, and the security team cannot explain why a role change had no effect on who can call the function.

False Assumption

The team assumed AWS Lambda’s execution role is the single control point for access to a function, so removing an IAM policy statement from that role would also remove an external account’s ability to invoke it. This treats “who can call the function” and “what the function’s code is allowed to do once it runs” as the same permission boundary, when AWS Lambda keeps them separate.

Root Cause

AWS Lambda enforces two independent permission layers, and only one of them was touched. The execution role is an identity-based policy: it governs the actions the function’s own code can take against other AWS services, such as writing to CloudWatch Logs or reading from a database. Invocation rights are governed by a separate resource-based policy attached directly to the function, managed with add-permission and remove-permission or the console’s function-level permissions view. A cross-account or service-to-service invoke grant, once added to that resource-based policy, remains in force until it is explicitly removed from that policy, regardless of any change made to the execution role.

Impact

The blast radius is high because the retained invoke grant keeps a function callable by a principal the team believed had been cut off, and every successful invocation still runs with the function’s live execution-role permissions. In a production account handling partner integrations, this can mean continued unauthorised access, unexpected cost from unbilled or unexpected invocations, or execution of business logic against live data long after the team believes access has been withdrawn. The exposure persists silently because no error, alert or failed deployment signals that the wrong policy layer was edited.

Diagnosis

Confirm the split by inspecting both policy layers rather than only the one that was changed.

aws lambda get-policy --function-name payment-webhook-handler

The returned resource-based policy document lists every statement with its principal, action and any source-arn or source-account condition. Compare the statement IDs and principals against the list of invokers the team believes are authorised. A statement referencing the partner’s account or role ARN that the team never removed is direct evidence of the retained grant.

aws iam get-role --role-name payment-webhook-handler-role

This confirms the execution role change was applied correctly and shows that it has no bearing on the resource-based statements found above; the two outputs describe different, non-overlapping permission surfaces. The console equivalent is comparing the function’s “Permissions” resource-based policy tab against the execution role’s attached policies side by side.

Correction

The fix is to remove the specific invoke-permission statement from the function’s resource-based policy, not to make further changes to the execution role.

aws lambda remove-permission --function-name payment-webhook-handler --statement-id partner-invoke-2024

Before running this, save the exact JSON of the statement being removed from the earlier get-policy output. If any access should be retained for a narrower set of callers, add it back deliberately with an explicit --source-arn or --source-account condition rather than leaving a broad or unconditioned grant in place.

Validation

Validation is complete only when the resource-based policy no longer lists the removed statement and the previously authorised principal is actually denied on attempted invocation.

  • Re-run aws lambda get-policy and confirm the statement ID is absent from the output.
  • From an isolated test copy of the calling principal, not the live partner integration, attempt an invocation and confirm an AccessDeniedException is returned.
  • Check CloudTrail or the function’s invocation logs over the following hours to confirm no further successful calls arrive from the removed principal.

Rollback

Rollback means restoring the exact resource-based policy statement that was removed, using the JSON captured before the change.

aws lambda add-permission --function-name payment-webhook-handler --statement-id partner-invoke-2024 --action lambda:InvokeFunction --principal <saved-principal> --source-arn <saved-source-arn>

Only restore the grant if removal turns out to have broken a legitimate, still-required integration; if the grant was correctly identified as unauthorised, do not restore it, and instead treat the rollback path as a documented option rather than a default action.

Prevention

Treat the resource-based policy and the execution role as two halves of one access-control decision, not sequential steps. Manage both under the same infrastructure-as-code definition, such as a single Lambda module that declares the execution role permissions and any resource-based policy statements together, so a review of one forces a review of the other. Schedule a periodic get-policy audit against the list of principals that should be able to invoke each production function, independent of any execution-role review, and require explicit sign-off before adding a new invoke grant with a broad or unconditioned principal.

03

Apply the safer control

Before you change production

Confirm the affected scope, export the current configuration, and test the replacement control in a non-production environment first.

Fix commands and configuration

lambda:InvokeFunction
add-permission
remove-permission
04

Verify, roll back or escalate

Verify

Validation is complete only when the resource-based policy no longer lists the removed statement and the previously authorised principal is actually denied on attempted invocation.Re-run aws lambda get-policy and confirm the statement ID is absent from the output.From an isolated…

Rollback

Rollback means restoring the exact resource-based policy statement that was removed, using the JSON captured before the change.aws lambda add-permission --function-name payment-webhook-handler --statement-id partner-invoke-2024 --action lambda:InvokeFunction --principal <saved-principal> --source-arn <saved-source-arn>Only restore the grant if removal turns out to have broken…

Escalate

Escalate when the blast radius is uncertain, the control cannot be tested safely, or remediation requires an outage or security exception.

After remediation

Further reading stays below the corrective workflow and is selected by platform, category and shared technical keywords.

Discover more

Connected KBY resources