Documentation
Environment
AWS credentials

AWS credentials on AWS Lambda

When your PHP application runs on AWS Lambda, it automatically has access to AWS credentials. This means you don't need to manage AWS access keys or credentials in your code - Lambda handles this for you.

⚠️

Don't deploy AWS access keys in your Lambda functions or environment variables. Lambda provides credentials automatically.

This is a common mistake when migrating an existing application to AWS Lambda.

How it works

Lambda functions automatically get AWS access keys in their environment variables. These credentials are temporary and managed by AWS, so you don't have to worry about rotating them or keeping them secure.

echo $_SERVER['AWS_ACCESS_KEY_ID']; // AKIAIOSFODNN7EXAMPLE
echo $_SERVER['AWS_SECRET_ACCESS_KEY']; // wJalrXUtnFEM
echo $_SERVER['AWS_SESSION_TOKEN']; // AQoEXAMPLEH4aoAH0gNCAPy...

The PHP AWS SDK automatically detects and uses them. Here's an example with S3:

$s3 = new \Aws\S3\S3Client([
    'version' => 'latest',
    'region' => $_SERVER['AWS_REGION'],
    // No credentials needed, the SDK uses the environment variables automatically
]);
 
// Use S3 normally
$result = $s3->putObject([
    'Bucket' => 'my-bucket',
    'Key' => 'file.txt',
    'Body' => 'Hello from Lambda!'
]);
 
// Note that this also works with https://async-aws.com

Note that Laravel and Symfony automatically pick up these permissions too.

These credentials have access controlled by an IAM role defined in serverless.yml.

By default, Lambda functions don't have any access (principle of least privilege). To access other AWS services (like S3 or SQS), you need to add permissions to that IAM role in serverless.yml (read below).

Adding permissions

To grant your Lambda function access to AWS services, add IAM statements to your serverless.yml:

service: my-app
 
provider:
    name: aws
    iam:
        role:
            statements:
                # IAM statements here...
 
functions:
    # ...

Example: S3

To read and write files to an S3 bucket:

provider:
    name: aws
    iam:
        role:
            statements:
                # Allow Lambda to read and write to S3
                -   Effect: Allow
                    Action:
                        - s3:GetObject
                        - s3:PutObject
                        - s3:DeleteObject
                    Resource: arn:aws:s3:::my-bucket/*
                # Allow listing bucket contents
                -   Effect: Allow
                    Action: s3:ListBucket
                    Resource: arn:aws:s3:::my-bucket
💡

If you use the Lift storage construct to create S3 buckets, it automatically adds the necessary permissions (opens in a new tab) to your functions. No need to set up permissions manually!

Example: SQS

To send and receive messages from SQS queues:

provider:
    name: aws
    iam:
        role:
            statements:
                # Allow Lambda to access an SQS queue
                -   Effect: Allow
                    Action:
                        - sqs:SendMessage
                        - sqs:ReceiveMessage
                        - sqs:DeleteMessage
                        - sqs:GetQueueAttributes
                    Resource: arn:aws:sqs:${aws:region}:${aws:accountId}:my-queue
💡

If you use the Lift queue construct to create SQS queues, it automatically adds the necessary permissions (opens in a new tab) to your functions. No need to set up permissions manually!

Common services and permissions

Here are the IAM actions you'll typically need for common AWS services:

DynamoDB

-   Effect: Allow
    Action:
        - dynamodb:GetItem
        - dynamodb:PutItem
        - dynamodb:UpdateItem
        - dynamodb:DeleteItem
        - dynamodb:Query
        - dynamodb:Scan
    Resource: arn:aws:dynamodb:${aws:region}:${aws:accountId}:table/my-table

Secrets Manager

-   Effect: Allow
    Action: secretsmanager:GetSecretValue
    Resource: arn:aws:secretsmanager:${aws:region}:${aws:accountId}:secret:my-secret-*

SNS (notifications)

-   Effect: Allow
    Action: sns:Publish
    Resource: arn:aws:sns:${aws:region}:${aws:accountId}:my-topic

EventBridge

-   Effect: Allow
    Action: events:PutEvents
    Resource: arn:aws:events:${aws:region}:${aws:accountId}:event-bus/my-event-bus

SSM Parameter Store

-   Effect: Allow
    Action:
        - ssm:GetParameter
        - ssm:GetParameters
    Resource: arn:aws:ssm:${aws:region}:${aws:accountId}:parameter/my-app/*

Troubleshooting

Access Denied errors

If you get "Access Denied" errors when trying to use AWS services:

  1. Check that you've added the correct IAM permissions in serverless.yml
  2. Verify the resource ARN is correct (bucket name, queue name, etc.)
  3. Make sure you've redeployed after adding permissions
  4. Check the logs for the exact error message

Testing locally

When testing locally remember that you will need to provide AWS credentials since you're not running on Lambda. You can set them up via long-lived AWS access keys or IAM roles with SSO.

Permissions per function

If you want to define permissions per function, instead of globally (ie: in the provider), you can install the plugin serverless-iam-roles-per-function (opens in a new tab) and then use the iamRoleStatements at the function definition block.

Learn more