> ## Documentation Index
> Fetch the complete documentation index at: https://docs.prowler.com/llms.txt
> Use this file to discover all available pages before exploring further.

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://docs.prowler.com/feedback

```json
{
  "path": "/user-guide/providers/aws/authentication",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# AWS Authentication in Prowler

Prowler requires AWS credentials to function properly. Authentication is available through the following methods:

* Static Credentials
* Assumed Role

When using **Assumed Role**, the Prowler UI exposes two credential sources for calling `sts:AssumeRole`. The labels differ between Prowler Cloud and self-hosted Prowler App, but both map to the same underlying credential types:

* **AWS SDK Default** (shown as *"Prowler Cloud will assume your IAM role"* in Prowler Cloud and *"AWS SDK Default"* in self-hosted Prowler App): Prowler uses the credentials already available to the API and worker containers through the [AWS SDK default credential chain](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html). This is the default in Prowler Cloud and requires extra configuration in self-hosted Prowler App (see [Configuring AWS SDK Default for Self-Hosted Prowler App](#configuring-aws-sdk-default-for-self-hosted-prowler-app)).
* **Access & Secret Key**: You paste an IAM user's `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and optionally `AWS_SESSION_TOKEN` into the form. Prowler uses those keys to call `sts:AssumeRole`.

## Required Permissions

To ensure full functionality, attach the following AWS managed policies to the designated user or role:

* `arn:aws:iam::aws:policy/SecurityAudit`
* `arn:aws:iam::aws:policy/job-function/ViewOnlyAccess`

### Additional Permissions

For certain checks, additional read-only permissions are required. Attach the following custom policy to your role: [prowler-additions-policy.json](https://github.com/prowler-cloud/prowler/blob/master/permissions/prowler-additions-policy.json)

## Assume Role (Recommended)

This method grants permanent access and is the recommended setup for production environments.

<Tabs>
  <Tab title="CloudFormation">
    1. Download the [Prowler Scan Role Template](https://raw.githubusercontent.com/prowler-cloud/prowler/refs/heads/master/permissions/templates/cloudformation/prowler-scan-role.yml)

           <img src="https://mintcdn.com/prowler/3MeTQEK7UW2A9QiV/images/providers/prowler-scan-role-template.png?fit=max&auto=format&n=3MeTQEK7UW2A9QiV&q=85&s=1edf1caeb3cfd336a65d6bb59a48e5dc" alt="Prowler Scan Role Template" width="2518" height="797" data-path="images/providers/prowler-scan-role-template.png" />

           <img src="https://mintcdn.com/prowler/VEKBBm2VL7R8-xYV/images/providers/download-role-template.png?fit=max&auto=format&n=VEKBBm2VL7R8-xYV&q=85&s=b2ac197fa1a12dd7003b26fbc31e9008" alt="Download Role Template" width="1241" height="455" data-path="images/providers/download-role-template.png" />

    2. Open the [AWS Console](https://console.aws.amazon.com), search for **CloudFormation**

           <img src="https://mintcdn.com/prowler/VEKBBm2VL7R8-xYV/images/providers/cloudformation-nav.png?fit=max&auto=format&n=VEKBBm2VL7R8-xYV&q=85&s=13596ccb401e7cd768733a0df90af8b4" alt="CloudFormation Search" width="1063" height="308" data-path="images/providers/cloudformation-nav.png" />

    3. Go to **Stacks** and click "Create stack" > "With new resources (standard)"

           <img src="https://mintcdn.com/prowler/VEKBBm2VL7R8-xYV/images/providers/create-stack.png?fit=max&auto=format&n=VEKBBm2VL7R8-xYV&q=85&s=b8b2a25dc47c27ca8d9a8ab9f6db3ab0" alt="Create Stack" width="914" height="456" data-path="images/providers/create-stack.png" />

    4. In **Specify Template**, choose "Upload a template file" and select the downloaded file

           <img src="https://mintcdn.com/prowler/cmPhg0PQUNFwgauQ/images/providers/upload-template-file.png?fit=max&auto=format&n=cmPhg0PQUNFwgauQ&q=85&s=cc2171a89e6a80ea42dae39fe025d0ce" alt="Upload a template file" width="659" height="751" data-path="images/providers/upload-template-file.png" />

           <img src="https://mintcdn.com/prowler/cmPhg0PQUNFwgauQ/images/providers/upload-template-from-downloads.png?fit=max&auto=format&n=cmPhg0PQUNFwgauQ&q=85&s=da46dfe45de14126e6e7ff654a988697" alt="Upload file from downloads" width="865" height="501" data-path="images/providers/upload-template-from-downloads.png" />

    5. Click "Next", provide a stack name and the **External ID** shown in the Prowler Cloud setup screen

           <img src="https://mintcdn.com/prowler/3MeTQEK7UW2A9QiV/images/providers/prowler-cloud-external-id.png?fit=max&auto=format&n=3MeTQEK7UW2A9QiV&q=85&s=05e2af36242c2051a337ed344a911b6f" alt="External ID" width="1172" height="806" data-path="images/providers/prowler-cloud-external-id.png" />

           <img src="https://mintcdn.com/prowler/3MeTQEK7UW2A9QiV/images/providers/fill-stack-data.png?fit=max&auto=format&n=3MeTQEK7UW2A9QiV&q=85&s=aea65d657787c8998f9dadd0469b3dbb" alt="Stack Data" width="1985" height="885" data-path="images/providers/fill-stack-data.png" />

           <Info>
             An **External ID** is required when assuming the *ProwlerScan* role to prevent the [confused deputy problem](https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html).
           </Info>

    6. Acknowledge the IAM resource creation warning and proceed

           <img src="https://mintcdn.com/prowler/cmPhg0PQUNFwgauQ/images/providers/stack-creation-second-step.png?fit=max&auto=format&n=cmPhg0PQUNFwgauQ&q=85&s=adb50400ace2594bd543ca8512599baf" alt="Stack Creation Second Step" width="1977" height="842" data-path="images/providers/stack-creation-second-step.png" />

    7. Click "Submit" to deploy the stack

           <img src="https://mintcdn.com/prowler/cmPhg0PQUNFwgauQ/images/providers/submit-third-page.png?fit=max&auto=format&n=cmPhg0PQUNFwgauQ&q=85&s=bf904bbe52bd7cf77264645def7ce595" alt="Click on submit" width="1984" height="893" data-path="images/providers/submit-third-page.png" />
  </Tab>

  <Tab title="Terraform">
    To provision the scan role using Terraform:

    1. Run the following commands:

       ```bash theme={null}
       terraform init
       terraform plan
       terraform apply
       ```
  </Tab>
</Tabs>

***

## Configuring AWS SDK Default for Self-Hosted Prowler App

When self-hosting Prowler App with Docker Compose, the API and worker containers do not have AWS credentials by default. Selecting **AWS SDK Default** without configuring those credentials produces:

```
AWSAssumeRoleError[1012]: AWS assume role error - An error occurred (InvalidClientTokenId) when calling the AssumeRole operation: The security token included in the request is invalid.
```

To fix this, expose an IAM identity with `sts:AssumeRole` permission on the target role to both the `api` and `worker` services.

### Option 1: Environment Variables in `.env`

Add the following keys to the `.env` file used by `docker-compose.yml`:

```bash theme={null}
AWS_ACCESS_KEY_ID="<your-access-key-id>"
AWS_SECRET_ACCESS_KEY="<your-secret-access-key>"
AWS_SESSION_TOKEN="<optional-session-token>"
AWS_DEFAULT_REGION="us-east-1"
```

The existing `docker-compose.yml` already loads `.env` into the `api`, `worker`, and `worker-beat` services, so `boto3` will pick them up through the default credential chain.

<Warning>
  Treat the `.env` file as a secret. Do not commit it to version control, scope the IAM identity to the minimum permissions required (`sts:AssumeRole` on the target `ProwlerScan` role only), prefer short-lived credentials over long-lived access keys, and rotate the keys immediately if you suspect exposure.
</Warning>

Recreate the containers to apply the change. A plain `docker compose restart` will **not** reload values from a modified `.env` file — you must force-recreate:

```bash theme={null}
docker compose up -d --force-recreate api worker worker-beat
```

### Option 2: IAM Role (Host with Instance Metadata)

If you run Prowler App on an EC2 instance, ECS task, or EKS pod with an attached IAM role that can assume the scan role, no extra configuration is needed — `boto3` resolves credentials through instance or task metadata automatically.

### Trust Policy: Align `IAMPrincipal` With Your Identity

The [Prowler scan role CloudFormation template](https://github.com/prowler-cloud/prowler/blob/master/permissions/templates/cloudformation/prowler-scan-role.yml) restricts the trust policy with:

```
aws:PrincipalArn  StringLike  arn:aws:iam::<AccountId>:<IAMPrincipal>
```

`IAMPrincipal` defaults to `role/prowler*`, which only allows IAM roles whose name starts with `prowler`. If the identity hosting the API and worker containers is anything else, the `sts:AssumeRole` call fails with `AccessDenied` even when the credentials themselves are valid.

Redeploy (or update) the CloudFormation stack with an `IAMPrincipal` that matches your identity:

| Your identity on the API/worker containers       | `IAMPrincipal` value    |
| ------------------------------------------------ | ----------------------- |
| IAM user (for example `prowler-app`)             | `user/prowler-app`      |
| IAM role whose name doesn't start with `prowler` | `role/<your-role-name>` |

`AccountId` must also point to the account where that identity lives — the default is Prowler Cloud's account and only applies when assuming from Prowler Cloud.

<Note>
  The same `External ID` entered in the Prowler UI must match the `ExternalId` parameter used when deploying the CloudFormation stack. A mismatch produces `AccessDenied` on `sts:AssumeRole`, not `InvalidClientTokenId`.
</Note>

***

## Credentials

<Tabs>
  <Tab title="Long term credentials">
    1. Go to the [AWS Console](https://console.aws.amazon.com), open **CloudShell**

           <img src="https://mintcdn.com/prowler/VEKBBm2VL7R8-xYV/images/providers/aws-cloudshell.png?fit=max&auto=format&n=VEKBBm2VL7R8-xYV&q=85&s=a25bc51d28015c73a18299467a09abcf" alt="AWS CloudShell" width="638" height="93" data-path="images/providers/aws-cloudshell.png" />

    2. Run:

       ```bash theme={null}
       aws iam create-access-key
       ```
  </Tab>

  <Tab title="Short term credentials (Recommended)">
    Use the [AWS Access Portal](https://docs.aws.amazon.com/singlesignon/latest/userguide/howtogetcredentials.html) or the CLI:

    1. Retrieve short-term credentials for the IAM identity using this command:

       ```bash theme={null}
       aws sts get-session-token --duration-seconds 900
       ```

           <Note>
             Check the aws documentation [here](https://docs.aws.amazon.com/IAM/latest/UserGuide/sts_example_sts_GetSessionToken_section.html)
           </Note>

    2. Copy the output containing:

       * `AccessKeyId`

       * `SecretAccessKey`

       * `SessionToken`

       > Sample output:

       ```json theme={null}
       {
           "Credentials": {
               "AccessKeyId": "ASIAIOSFODNN7EXAMPLE",
               "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY",
               "SessionToken": "AQoEXAMPLEH4aoAH0gNCAPyJxz4BlCFFxWNE1OPTgk5TthT+FvwqnKwRcOIfrRh3c/LTo6UDdyJwOOvEVPvLXCrrrUtdnniCEXAMPLE/IvU1dYUg2RVAJBanLiHb4IgRmpRV3zrkuWJOgQs8IZZaIv2BXIa2R4OlgkBN9bkUDNCJiBeb/AXlzBBko7b15fjrBs2+cTQtpZ3CYWFXG8C5zqx37wnOE49mRl/+OtkIKGO7fAE",
               "Expiration": "2020-05-19T18:06:10+00:00"
           }
       }
       ```
  </Tab>
</Tabs>
