-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
aws-cognito: can't set custom attribute as non-writable #30608
Comments
@njeirath Good morning. Based on my testing, I think this is a limitation of CloudFormation (not CDK).
So, in order for your scenario to work, we would need to ensure non-empty import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as cognito from 'aws-cdk-lib/aws-cognito';
export class Issue30608Stack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const userPool = new cognito.UserPool(this, 'UserPool', {
userPoolName: 'TestPool',
signInCaseSensitive: false,
selfSignUpEnabled: true,
userVerification: {
emailSubject: 'Verify your email',
emailBody: 'Thanks for signing up! Your verification code is {####}',
emailStyle: cognito.VerificationEmailStyle.CODE
},
signInAliases: {
email: true
},
accountRecovery: cognito.AccountRecovery.EMAIL_ONLY,
advancedSecurityMode: cognito.AdvancedSecurityMode.AUDIT,
customAttributes: {
'tier': new cognito.NumberAttribute({mutable: true})
}
});
const client = userPool.addClient('AppClient', {
preventUserExistenceErrors: true,
readAttributes: new cognito.ClientAttributes()
.withStandardAttributes({
email: true,
emailVerified: true,
phoneNumberVerified: true}),
writeAttributes: new cognito.ClientAttributes()
.withStandardAttributes({
email: true
})
});
}
} This generated the below CloudFormation template: Resources:
UserPool6BA7E5F2:
Type: AWS::Cognito::UserPool
Properties:
AccountRecoverySetting:
RecoveryMechanisms:
- Name: verified_email
Priority: 1
AdminCreateUserConfig:
AllowAdminCreateUserOnly: false
AutoVerifiedAttributes:
- email
EmailVerificationMessage: Thanks for signing up! Your verification code is {####}
EmailVerificationSubject: Verify your email
Schema:
- AttributeDataType: Number
Mutable: true
Name: tier
SmsVerificationMessage: The verification code to your new account is {####}
UserPoolAddOns:
AdvancedSecurityMode: AUDIT
UserPoolName: TestPool
UsernameAttributes:
- email
UsernameConfiguration:
CaseSensitive: false
VerificationMessageTemplate:
DefaultEmailOption: CONFIRM_WITH_CODE
EmailMessage: Thanks for signing up! Your verification code is {####}
EmailSubject: Verify your email
SmsMessage: The verification code to your new account is {####}
UpdateReplacePolicy: Retain
DeletionPolicy: Retain
Metadata:
aws:cdk:path: Issue30608Stack/UserPool/Resource
UserPoolAppClientDD0407EC:
Type: AWS::Cognito::UserPoolClient
Properties:
AllowedOAuthFlows:
- implicit
- code
AllowedOAuthFlowsUserPoolClient: true
AllowedOAuthScopes:
- profile
- phone
- email
- openid
- aws.cognito.signin.user.admin
CallbackURLs:
- https://example.com
PreventUserExistenceErrors: ENABLED
ReadAttributes:
- email
- email_verified
- phone_number_verified
SupportedIdentityProviders:
- COGNITO
UserPoolId:
Ref: UserPool6BA7E5F2
WriteAttributes:
- email
Metadata:
aws:cdk:path: Issue30608Stack/UserPool/AppClient/Resource
... After deployment, we get the results as you expected for your scenario: Thanks, |
@ashishdhingra Thanks for the response. That was the workaround I ended up using as well which worked for my use case. What I'm wondering is given my original code: writeAttributes: new cognito.ClientAttributes()
.withStandardAttributes({
emailVerified: false,
phoneNumberVerified: false,
})
.withCustomAttributes() Would it be better for the generated UserPoolAppClientDD0407EC:
Type: AWS::Cognito::UserPoolClient
Properties:
...
WriteAttributes: ['address', 'birthdate', ...] #All standard attributes except email_verified and phone_number_verified That way any custom attributes would be set to not allow writing unless they were explicitly passed to |
@njeirath Based on the implementation and CloudFormation spec, one needs to explicitly specify the list. That's the reason why standard attributes are supported in the form of mask, which could be turned on/off. This is a convenience so that one doesn't need to remember standard attribute names. Also, changing the default behavior to include all standard attributes by default is a breaking change and undermines the default Cognito behavior to app can write the values of the Standard attributes of your user pool if not explicitly set. Thanks, |
This issue has not received a response in a while. If you want to keep this issue open, please leave a comment below and auto-close will be canceled. |
I think the issue is that an empty list does not only allow writing of standard attributes but also custom attributes. As you mentioned, the CloudFormation docs say So an empty list passed to This would still allow masking out any of the standard attributes the user does not want to include by leaving it off the generated list but would have the added benefit of allowing one to opt in to including custom attributes. I understand this could be considered a breaking change but wondering if it would be useful for this behavior to be added to a new class like |
@njeirath The write behavior on custom attributes is controlled by the CloudFormation, not by the CDK. CDK is sending empty list in generated CloudFormation template as observed in #30608 (comment). In case you think the documentation needs to be updated you may share feedback using As a convenience, it would be more desirable to add something like Thanks, |
Describe the bug
I have a user pool with a single mutable custom attribute named
custom:tier
. I'd like to mark it as non writable by my client however specifyingwriteAttributes
when adding the client to the pool with the code below leaves all attributes (both custom and standard) as writable other than email_verified and phone_number_verified.If I update this to include my custom attribute in the
withCustomAttributes
it marks all the standard attributes as non-writable. Similarly, if I include a standard attribute as writable likeemail: true
it marks email writable as expected and marks everything else as non-writable. It appears the writeAttributes requires at least one attribute to be writable in order to mark the rest as non-writable.Expected Behavior
I would expect for the attributes specified to
writeAttributes
to be the only ones that are writable and everything else to be non-writable.Current Behavior
If I specify standard attributes as non-writable, it leaves my custom attributes writable and there doesn't appear to be any way to mark them non-writable.
Reproduction Steps
Deploying the above stack will result in the client's attributes settings looking like this:
Possible Solution
No response
Additional Information/Context
No response
CDK CLI Version
2.146.0 (build b368c78)
Framework Version
2.147.0
Node.js Version
v22.3.0
OS
MacOS
Language
TypeScript
Language Version
~4.9.5
Other information
No response
The text was updated successfully, but these errors were encountered: