Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Imported DynamoDB TableV2 with fromTableArn does not get access to indexes with grantFullAccess #33896

Open
1 task
rlbrillband opened this issue Mar 24, 2025 · 3 comments
Labels
@aws-cdk/aws-dynamodb Related to Amazon DynamoDB bug This issue is a bug. effort/medium Medium work item – several days of effort p2

Comments

@rlbrillband
Copy link

Describe the bug

Related to 1540, but with a new caveat. There was previously a bug with granting constructs access to a table, where the policy it created would not grant access to any secondary indexes. This was addressed in PR 1564. Notably, I think this was before TableV2 was introduced.
However I have just found that, when importing with cdk.aws_dynamodb.TableV2.fromTableArn, grantFullAccess still does not give adequate permissions for indexes in that case.

Regression Issue

  • Select this option if this issue appears to be a regression.

Last Known Working CDK Version

No response

Expected Behavior

grantFullAccess should grant access to any indexes of the table.

Current Behavior

grantFullAccess does not access to any indexes of the table.

Reproduction Steps

1: Create a table with an index in AWS.
2: Import the table into a construct with fromTableArn
3: Do grantFullAccess to a lambda
4: Try to access the index from the lambda - this will fail to due inadequate permissions.

Possible Solution

I presume either:
1 - The ITableV2 created by fromTableArn may not be aware of the indexes on the imported table, so did not add permissions for them.
2 - Since TableV2 is newer than the fix, this may have been a regression. However I have not tested a v1 ITable so I can't confirm this.

Additional Information/Context

The table I imported where I discovered this is a couple of years old, and was originally created in AWS SAM, but that should not prevent this from working.

CDK CLI Version

2.1005.0 (build be378de)

Framework Version

2.181.1

Node.js Version

v20.15.1

OS

Ubuntu 24.04

Language

TypeScript

Language Version

5.6.3

Other information

This is the policy that was added:

{
			"Action": "dynamodb:*",
			"Resource": "arn:aws:dynamodb:eu-west-1:[account]:table/[mytablename]",
			"Effect": "Allow"
}

Notably lacking any permissions for /index

@rlbrillband rlbrillband added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Mar 24, 2025
@github-actions github-actions bot added the @aws-cdk/aws-dynamodb Related to Amazon DynamoDB label Mar 24, 2025
@pahud pahud self-assigned this Mar 25, 2025
@pahud
Copy link
Contributor

pahud commented Mar 26, 2025

When CDK use a resource using the fromXxx() method, it essentially builds a reference object with attributes on it. It's pretty much like you create a table out of CDK and now you need to reference it in your current CDK stack. In this case, CDK by default won't add or update any resource in this referenced resource.

Now when you grantFullAccess() to lambda, generally there would be an addToPrincipalOrResource() call happening, which essentially first add the identity-based policies when possible and optionally add to the resource-based policy. But dynamodb Table2 is a little bit different.

Root Cause

The issue stems from how hasIndex is determined when importing a table with fromTableArn():

  1. When using TableV2.fromTableArn(), it calls TableV2.fromTableAttributes()
  2. Inside fromTableAttributes(), a new Import class is created that extends TableBaseV2
  3. The hasIndex property is initialized as:

protected readonly hasIndex = (attrs.grantIndexPermissions ?? false) ||
(attrs.globalIndexes ?? []).length > 0 ||
(attrs.localIndexes ?? []).length > 0;

  1. Since no attributes are provided when using fromTableArn() directly, hasIndex defaults to false
  2. Later, when grantFullAccess() is called, the permission for indexes (${this.tableArn}/index/*) is NOT added:

const resourceArns = [this.tableArn];
this.hasIndex && resourceArns.push(`${this.tableArn}/index/*`);

Affected Code

private combinedGrant(grantee: IGrantable, options: { keyActions?: string[]; tableActions?: string[]; streamActions?: string[] }) {
if (options.keyActions && this.encryptionKey) {
this.encryptionKey.grant(grantee, ...options.keyActions);
}
if (options.tableActions) {
const resourceArns = [this.tableArn];
this.hasIndex && resourceArns.push(`${this.tableArn}/index/*`);
return Grant.addToPrincipalOrResource({
grantee,
actions: options.tableActions,
resourceArns,
resource: this,
});
}

Workaround

Explicitly provide the TableAttributesV2 with grantIndexPermissions: true:

TableV2.fromTableAttributes(scope, id, { 
  tableArn: 'arn:aws:dynamodb:region:account:table/name',
  grantIndexPermissions: true 
});

Simple Fix

Modify fromTableArn() to automatically set grantIndexPermissions: true when creating the imported table or simply expose this prop to the surface in a new options object.

Making this a p2 and we welcome PRs.

@pahud pahud added p2 effort/medium Medium work item – several days of effort labels Mar 26, 2025
@pahud pahud removed their assignment Mar 26, 2025
@pahud pahud removed the needs-triage This issue or PR still needs to be triaged. label Mar 26, 2025
@rlbrillband
Copy link
Author

Thanks for looking at this. Just to clarify - this is not intended behaviour? But it can be circumvented using fromTableAttributes with grantIndexPermissions: true. I will make use of that.
Out of curiosity, do you know why fromTableAttributes is designed not to have access to indexes by default? As a user this was clearly not what I expected (otherwise I wouldn't have considered this a bug). Perhaps there's some ideological motivation for it?

@pahud
Copy link
Contributor

pahud commented Mar 26, 2025

Hi,

I checked the source, the default value of grantIndexPermissions is false, which I am not sure if it makes perfect sense here but from least permission's perspective, I think it's acceptable and we are still allowed to customize it using the fromTableAttributes() method.

* @default false
*/
readonly grantIndexPermissions?: boolean;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-dynamodb Related to Amazon DynamoDB bug This issue is a bug. effort/medium Medium work item – several days of effort p2
Projects
None yet
Development

No branches or pull requests

2 participants