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

# AWS

> Connect an AWS account to Expira with a read-only IAM user to track ACM, Private CA, RDS, IAM, SAML, Secrets Manager, KMS and Route 53 expiry.

Expira scans an AWS account and tracks everything in it that expires or needs rotating. It only uses read-only APIs: list and describe calls, plus the IAM credential report (it asks AWS to generate one when needed). It never reads a secret's value, only its rotation metadata.

## What Expira finds

Each type can be turned on or off per connection.

**Certificates and PKI**

| Type | Default | Notes |
| - | - | - |
| ACM certificates | On | Public and private certificates. Imported ones are flagged because they never auto-renew. |
| ACM Private CA | On | CA certificate expiry. Everything the CA issued stops working with it. |
| IAM server certificates | On | Legacy uploads for classic ELB and CloudFront. |
| RDS / Aurora CA certificates | On | Per-instance CA validity. Rotation needs a reboot. |
| Directory Service LDAPS | Off | Certificates registered on Managed Microsoft AD. |

**Credentials and secrets**

| Type | Default | Notes |
| - | - | - |
| IAM access key rotation | On | Access keys never expire in AWS. Expira tracks a rotation deadline: creation date + **Rotate after** (default 90 days). |
| IAM console passwords | On | Only when the account password policy sets a maximum age. |
| SAML identity providers | On | Metadata validity. Every federated login breaks when it lapses. |
| Secrets Manager rotation | On | The next scheduled rotation, for secrets that rotate. |
| Unrotated secrets | Off | Secrets with no rotation set up, flagged **Flag stale after** days (default 180) after their last change. Editing a secret's tags or description also counts as a change. |
| KMS keys pending deletion | On | Deletion makes everything the key encrypted unrecoverable. |

**Domains**

| Type | Default | Notes |
| - | - | - |
| Route 53 registered domains | On | Registration expiry and auto-renew status. |

## Connect an account

**1. Create a dedicated IAM user**

In the AWS console, go to **IAM → Users → Create user**. Don't give it console access; Expira only needs an access key.

**2. Attach the read-only policy**

Attach this policy to the user, as an inline policy or a customer-managed one. The same policy is in the connection form, with a **Copy** button.

```json Expira read-only policy theme={null} theme={null} theme={null} theme={null}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ExpiraReadOnlyDiscovery",
      "Effect": "Allow",
      "Action": [
        "sts:GetCallerIdentity",
        "ec2:DescribeRegions",
        "iam:ListAccountAliases",
        "acm:ListCertificates",
        "acm-pca:ListCertificateAuthorities",
        "iam:ListServerCertificates",
        "rds:DescribeDBInstances",
        "ds:DescribeDirectories",
        "ds:ListCertificates",
        "iam:ListUsers",
        "iam:ListAccessKeys",
        "iam:GenerateCredentialReport",
        "iam:GetCredentialReport",
        "iam:ListSAMLProviders",
        "secretsmanager:ListSecrets",
        "kms:ListKeys",
        "kms:ListAliases",
        "kms:DescribeKey",
        "route53domains:ListDomains"
      ],
      "Resource": "*"
    }
  ]
}
```

If you leave out actions for a service, those types show as **Skipped** after a sync instead of failing. See [Skipped types](#skipped-types).

**3. Create an access key**

Open the user, go to **Security credentials → Create access key**, and copy the access key ID and secret access key.

**4. Add the connection in Expira**

Go to **Integrations → AWS → Add connection** and fill in:

* **Display name**, for example "Production account".
* **Access key ID** (starts with `AKIA`).
* **Secret access key**.
* **Regions** (optional): a comma-separated list such as `eu-west-1, us-east-1`. Leave it blank to scan every enabled region. IAM and Route 53 are global and always scanned.
* The types to discover, and the rotation and staleness ages.

Save, then press **Sync** to scan now instead of waiting for the daily run at 07:30 UTC.

> [!TIP]
>
> Restricting regions makes each sync faster. Connect each AWS account separately: every account is one integration connection.

## Limits

* A key or secret more than 7 days past its rotation deadline shows as **Expired** on the dashboard, with no alert. That includes one that was already that far overdue when Expira first found it. Overdue keys and secrets are never removed while AWS still lists them.
* Each sync checks at most the first 1,000 IAM users and 500 KMS keys per region. When an account has more, the sync reports an error saying so, and nothing beyond the limit is removed.
* Turning a type off, or removing a region, stops updating its assets but keeps them, until 30 days after they expire. Delete them from **Assets** if you no longer want them.

## Skipped types

AWS returns `AccessDenied` when the policy doesn't allow a service. Expira treats this as normal and lists those types under the sync result: "Skipped (the IAM policy does not allow it): …". Add the missing actions to the policy to scan them.

Wrong credentials are different: a mistyped or revoked key fails the whole sync, so a bad key is never reported as a clean run.

## Rotate or revoke the key

To rotate, create a new access key, paste it into the connection's **Edit** form, and delete the old key in AWS. To disconnect, [remove the integration](https://docs.expira.dev/integrations/overview.md#pause-or-remove-an-integration), then delete the IAM user.

With **IAM access key rotation** turned on, Expira also tracks the rotation deadline of the key it uses itself, so you'll be reminded when it's due.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.