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

(cognito-idp): cannot use Cognito identity pool for role mappings #19222

Closed
2 tasks
michaeljfazio opened this issue Mar 3, 2022 · 16 comments · Fixed by #21191
Closed
2 tasks

(cognito-idp): cannot use Cognito identity pool for role mappings #19222

michaeljfazio opened this issue Mar 3, 2022 · 16 comments · Fixed by #21191
Labels
@aws-cdk/aws-iam Related to AWS Identity and Access Management effort/small Small work item – less than a day of effort feature-request A feature should be added or improved. good first issue Related to contributions. See CONTRIBUTING.md p2

Comments

@michaeljfazio
Copy link

michaeljfazio commented Mar 3, 2022

Description

The following role mapping will fail:

 const identityPool = new IdentityPool(this, "IdentityPool", {
      roleMappings: [
        {
          providerUrl: IdentityPoolProviderUrl.custom(userPool.userPoolProviderUrl),
          resolveAmbiguousRoles: false,
          useToken: true
        }
      ]
    })

The reason it will fail is because the internal logic is to map the provided URL as the corresponding key value, which is performed here.

The same function is achieved in Cloudformation by specifying the key separately from the provider url. See notes specified under the IdentityProvider field description.

Use Case

Referencing user pool from the same stack.

Proposed Solution

Allow the ability to optionally specify static key when creating a role mapping.

Other information

Possible (untested) workaround is to create role attachment with Cfn resource and manually assign an arbitrary key.

    const identityPool = new IdentityPool(this, "IdentityPool", {
      allowUnauthenticatedIdentities: false
    })

    new CfnIdentityPoolRoleAttachment(this, "RoleAttachment2", {
      identityPoolId: identityPool.identityPoolId,
      roleMappings: {
        cognito: { // 👈 manually specified key of "cognito"
          type: "Token",
          ambiguousRoleResolution: "Deny",
          identityProvider: userPool.userPoolProviderUrl
        }
      }
    }).node.addDependency(identityPool)

Acknowledge

  • I may be able to implement this feature request
  • This feature might incur a breaking change
@michaeljfazio michaeljfazio added feature-request A feature should be added or improved. needs-triage This issue or PR still needs to be triaged. labels Mar 3, 2022
@github-actions github-actions bot added the @aws-cdk/aws-iam Related to AWS Identity and Access Management label Mar 3, 2022
@rix0rrr
Copy link
Contributor

rix0rrr commented Mar 7, 2022

It looks like this is because there is no Cognito provider type in this enum:

export enum IdentityPoolProviderType {
/** Facebook Provider type */
FACEBOOK = 'Facebook',
/** Google Provider Type */
GOOGLE = 'Google',
/** Amazon Provider Type */
AMAZON = 'Amazon',
/** Apple Provider Type */
APPLE = 'Apple',
/** Twitter Provider Type */
TWITTER = 'Twitter',
/** Digits Provider Type */
DIGITS = 'Digits',
/** Open Id Provider Type */
OPEN_ID = 'OpenId',
/** Saml Provider Type */
SAML = 'Saml',
/** User Pool Provider Type */
USER_POOL = 'UserPool',
/** Custom Provider Type */
CUSTOM = 'Custom',
}

Feel free to submit it.

@rix0rrr rix0rrr changed the title (cognito-idp): Cannot Resolve Role Mapping Provider URL from Local Resource (cognito-idp): cannot use Cognito identity pool for role mappings Mar 7, 2022
@rix0rrr rix0rrr added effort/small Small work item – less than a day of effort good first issue Related to contributions. See CONTRIBUTING.md p2 and removed needs-triage This issue or PR still needs to be triaged. labels Mar 7, 2022
@rix0rrr rix0rrr removed their assignment Mar 7, 2022
@SamStephens
Copy link
Contributor

SamStephens commented Jul 7, 2022

@rix0rrr said:

It looks like this is because there is no Cognito provider type in this enum:

export enum IdentityPoolProviderType {
/** Facebook Provider type */
FACEBOOK = 'Facebook',
/** Google Provider Type */
GOOGLE = 'Google',
/** Amazon Provider Type */
AMAZON = 'Amazon',
/** Apple Provider Type */
APPLE = 'Apple',
/** Twitter Provider Type */
TWITTER = 'Twitter',
/** Digits Provider Type */
DIGITS = 'Digits',
/** Open Id Provider Type */
OPEN_ID = 'OpenId',
/** Saml Provider Type */
SAML = 'Saml',
/** User Pool Provider Type */
USER_POOL = 'UserPool',
/** Custom Provider Type */
CUSTOM = 'Custom',
}

I don't think it's as simple as that.

IdentityPoolProviderType provides the USER_POOL constant, which I believe is for Cognito User Pools. IdentityPoolProviderUrl provides a userPool method that uses this constant. The documentation includes an example of IdentityPoolProviderUrl.userPool being used with a Cognito user pool provider URL.

I'm using the IdentityPoolProviderUrl.userPool method, and getting the same results.

 const identityPool = new IdentityPool(this, "IdentityPool", {
      roleMappings: [
        {
          providerUrl: IdentityPoolProviderUrl.userPool(userPool.userPoolProviderUrl),
          resolveAmbiguousRoles: false,
          useToken: true
        }
      ]
    })

(or more accurately, the Python equivalent, as I use Python). userPool is of course an earlier instantated aws_cognito.UserPool construct.

The specific error message we're getting is similar to

Error: Resolution error: Resolution error: "${Token[TOKEN.209]}" is used as the key in a map so must resolve to a string, but it resolves to: {"Fn::GetAtt":["UserPool6BA7E5F2","ProviderURL"]}. Consider using "CfnJson" to delay resolution to deployment-time..

The problem being that as @michaeljfazio points out, the provider URL is used as the key of a map. However map keys do not allow for Tokens, only for string constants.

As @michaeljfazio also points out, the solution is to stop providing the identity provider using the role mapping keys, and instead use the IdentityProvider attribute of the role mapping object. The existing code already sets the attribute. So all that is needed is to stop using the provider URL as the map key.

What the map key should be instead of the provider URL is an open question. Maybe it could be an optional parameter to IdentityPoolRoleMapping that you are required to provide if the providerUrl is a Token.

@SamStephens
Copy link
Contributor

FYI, the issue is currently incorrectly labelled @aws-cdk/aws-iam.

@SamStephens
Copy link
Contributor

The possible workaround that @michaeljfazio provides does not work, because an IdentityPool creates a DefaultRoleAttachment, and the CfnIdentityPoolRoleAttachment suggested conflicts with the existing DefaultRoleAttachment.

@alukach
Copy link
Contributor

alukach commented Jul 13, 2022

@SamStephens Thanks for your comments. I have been hitting my head against this (also using Python). Your description of the issue is inline with my thinking.

However, I get a bit lost when you describe the solution.

stop providing the identity provider using the role mapping keys, and instead use the IdentityProvider attribute of the role mapping object. The existing code already sets the attribute. So all that is needed is to stop using the provider URL as the map key.

What the map key should be instead of the provider URL is an open question.

Are you suggesting a change to CDK, or is this a change to CloudFormation itself? Reading through the AWS::Cognito::IdentityPoolRoleAttachment docs, I see:

RoleMappings
How users for a specific identity provider are mapped to roles. This is a string to the RoleMapping object map. The string identifies the identity provider. For example: graph.facebook.com or cognito-idp.us-east-1.amazonaws.com/us-east-1_abcdefghi:app_client_id.

At the end of the day, CDK will need to populate the RoleMappings on the CloudFormation Template. To create the Cognito IDP key, CDK is going to need to resolve the tokens at time of synthesis due to the fact that it's a CloudFormation restriction that keys can't be composed of tokens, correct?

As a workaround, I was trying to apply some ideas from #12988 (i.e. leaning on CfnIdentityPoolRoleAttachment) but ran into some other issues. I'll report back here if I make any progress. Please do let me know if you find a path forward.

@SamStephens
Copy link
Contributor

@alukach this would be a CDK change.

If you have a look at the documentation for a RoleMapping, it says:

IdentityProvider: Identifier for the identity provider for which the role is mapped. For example: graph.facebook.com or cognito-idp.us-east-1.amazonaws.com/us-east-1_abcdefghi:app_client_id (http://cognito-idp.us-east-1.amazonaws.com/us-east-1_abcdefghi:app_client_id). This is the identity provider that is used by the user for authentication.

If the identity provider property isn't provided, the key of the entry in the RoleMappings map is used as the identity provider.

I read this as saying that if the IdentityProvider is provided, then the key of the Role Mapping can be any arbitrary string, it does not also have to be the identifier for the identity provider. I have not verified this experimentally, however.

You can see this from the template my CDK currently generates. I've hardcoded the identity provider temporarily to work around this issue. The role mapping generated for my attachment is:

    "RoleMappings": {
     "cognito-idp.us-west-2.amazonaws.com/us-west-2_pool_id:client_id": {
      "AmbiguousRoleResolution": "Deny",
      "IdentityProvider": "cognito-idp.us-west-2.amazonaws.com/us-west-2_pool_id:client_id",
      "Type": "Token"
     }
    },

See the identity provider is there as the key in RoleMappings, but also present as IdentityProvider.

I'm suggesting we provide a way for the CDK to generate this as:

    "RoleMappings": {
     "cognito": {
      "AmbiguousRoleResolution": "Deny",
      "IdentityProvider": "cognito-idp.us-west-2.amazonaws.com/us-west-2_pool_id:client_id",
      "Type": "Token"
     }
    },

Instead.

@alukach
Copy link
Contributor

alukach commented Jul 13, 2022

@SamStephens Thanks for the clarification.

I read this as saying that if the IdentityProvider is provided, then the key of the Role Mapping can be any arbitrary string, it does not also have to be the identifier for the identity provider.

This does indeed track with the example in the AWS::Cognito::IdentityPoolRoleAttachment docs, wherein the key is a generic userpool1:

IdentityPoolRoleAttachment: 
  Type: AWS::Cognito::IdentityPoolRoleAttachment 
  Properties: 
    IdentityPoolId: !Ref IdentityPool
    Roles: 
      "authenticated": !GetAtt AuthenticatedRole.Arn 
      "unauthenticated": !GetAtt UnAuthenticatedRole.Arn 
    RoleMappings:  
      "graph.facebook.com":
        IdentityProvider: "graph.facebook.com" 
        AmbiguousRoleResolution: Deny 
        Type: Rules 
        RulesConfiguration: 
          Rules: 
            - Claim: "sub" 
              MatchType: "Equals" 
              RoleARN: !GetAtt AuthenticatedRole.Arn 
              Value: "goodvalue"
      "userpool1": 
        IdentityProvider: !Ref CognitoUserPool 
        AmbiguousRoleResolution: Deny 
        Type: Rules 
        RulesConfiguration: 
          Rules: 
            - Claim: "sub" 
              MatchType: "Equals" 
              RoleARN: !GetAtt AuthenticatedRole.Arn 
              Value: "goodvalue"

I will do my best to find some time tomorrow to play around with the CDK lib and see if I can make such a change in the lib (not sure how to cross-compile to Python locally, so we'll see how this goes...)

@SamStephens
Copy link
Contributor

@alukach Awesome; I'm not working this week, but am back next week and would have time to look at this.

I think the main challenge is working out how the RoleMappings keys should be defined now they're no longer always the IdentityProvider.

I think we need to be careful that this scheme is resilient, that a given identity provider always retains the same key.

For a concrete example of what I mean, a naive solution would be just to make all the keys be numbered incrementally: roleMapping1, roleMapping2, and so on. So the role mappings you show above might look like:

IdentityPoolRoleAttachment: 
  Type: AWS::Cognito::IdentityPoolRoleAttachment 
  Properties: 
    IdentityPoolId: !Ref IdentityPool
    Roles: 
      "authenticated": !GetAtt AuthenticatedRole.Arn 
      "unauthenticated": !GetAtt UnAuthenticatedRole.Arn 
    RoleMappings:  
      "roleMapping1":
        IdentityProvider: "graph.facebook.com" 
        AmbiguousRoleResolution: Deny 
        Type: Rules 
        RulesConfiguration: 
          Rules: 
            - Claim: "sub" 
              MatchType: "Equals" 
              RoleARN: !GetAtt AuthenticatedRole.Arn 
              Value: "goodvalue"
      "roleMapping2": 
        IdentityProvider: !Ref CognitoUserPool 
        AmbiguousRoleResolution: Deny 
        Type: Rules 
        RulesConfiguration: 
          Rules: 
            - Claim: "sub" 
              MatchType: "Equals" 
              RoleARN: !GetAtt AuthenticatedRole.Arn 
              Value: "goodvalue"

The problem being that if you add a new role mapping to the beginning of the role mapping list, the keys of all the existing mappings will change:

IdentityPoolRoleAttachment: 
  Type: AWS::Cognito::IdentityPoolRoleAttachment 
  Properties: 
    IdentityPoolId: !Ref IdentityPool
    Roles: 
      "authenticated": !GetAtt AuthenticatedRole.Arn 
      "unauthenticated": !GetAtt UnAuthenticatedRole.Arn 
    RoleMappings:  
      "roleMapping1":
        IdentityProvider: "new.provider.com" 
        AmbiguousRoleResolution: Deny 
        Type: Rules 
        RulesConfiguration: 
          Rules: 
            - Claim: "sub" 
              MatchType: "Equals" 
              RoleARN: !GetAtt AuthenticatedRole.Arn 
              Value: "badvalue"
      "roleMapping2":
        IdentityProvider: "graph.facebook.com" 
        AmbiguousRoleResolution: Deny 
        Type: Rules 
        RulesConfiguration: 
          Rules: 
            - Claim: "sub" 
              MatchType: "Equals" 
              RoleARN: !GetAtt AuthenticatedRole.Arn 
              Value: "goodvalue"
      "roleMapping3": 
        IdentityProvider: !Ref CognitoUserPool 
        AmbiguousRoleResolution: Deny 
        Type: Rules 
        RulesConfiguration: 
          Rules: 
            - Claim: "sub" 
              MatchType: "Equals" 
              RoleARN: !GetAtt AuthenticatedRole.Arn 
              Value: "goodvalue"

My take is that the cleanest way to deal with this is to not make the CDK generate the keys; to have them provided by users.

I'd do this by adding a roleMappingName optional string to IdentityPoolRoleMapping.

I'd then update the role mapping logic to use that name if it's provided. Change the map setting code to be:

if (prop.roleMappingName) {
  acc[prop.roleMappingName] = roleMapping;
} else {
  acc[prop.providerUrl.value] = roleMapping;
}

A nice side effect of doing it this way is that the code is backwards compatible. Existing role mappings continue to work as before, but you can provide a roleMappingName to avoid using the providerUrl as the key in the role mapping hash.

@SamStephens
Copy link
Contributor

@rix0rrr or @kaizencc I've put together a pull request to solve this. It'd be great to get someone to look at this; it's not possible to define a CDK User Pool and then define an Identity Pool using that User Pool for role mapping without this fix; a use case that seems like it would be relatively common.

Thanks.

@mergify mergify bot closed this as completed in #21191 Jul 30, 2022
mergify bot pushed a commit that referenced this issue Jul 30, 2022
…s not provided and it is a token (#21191)

This property is for use when the identityProvider is a Token. By default identityProvider is used as the key in the role mapping
hash, but Cloudformation only allows concrete strings to be used as hash keys.

In particular this feature is a requirement to allow a previously defined CDK UserPool to be used as an identityProvider.

closes #19222

Please note that the integ test results will need updating. I attempted to run the tests, and received the error

```
Error: ENOENT: no such file or directory, open '/home/sam/aws-cdk/packages/aws-cdk/lib/init-templates/v1/info.json'
  ERROR      integ.identitypool 0.535s
      Command exited with status 1
```

I've used `npm` to update to the latest CDK CLI. I appear to not be the only person facing this issue; see #21056 (comment)

----

### All Submissions:

* [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Unconventional Dependencies:

* [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies)

### New Features

* [x] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
@github-actions
Copy link

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

@alukach
Copy link
Contributor

alukach commented Aug 2, 2022

@SamStephens I obviously was unable to resolve this. Thanks so much for the fix, works like a charm!

@SamStephens
Copy link
Contributor

@SamStephens I obviously was unable to resolve this. Thanks so much for the fix, works like a charm!

Perfect. We're not going to use Cognito, so I've not seen any benefit from doing this, so I'm glad it's proved useful for someone 😁

@alukach
Copy link
Contributor

alukach commented Aug 2, 2022

@SamStephens Actually, I may have spoken too soon. Now seeing: (https://cognito-idp.us-west-2.amazonaws.com/us-west-2_ABCDEFGHI) is not a valid RoleMapping ProviderName or is not a configured provider. (Service: AmazonCognitoIdentity; Status Code: 400; Error Code:

Can you help me understand what is going on in this line?

const providerUrl = Fn.importValue('ProviderUrl');

For reference, here's my code (Python):

    def _create_identity_pool(
        self, userpool: cognito.UserPool
    ) -> cognito_id_pool.IdentityPool:
        userpool_provider = cognito_id_pool.UserPoolAuthenticationProvider(
            user_pool=userpool,
        )

        return cognito_id_pool.IdentityPool(
            self,
            "identity_pool",
            identity_pool_name=f"{Stack.of(self).stack_name} IdentityPool",
            authentication_providers=cognito_id_pool.IdentityPoolAuthenticationProviders(
                user_pools=[
                    userpool_provider,
                ],
            ),
            role_mappings=[
                cognito_id_pool.IdentityPoolRoleMapping(
                    provider_url=cognito_id_pool.IdentityPoolProviderUrl.user_pool(
                        # HACK: Need to manually provide this as per:
                        # https://github.com/aws/aws-cdk/issues/19222
                        userpool.user_pool_provider_url
                    ),
                    use_token=True,
                    mapping_key="userpool1",
                )
            ],
        )

@SamStephens
Copy link
Contributor

@alukach

const providerUrl = Fn.importValue('ProviderUrl');

Is a simple way to get a Token for the sake of the unit test. In real world usage, you'd use Fn.importValue to import a value exported from another stack. You might do this if you have a user pool declared in one Cloudformation/CDK stack, and then want to declare an identity pool that integrates with it in another.

In real world usage you'd be more likely to do what you're doing. I just didn't do that in the unit tests to keep them as simple as possible.

As to why what you're doing is failing, it's hard for me to say. I suspect it isn't a problem with the construct itself but the userpool.user_pool_provider_url value that's being passed in. This error is the Cognito service telling you that https://cognito-idp.us-west-2.amazonaws.com/us-west-2_ABCDEFGHI is not a valid provider URL.

To confirm that it's not a problem with this fix, I'd hard-code the value in, and see if you get the same error:

    def _create_identity_pool(
        self, userpool: cognito.UserPool
    ) -> cognito_id_pool.IdentityPool:
        userpool_provider = cognito_id_pool.UserPoolAuthenticationProvider(
            user_pool=userpool,
        )

        return cognito_id_pool.IdentityPool(
            self,
            "identity_pool",
            identity_pool_name=f"{Stack.of(self).stack_name} IdentityPool",
            authentication_providers=cognito_id_pool.IdentityPoolAuthenticationProviders(
                user_pools=[
                    userpool_provider,
                ],
            ),
            role_mappings=[
                cognito_id_pool.IdentityPoolRoleMapping(
                    provider_url=cognito_id_pool.IdentityPoolProviderUrl.user_pool(
                        # Use your actual provider URL here
                        'https://cognito-idp.us-west-2.amazonaws.com/us-west-2_ABCDEFGHI'),
                    ),
                    use_token=True,
                    # No mapping_key
                )
            ],
        )

If this fails with the same error you reported above, then the issue is not with this fix.

Looking at my code, when I hard-coded the provider URL (to work around this issue, before I solved it), my URL didn't include the https:// prefix. So if what I have above fails, try:

    def _create_identity_pool(
        self, userpool: cognito.UserPool
    ) -> cognito_id_pool.IdentityPool:
        userpool_provider = cognito_id_pool.UserPoolAuthenticationProvider(
            user_pool=userpool,
        )

        return cognito_id_pool.IdentityPool(
            self,
            "identity_pool",
            identity_pool_name=f"{Stack.of(self).stack_name} IdentityPool",
            authentication_providers=cognito_id_pool.IdentityPoolAuthenticationProviders(
                user_pools=[
                    userpool_provider,
                ],
            ),
            role_mappings=[
                cognito_id_pool.IdentityPoolRoleMapping(
                    provider_url=cognito_id_pool.IdentityPoolProviderUrl.user_pool(
                        # Use your actual provider URL here, without the https:// prefix.
                        'cognito-idp.us-west-2.amazonaws.com/us-west-2_ABCDEFGHI'),
                    ),
                    use_token=True,
                )
            ],
        )

If you find it is the https:// prefix that is causing the issue, you'll need to log a separate bug against the CDK for them to sort that out.

Good luck.

@sudopla
Copy link

sudopla commented Aug 3, 2022

@SamStephens thanks a lot for fixing this! I ran into this issue tonight, saw this thread and when updated the CDK everything worked perfectly.

@alukach
Copy link
Contributor

alukach commented Aug 12, 2022

Thanks @SamStephens, you're spot on, the following did the trick:

    def _create_identity_pool(
        self, userpool: cognito.UserPool
    ) -> cognito_id_pool.IdentityPool:
        client = self.add_programmatic_client(
            "cognito-identity-pool-auth-provider",
            name="Identity Pool Authentication Provider",
        )

        userpool_provider = cognito_id_pool.UserPoolAuthenticationProvider(
            user_pool=userpool,
            user_pool_client=client,
        )

        return cognito_id_pool.IdentityPool(
            self,
            "identity_pool",
            identity_pool_name=f"{Stack.of(self).stack_name} IdentityPool",
            authentication_providers=cognito_id_pool.IdentityPoolAuthenticationProviders(
                user_pools=[userpool_provider],
            ),
            role_mappings=[
                cognito_id_pool.IdentityPoolRoleMapping(
                    provider_url=cognito_id_pool.IdentityPoolProviderUrl.user_pool(
                        f"cognito-idp.{Stack.of(userpool).region}.amazonaws.com/{userpool.user_pool_id}:{client.user_pool_client_id}"
                    ),
                    use_token=True,
                    mapping_key="userpool",
                )
            ],
        )

To smooth over this process, I'm proposing #21585

josephedward pushed a commit to josephedward/aws-cdk that referenced this issue Aug 30, 2022
…s not provided and it is a token (aws#21191)

This property is for use when the identityProvider is a Token. By default identityProvider is used as the key in the role mapping
hash, but Cloudformation only allows concrete strings to be used as hash keys.

In particular this feature is a requirement to allow a previously defined CDK UserPool to be used as an identityProvider.

closes aws#19222

Please note that the integ test results will need updating. I attempted to run the tests, and received the error

```
Error: ENOENT: no such file or directory, open '/home/sam/aws-cdk/packages/aws-cdk/lib/init-templates/v1/info.json'
  ERROR      integ.identitypool 0.535s
      Command exited with status 1
```

I've used `npm` to update to the latest CDK CLI. I appear to not be the only person facing this issue; see aws#21056 (comment)

----

### All Submissions:

* [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Unconventional Dependencies:

* [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies)

### New Features

* [x] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-iam Related to AWS Identity and Access Management effort/small Small work item – less than a day of effort feature-request A feature should be added or improved. good first issue Related to contributions. See CONTRIBUTING.md p2
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants