Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions site/docs/guides/iam-auth/aws.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ To find the correct issuer value:

3. Find the **Data Planes** table and make sure you're viewing the correct tab for your data plane (either **public** or **private**).

4. Copy the value from the **IAM OIDC** column. This should look something like: `https://openid.estuary.dev/your-data-plane-identifier.dp.estuary-data.com/`
4. Copy the value from the **IAM OIDC** column. This should look something like: `https://openid.estuary.dev/your-data-plane-identifier.dp.estuary-data.com`

For example, these are the issuer values for a few common public data planes:

| Data Plane | Issuer |
|---|---|
| US east-1 AWS data plane | https://openid.estuary.dev/aws-us-east-1-c1.dp.estuary-data.com/ |
| US central-1 GCP data plane | https://openid.estuary.dev/gcp-us-central1-c2.dp.estuary-data.com/ |
| US west-2 AWS data plane | https://openid.estuary.dev/aws-us-west-2-c1.dp.estuary-data.com/ |
| EU west-1 AWS data plane | https://openid.estuary.dev/aws-eu-west-1-c1.dp.estuary-data.com/ |
| US east-1 AWS data plane | https://openid.estuary.dev/aws-us-east-1-c1.dp.estuary-data.com |
| US central-1 GCP data plane | https://openid.estuary.dev/gcp-us-central1-c2.dp.estuary-data.com |
| US west-2 AWS data plane | https://openid.estuary.dev/aws-us-west-2-c1.dp.estuary-data.com |
| EU west-1 AWS data plane | https://openid.estuary.dev/aws-eu-west-1-c1.dp.estuary-data.com |

![Add Identity Provider](../guide-images/aws-iam-1.png)

Expand Down
105 changes: 105 additions & 0 deletions site/docs/reference/Connectors/capture-connectors/amazon-dynamodb.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,85 @@ To use this connector, you'll need:
}
```

**Example IAM Policy for Specific Tables:**

If you want to limit access to specific tables rather than all tables, use this policy. Note that `ListTables` and `DescribeTable` require the `table/*` resource pattern and cannot be scoped to specific tables.

```json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SpecificTableAccess",
"Effect": "Allow",
"Action": [
"dynamodb:DescribeStream",
"dynamodb:GetShardIterator",
"dynamodb:GetRecords",
"dynamodb:Scan"
],
"Resource": [
"arn:aws:dynamodb:<REGION>:<ACCOUNT_ID>:table/<TABLE_NAME>",
"arn:aws:dynamodb:<REGION>:<ACCOUNT_ID>:table/<TABLE_NAME>/stream/*"
]
},
{
"Sid": "DiscoveryAccess",
"Effect": "Allow",
"Action": [
"dynamodb:ListTables",
"dynamodb:DescribeTable"
],
"Resource": "arn:aws:dynamodb:<REGION>:<ACCOUNT_ID>:table/*"
}
]
}
```

**Terraform Example with IAM Role:**

When using Terraform to create both the OIDC provider and IAM role, you may encounter a circular dependency since the OIDC provider needs the role ARN as its audience, but the role needs the OIDC provider ARN in its trust policy. Use `locals` to construct the role ARN before creating it:

```hcl
data "aws_caller_identity" "current" {}

locals {
role_name = "EstuaryDynamoDB"
role_arn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${local.role_name}"
}

resource "aws_iam_openid_connect_provider" "estuary" {
url = "https://openid.estuary.dev/1234567890abcdef.dp.estuary-data.com"
client_id_list = [local.role_arn]
thumbprint_list = ["<THUMBPRINT>"]
}

resource "aws_iam_role" "estuary_dynamodb" {
name = local.role_name

assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = {
Federated = aws_iam_openid_connect_provider.estuary.arn
}
Action = "sts:AssumeRoleWithWebIdentity"
Condition = {
StringEquals = {
"openid.estuary.dev/1234567890abcdef.dp.estuary-data.com:aud" = local.role_arn
}
StringLike = {
"openid.estuary.dev/1234567890abcdef.dp.estuary-data.com:sub" = "your-tenant/*"
}
}
}]
})
}
```

Replace `1234567890abcdef.dp.estuary-data.com` with your data plane identifier from the Estuary dashboard.

- AWS Credentials. One of the following types:
- The AWS **access key** and **secret access key** for the user. See the [AWS blog](https://aws.amazon.com/blogs/security/wheres-my-secret-access-key/) for help finding these credentials.
- To authenticate using an AWS Role, you'll need the **region** and the **role arn**. Follow the steps in the [AWS IAM guide](/guides/iam-auth/aws.md) to setup the role.
Expand Down Expand Up @@ -121,3 +200,29 @@ captures:
Your capture definition may be more complex, with additional bindings for each DynamoDB table.

[Learn more about capture definitions.](../../../concepts/captures.md#specification)

## Troubleshooting

### "No OpenIDConnect provider found"

The OIDC provider URL doesn't match what AWS expects. Verify:
- The URL in AWS matches exactly what's shown in the Estuary connector config
- Check for trailing slash mismatches (the URL should not have a trailing slash)

### "Not authorized to perform sts:AssumeRoleWithWebIdentity"

The trust policy conditions don't match. Verify:
- The `aud` claim matches your role ARN exactly
- The `sub` claim pattern matches your Estuary tenant prefix
- Wait 1-2 minutes after creating or updating the OIDC provider for AWS propagation

### Tables not appearing in bindings

If your DynamoDB tables don't appear when configuring the capture:
- Verify DynamoDB Streams is enabled on the table
- Verify the stream view type is set to "New and old images"
- Verify your IAM policy includes `ListTables` permission on `table/*`

### "dynamodb:ListTables... AccessDeniedException"

The `ListTables` action requires the `table/*` resource pattern. You cannot scope this permission to specific table names—it must have access to list all tables in the region.
Loading