The most secure and AWS-recommended way for a Lambda function to access other AWS services is to use an IAM execution role. Lambda assumes this role at runtime and receives temporary credentials that are automatically rotated by AWS. The developer attaches the necessary permissions (the existing IAM policy) to that role, and then configures the Lambda function to use the role.
Option B follows least privilege and avoids long-term credentials. It also integrates with AWS security tooling: IAM Access Analyzer, CloudTrail, and policy boundaries can all be applied cleanly. Because the policy already exists, this requires minimal extra work: create/choose the execution role, attach the policy, and assign the role to the function.
Option A is not correct because IAM policies are attached to IAM identities (users, groups, roles) — not directly to Lambda functions as standalone entities. Lambda permissions are granted through the function’s execution role.
Option C is insecure because it uses long-term IAM user access keys embedded in environment variables. Even if encrypted, this expands the blast radius, complicates rotation, and contradicts AWS best practices for avoiding static credentials inside code/runtime.
Option D is extremely insecure and noncompliant. Root user access keys should not be used for applications and should generally not exist.
Therefore, create and attach the existing policy to a Lambda execution IAM role and assign that role to the function.