- 
                Notifications
    You must be signed in to change notification settings 
- Fork 4.3k
feat(route53): support restricting delegated zone names when using grantDelegation #35129
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
base: main
Are you sure you want to change the base?
Conversation
| AWS CodeBuild CI Report
 Powered by github-codebuild-logs, available on the AWS Serverless Application Repository | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few minor suggestions for consideration:
- 
Input Validation: Consider adding validation that the provided record names are valid DNS names to catch errors early rather than at IAM policy evaluation time. 
- 
Documentation Enhancement: It might be helpful to clarify in the README that the record names should be the actual NS record names that will be created (e.g., for delegating beta.example.com, you'd specify['beta.example.com']).
- 
Property Naming: While nameEqualsis clear,recordNamesorallowedRecordNamesmight be slightly more intuitive for users.
These are minor suggestions - the core implementation is solid. Thanks for contributing this useful feature to the CDK!
| Thanks for the review - I can add the input validation and update the docs. For input validation I will likely just reuse this. I was thinking about it, and using  zone.grantDelegation(role, {
  recordNames: ['beta'],
})instead of zone.grantDelegation(role, {
  recordNames: ['beta.example.com'],
})What do you think of using the logic in this function to make it so that usage would also work? | 
| Maybe the property should be named  Update: so according to RFC 9499 DNS Terminology there is no uniform name, but child zone is definitely the most common name. | 
| 
 I think the  
 I think after some time I have gone back against supporting the rather complex logic in that function for determining whether to append the hosted zone name to the record name or not. I think it is a lot simpler to require the hosted zone name you are delegating to, ie:  Additionally, the lambda handler for creating the zone delegation uses  Line 68 in 40644c6 
 I was also considering removing the ability to give a list of zone names, but I suppose it doesn't hurt. | 
88ea9b1    to
    005bb30      
    Compare
  
    | I have updated the PR to use  
 I personally think  | 
| 
 Additionally, the integ test is using conditions to limit access | 
|  | ||
| export function makeGrantDelegation(grantee: iam.IGrantable, hostedZoneArn: string): iam.Grant { | ||
| function stripTrailingDot(zoneName: string) { | ||
| return zoneName.endsWith('.') ? zoneName.substring(0, zoneName.length - 1) : zoneName; | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
zoneName here could be a token, so we can't really do normal string operations here unless we either:
- Use Cloudformation intrinsic functions to preform the string operation instead.
- Throw an error if zoneNameis an unresolved token.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this also apply to line R52 above? This token check was not being done there before
Additionally I do have a more general question on the trailing dot. The delegatedZoneName needs to match exactly with whatever is used as the hosted zone name in the CrossAccountZoneDelegationRecord, including the trailing dot, if we use the StringEquals condition, which may not be intuitive. I wonder if it makes sense to instead use StringLike so we can allow requests whether or not the trailing dot exists. Alternatively we could just document the trailing dot issue and let users deal with it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- If its been done before then I'll allow it. It was probably incorrect in the first place but that's outside the scope of the PR.
- I might be misunderstanding this, but are you talking about the IAM statements for the conditions? If so, then according to the AWS docs, it recommends using StringEqualswith a normalized DNS name without the trailing dot:
For route53:ChangeResourceRecordSetsNormalizedRecordNames:
All letters must be lowercase.
The DNS name must be without the trailing dot.
Characters other than a–z, 0–9, - (hyphen), _ (underscore), and . (period, as a delimiter between labels) must use escape codes in the format \three-digit octal code. For example, \052 is the octal code for character *.
You say we should include the trailing dot which is incorrect in this situation, so I'm not sure what exactly are you referring to.
|  | ||
| export function makeGrantDelegation(grantee: iam.IGrantable, hostedZone: IHostedZone, delegationOptions?: GrantDelegationOptions): iam.Grant { | ||
| const delegatedZoneNames = delegationOptions?.delegatedZoneNames; | ||
| delegatedZoneNames?.forEach(zoneName => validateDelegatedZoneName(hostedZone.zoneName, zoneName)); | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIUC, this doesn't check if the delegated zone name has a trailing dot. It should be normalized and not have a trailing dot. Throw an error if it does.
Issue # (if applicable)
Closes #28078.
Reason for this change
Allowing the option to restrict the hosted zone names the delegation role can create records for encourages minimum permissions setup. The linked issue establishes a fairly common usecase - different roles for
dev.example.comeandprod.example.com,Description of changes
Adds the interface
GrantDelegationOptions, with optional readonly propdelegatedZoneNames. This interface is used as an optional prop tohostedZone.grantDelegation().Example usage:
Added some validation that ensures each of the
delegatedZoneNamesis a valid subdomain of the parent hosted zone.Additionally, updated the README with usage instructions and fixed an outdated code example for how to use
grantDelegation. This code example was giving too broad permissions that what was necessary.Describe any new or updated permissions being added
when
delegatedZoneNamesis provided with[a.example.com], the following condition is added:"ForAllValues:StringEquals": { "route53:ChangeResourceRecordSetsRecordTypes": [ "NS" ], "route53:ChangeResourceRecordSetsActions": [ "UPSERT", "DELETE" ], + "route53:ChangeResourceRecordSetsNormalizedRecordNames": [ + "a.example.com" + ]Description of how you validated changes
Updated Integ and unit tests
Checklist
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license