Can't set writeable or readable properties on user pool client

I am trying to configure my user pool client to have write access to user pool attributes. The following code works fine if I comment out the WriteAttributes property, but by default AWS doesn’t set write access to custom attributes, which in this case I have one which is called role. But when I leave it in, I get this error:

An error occurred while provisioning your stack: WebAppUserPoolWebClient - Invalid write attributes specified while updating a client (Service: AWSCognitoIdentityProvider; Status Code: 400; Error Code: InvalidParameterException;

I’m not sure what is wrong. On the AWS docs it says I need to provide a string, but it doesn’t mention what format it should be in exactly. I’ve tried just role, even "role" but nothing seems to work and I always get that same error. Any help would be appreciated.

WebAppUserPoolWebClient:
  Type: "AWS::Cognito::UserPoolClient"
  Properties:
      ClientName: Web
      GenerateSecret: false
      UserPoolId:
        Ref: WebAppUserPool
      WriteAttributes: 
        - custom:role
2 Likes

I figured it out. If you have a custom attribute, you need to define it as "custom:<attribute>" where <attribute> is your custom attribute. It must be wrapped in quotes!

6 Likes

One more thing here: You must not include the “custom:” prefix in the Name when you actually define the Schema attribute, or else it’ll end up getting called “custom:custom:attributename” and you’ll get the error “Invalid read attributes specified while creating a client” or “Invalid write attributes specified while creating a client” when you go to reference it in ReadAttributes/WriteAttributes.

1 Like

Thank you , I mean it , THANK you.

I found another requirement: In the write attributes, you actually have to declare all attributes you defined in your Schema. For readAttributes this is not the case.

1 Like

And another one:
In your cloudformation schema section, just state the name without custom:. In the Attributes section, you need the custom prefix.
eg

      Schema:
        -
          Name: "roles"
          AttributeDataType: "String"
          DeveloperOnlyAttribute: false
          Mutable: true
          Required: false
          StringAttributeConstraints:
            MaxLength: "2048"
...
      WriteAttributes: 
        - custom:roles

Testing it I found you can declare some of it. So if I want to limit changes, I will declare some attributes but also “given_name” which I don’t care about, Which will make defining “WriteAttributes” with “given_name” only possible to block all others.

Unfortunately… this trick require to set up a pool correctly from the start… so blocking write on attributes on old must be done manually.