Skip to content

Conversation

@rix0rrr
Copy link
Contributor

@rix0rrr rix0rrr commented Oct 20, 2025

Instead of grants being attached to the L2 class, they are now available as separate classes.

For example, for Topic the grants are now available as the TopicGrants class. This class is exposed as a public member: public readonly grants: TopicGrants, and can be used like this:

myTopic.grants.publish(myRole);

The grantPublish etc methods on the L2 are now no longer recommended (though they will not be deprecated immediately to not disrupt existing code too much). Instead, all examples now use the new methods, and a linter will prevent new grantXxx() methods from being added to the L2 level. Instead, Grant classes should be written.

The grants class can also be used if you have an L1, and can be generated for services that don't have L2s yet.

They are currently driven from a datafile, grants.json, in the service module directory. This data source may move to the awscdk-service-spec repo in the future.

Example

An example of a generated grants class, for SNS topics:

/* eslint-disable @stylistic/max-len, eol-last */
import * as sns from "./sns.generated";
import * as iam from "aws-cdk-lib/aws-iam";

/**
 * Properties for TopicGrants
 */
interface TopicGrantsProps {
  /**
   * The resource on which actions will be allowed
   */
  readonly resource: sns.ITopicRef;

  /**
   * The resource with policy on which actions will be allowed
   *
   * @default - No resource policy is created
   */
  readonly policyResource?: iam.IResourceWithPolicyV2;

  /**
   * The encrypted resource on which actions will be allowed
   *
   * @default - No permission is added to the KMS key, even if it exists
   */
  readonly encryptedResource?: iam.IEncryptedResource;
}

/**
 * Collection of grant methods for a ITopicRef
 */
export class TopicGrants {
  /**
   * Creates grants for TopicGrants
   *
   * @internal
   */
  public static _fromTopic(resource: sns.ITopicRef): TopicGrants {
    return new TopicGrants({
      resource: resource,
      encryptedResource: (iam.GrantableResources.isEncryptedResource(resource) ? resource : undefined),
      policyResource: (iam.GrantableResources.isResourceWithPolicy(resource) ? resource : undefined)
    });
  }

  protected readonly resource: sns.ITopicRef;

  protected readonly encryptedResource?: iam.IEncryptedResource;

  protected readonly policyResource?: iam.IResourceWithPolicyV2;

  private constructor(props: TopicGrantsProps) {
    this.resource = props.resource;
    this.encryptedResource = props.encryptedResource;
    this.policyResource = props.policyResource;
  }

  /**
   * Grant topic publishing permissions to the given identity
   */
  public publish(grantee: iam.IGrantable): iam.Grant {
    const actions = ["sns:Publish"];
    const result = (this.policyResource ? iam.Grant.addToPrincipalOrResource({
      actions: actions,
      grantee: grantee,
      resourceArns: [sns.CfnTopic.arnForTopic(this.resource)],
      resource: this.policyResource
    }) : iam.Grant.addToPrincipal({
      actions: actions,
      grantee: grantee,
      resourceArns: [sns.CfnTopic.arnForTopic(this.resource)]
    }));
    this.encryptedResource?.grantOnKey(grantee, "kms:Decrypt", "kms:GenerateDataKey*");
    return result;
  }

  /**
   * Grant topic subscribing permissions to the given identity
   */
  public subscribe(grantee: iam.IGrantable): iam.Grant {
    const actions = ["sns:Subscribe"];
    const result = (this.policyResource ? iam.Grant.addToPrincipalOrResource({
      actions: actions,
      grantee: grantee,
      resourceArns: [sns.CfnTopic.arnForTopic(this.resource)],
      resource: this.policyResource
    }) : iam.Grant.addToPrincipal({
      actions: actions,
      grantee: grantee,
      resourceArns: [sns.CfnTopic.arnForTopic(this.resource)]
    }));
    return result;
  }
}

A few things to note:

  • The class can only be created via the static method _from<Resource>(). For now, while we experiment with this idea, this method is marked as internal, hence the _ leading the name.
  • If the JSON config for the class contains a keyActions, the generated class will also have an encryptedResource property, that allows the Grants class to add permissions to the key, if it's present. This is done via the IEncryptedResource interface.
  • If the JSON config for the class has hasPolicy: true, the generated class will also have a policyResource property, that allows the Grants class to create a resource policy.

Also in this PR

  • Cleanup around file pattern handling in spec2cdk, and a slight attempt at making it more obvious that spec2cdk has 2 distinct entry points; no attempt at reconciling these 2 entry points yet, I fear that's going to be a time suck.
  • JSON files for a subset of services.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

@github-actions github-actions bot added the p2 label Oct 20, 2025
@aws-cdk-automation aws-cdk-automation requested a review from a team October 20, 2025 10:39
@mergify mergify bot added the contribution/core This is a PR that came from AWS. label Oct 20, 2025
Copy link
Collaborator

@aws-cdk-automation aws-cdk-automation left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(This review is outdated)

otaviomacedo
otaviomacedo previously approved these changes Oct 21, 2025
{
"resources": {
"Topic": {
"targetField": "arn",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this what's going in the resourceArns in the call to Grant.addToPrincipalOrResource?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I was thinking yes

@rix0rrr rix0rrr force-pushed the huijbers-otaviom/grants branch from f1e9873 to 1cb6f2d Compare October 30, 2025 08:34
# Conflicts:
#	tools/@aws-cdk/spec2cdk/lib/cdk/ast.ts
#	tools/@aws-cdk/spec2cdk/lib/cdk/resource-class.ts
#	tools/@aws-cdk/spec2cdk/lib/cfn2ts/index.ts
#	tools/@aws-cdk/spec2cdk/lib/generate.ts
@otaviomacedo otaviomacedo removed the pr/do-not-merge This PR should not be merged at this time. label Nov 17, 2025
@otaviomacedo otaviomacedo added pr-linter/exempt-readme The PR linter will not require README changes pr-linter/exempt-integ-test The PR linter will not require integ test changes labels Nov 17, 2025
@aws-cdk-automation aws-cdk-automation dismissed their stale review November 17, 2025 17:01

✅ Updated pull request passes all PRLinter validations. Dismissing previous PRLinter review.

@mergify
Copy link
Contributor

mergify bot commented Nov 17, 2025

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@mergify
Copy link
Contributor

mergify bot commented Nov 17, 2025

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@mergify
Copy link
Contributor

mergify bot commented Nov 17, 2025

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@mergify mergify bot merged commit 21fd959 into main Nov 17, 2025
19 of 20 checks passed
@mergify mergify bot deleted the huijbers-otaviom/grants branch November 17, 2025 19:09
@github-actions
Copy link
Contributor

Comments on closed issues and PRs are hard for our team to see.
If you need help, please open a new issue that references this one.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 17, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

contribution/core This is a PR that came from AWS. p2 pr-linter/exempt-integ-test The PR linter will not require integ test changes pr-linter/exempt-readme The PR linter will not require README changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants