aws-cdk icon indicating copy to clipboard operation
aws-cdk copied to clipboard

(kms): PolicyDocument returned from key.addToResourcePolicy does not implement IDependable

Open BenChaimberg opened this issue 3 years ago • 3 comments

The kms.Key.addToResourcePolicy method should return an iam.AddToResourcePolicyResult which includes a policyDependable?: cdk.IDependable. However, the method returns an iam.PolicyDocument as the policy dependable, which does not implement cdk.IDependable (it is an empty interface since it's intended to be used as a trait marker but essentially allows any object to be treated as one). This causes a synthesis error when attempting to depend on an iam.Grant that is returned from a kms.Key.grant* method that adds statements to the resource policy (for example on an imported role).

Reproduction Steps

import * as iam from '@aws-cdk/aws-iam';
import * as kms from '@aws-cdk/aws-kms';
import * as cdk from '@aws-cdk/core';

class TestConstruct extends Construct {
  constructor(scope: Construct, id: string) {
    super(scope, id);

    const role = iam.Role.fromRoleArn(this, 'Role', 'arn:aws:iam::111122223333:role/my-role');
    const key = new kms.Key(this, 'Key');
    const keyGrant = key.grantEncryptDecrypt(role);
    const someResource = new cdk.CfnResource(this, 'Some Resource', {
      type: 'AWS::Service::Resource'
    });
    keyGrant.applyBefore(someResource);
  }
}

What did you expect to happen?

A DependsOn clause is added to the CFN resource that sets an explicit dependency of the resource on the generated IAM policy.

What actually happened?

An error is thrown during synthesis:

Error: ${Token[PolicyDocument.33]} does not implement DependableTrait
    at Function.get (@aws-cdk/core/lib/dependency.ts:88:13)
    at Object.get dependencyRoots [as dependencyRoots] (@aws-cdk/aws-iam/lib/grant.ts:252:61)
    at Node.get dependencies [as dependencies] (constructs/src/construct.ts:247:61)
    at ConstructNode.get dependencies [as dependencies] (@aws-cdk/core/lib/construct-compat.ts:533:69)
    at Object.prepareApp (@aws-cdk/core/lib/private/prepare-app.ts:20:38)
    at Object.synthesize (@aws-cdk/core/lib/private/synthesis.ts:24:3)
    at App.synth (@aws-cdk/core/lib/stage.ts:180:23)
    at process.<anonymous> (@aws-cdk/core/lib/app.ts:125:45)
    at Object.onceWrapper (node:events:514:26)
    at process.emit (node:events:394:28)

Environment

  • CDK CLI Version : 1.115.0
  • Framework Version: 1.115.0
  • Node.js Version: 16.3.0
  • OS : macOS 11.4 (20F71)
  • Language (Version): all

Other

Surfaced in #15547.


This is :bug: Bug Report

BenChaimberg avatar Jul 28 '21 02:07 BenChaimberg

Something like Policy implements the Dependable trait via extending constructs.Construct, which implements the DependableTrait privately: https://github.com/aws/constructs/blob/4e15f3bea526f7a9d08dac7f778918f5ece3ce58/src/construct.ts#L580-L583

I suppose the return from Key.addToResourcePolicy could be changed to an (unexported) class that also privately implements the trait. Marking as a p2, as I'm not aware of any of use cases or users impacted by this.

njlynch avatar Aug 24 '21 10:08 njlynch

To clarify, the returned type is PolicyDocument, not Policy. The former does not extend Construct and so does not implement DependableTrait.

@madeline-k and I ran into this problem in #15547. It was non-blocking since the policy is embedded into the key itself so there is no need to depend on the policy itself. However, it is a false advertisement of the IDependable interface and throws an unexpected error.

BenChaimberg avatar Aug 24 '21 17:08 BenChaimberg

This issue has not received any attention in 1 year. If you want to keep this issue open, please leave a comment below and auto-close will be canceled.

github-actions[bot] avatar Sep 22 '22 12:09 github-actions[bot]