-
Notifications
You must be signed in to change notification settings - Fork 4k
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
feat(apigateway): mTLS support #10521
Conversation
* The mutual TLS authentication configuration for a custom domain name. | ||
* @default - mTLS is not configured. | ||
*/ | ||
readonly mutualTlsAuthentication?: MutualTlsAuthenticationAttributes |
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.
mTLS is the industry standard abbreviation. Let's use that.
readonly mutualTlsAuthentication?: MutualTlsAuthenticationAttributes | |
readonly mtls?: MTLSAttributes |
export interface MutualTlsAuthenticationAttributes { | ||
/** | ||
* An Amazon S3 URL that specifies the truststore for mutual TLS authentication, for example, s3://bucket-name/key-name. | ||
* The truststore can contain certificates from public or private certificate authorities. | ||
* To update the truststore, upload a new version to S3, and then update your custom domain name to use the new version. | ||
* To update the truststore, you must have permissions to access the S3 object. | ||
*/ | ||
readonly truststoreUri: string; | ||
|
||
/** | ||
* The version of the S3 object that contains your truststore. | ||
* To specify a version, you must have versioning enabled for the S3 bucket. | ||
* @default - Uses current version | ||
*/ | ||
readonly truststoreVersion?: string; | ||
} |
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.
Since this is a reference to an S3 object, this can be -
export interface MTLSAttributes {
readonly bucket: s3.IBucket;
readonly key: string;
readonly version?: string;
}
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.
I was just starting to refactor towards this as well. Good to know I was going down the right path.
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.
Please also look into the build and linter failures.
Had a look and was fixing this afternoon, the linting failure was lack of updated documentation, while doing the documentation I started to go down the process of refactoring the MTLS attributes similar to how you did. I'll get this updated tomorrow. |
I did a fresh clone based on the latest master, ran cfn2ts again and noticed that it did not have the relevant fields, so as mentioned in the #10521, this may have worked on paper due to the fact I had done a bump (and need to rebase to remove it). |
Even after pulling 1.65.0, I'm seeing the field missing on a fresh clone of this repo and doing a cfn2ts. |
Not sure about If you rebase with the latest |
b4ee46f
to
39fbd53
Compare
39fbd53
to
b3135f4
Compare
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.
Thanks for addressing the previous comments. I have a few more around the implementation.
@@ -562,6 +563,24 @@ Authorizers can also be passed via the `defaultMethodOptions` property within th | |||
explicitly overridden, the specified defaults will be applied across all `Method`s across the `RestApi` or across all `Resource`s, | |||
depending on where the defaults were specified. | |||
|
|||
## Mutal TLS (mTLS) |
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.
## Mutal TLS (mTLS) | |
## Mutual TLS (mTLS) |
@@ -29,6 +29,7 @@ running on AWS Lambda, or any web application. | |||
- [IAM-based authorizer](#iam-based-authorizer) | |||
- [Lambda-based token authorizer](#lambda-based-token-authorizer) | |||
- [Lambda-based request authorizer](#lambda-based-request-authorizer) | |||
- [MTLS](#mutal-tls-mtls) |
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.
- [MTLS](#mutal-tls-mtls) | |
- [Mutual TLS](#mutual-tls-mtls) |
@@ -102,17 +110,25 @@ export class DomainName extends Resource implements IDomainName { | |||
|
|||
const endpointType = props.endpointType || EndpointType.REGIONAL; | |||
const edge = endpointType === EndpointType.EDGE; | |||
|
|||
const getMTLSConfiguration = (mtlsConfig?: MTLSAttributes): CfnDomainName.MutualTlsAuthenticationProperty | undefined => { |
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.
Use function declaration instead of function expression. It can either be a private function of this class or a standalone function outside of the scope of this class.
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.
Pushed a commit where I tried this just to verify I've done this in the way you expected.
I moved getMTLSConfiguration into a function instead of being in the constructor (note, I only put the function here to make this diff clean, I was going to put it elsewhere).
diff --git a/packages/@aws-cdk/aws-apigateway/lib/domain-name.ts b/packages/@aws-cdk/aws-apigateway/lib/domain-name.ts
index a59b71892..b490c1c80 100644
--- a/packages/@aws-cdk/aws-apigateway/lib/domain-name.ts
+++ b/packages/@aws-cdk/aws-apigateway/lib/domain-name.ts
@@ -86,6 +86,14 @@ export interface IDomainName extends IResource {
}
+function getMTLSConfiguration(mtlsConfig?: MTLSConfig): CfnDomainName.MutualTlsAuthenticationProperty | undefined {
+ if (!mtlsConfig) return undefined;
+ return {
+ truststoreUri: mtlsConfig.bucket.s3UrlForObject(mtlsConfig.key),
+ truststoreVersion: mtlsConfig.version,
+ };
+};
+
export class DomainName extends Resource implements IDomainName {
/**
@@ -115,7 +123,7 @@ export class DomainName extends Resource implements IDomainName {
throw new Error('domainName does not support uppercase letters. ' +
`got: '${props.domainName}'`);
}
- const mtlsConfig = this.getMTLSConfiguration(props.mtls);
+ const mtlsConfig = getMTLSConfiguration(props.mtls);
const resource = new CfnDomainName(this, 'Resource', {
domainName: props.domainName,
certificateArn: edge ? props.certificate.certificateArn : undefined,
@@ -153,14 +161,6 @@ export class DomainName extends Resource implements IDomainName {
restApi: targetApi,
...options,
});
- }
But now I get a jsii build error
[2020-10-06T08:57:54.987] [ERROR] jsii/compiler - Error during type model analysis: TypeError: Cannot read property 'getJsDocTags' of undefined
TypeError: Cannot read property 'getJsDocTags' of undefined
at _hasInternalJsDocTag (/home/dferris/aws-cdk/node_modules/jsii/lib/assembler.js:1617:19)
at Assembler._isPrivateOrInternal (/home/dferris/aws-cdk/node_modules/jsii/lib/assembler.js:988:37)
at Assembler._visitClass (/home/dferris/aws-cdk/node_modules/jsii/lib/assembler.js:834:26)
at async Assembler._visitNode (/home/dferris/aws-cdk/node_modules/jsii/lib/assembler.js:579:24)
at async Promise.all (index 86)
at async Assembler.emit (/home/dferris/aws-cdk/node_modules/jsii/lib/assembler.js:102:9)
at async Compiler._consumeProgram (/home/dferris/aws-cdk/node_modules/jsii/lib/compiler.js:148:30)
at async /home/dferris/aws-cdk/node_modules/jsii/bin/jsii.js:70:39
I've tried it as both a private function on the class as well as standalone, still get the same behaviour.
As is probably clear, this is my first time working with jsii, so I'm not 100% clear about the why this is occurring.
If you have any suggestions on how to format my code to have the same intent but get around this, it would be greatly appreciated.
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.
The problem is likely because the method has a get
prefix. Changing this to mtlsConfiguration()
should fix this.
Let me know if not and I'll dig into this.
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.
I've tried making this diff locally
diff --git a/packages/@aws-cdk/aws-apigateway/lib/domain-name.ts b/packages/@aws-cdk/aws-apigateway/lib/domain-name.ts
index a59b71892..71371765b 100644
--- a/packages/@aws-cdk/aws-apigateway/lib/domain-name.ts
+++ b/packages/@aws-cdk/aws-apigateway/lib/domain-name.ts
@@ -86,6 +86,7 @@ export interface IDomainName extends IResource {
}
+
export class DomainName extends Resource implements IDomainName {
/**
@@ -107,7 +108,6 @@ export class DomainName extends Resource implements IDomainName {
constructor(scope: Construct, id: string, props: DomainNameProps) {
super(scope, id);
-
const endpointType = props.endpointType || EndpointType.REGIONAL;
const edge = endpointType === EndpointType.EDGE;
@@ -115,13 +115,13 @@ export class DomainName extends Resource implements IDomainName {
throw new Error('domainName does not support uppercase letters. ' +
`got: '${props.domainName}'`);
}
- const mtlsConfig = this.getMTLSConfiguration(props.mtls);
+ // const mtlsConfig = this.mtlsConfiguration(props.mtls);
const resource = new CfnDomainName(this, 'Resource', {
domainName: props.domainName,
certificateArn: edge ? props.certificate.certificateArn : undefined,
regionalCertificateArn: edge ? undefined : props.certificate.certificateArn,
endpointConfiguration: { types: [endpointType] },
- mutualTlsAuthentication: mtlsConfig,
+ // mutualTlsAuthentication: ,
securityPolicy: props.securityPolicy,
});
@@ -153,15 +153,15 @@ export class DomainName extends Resource implements IDomainName {
restApi: targetApi,
...options,
});
- }
-
- private getMTLSConfiguration(mtlsConfig?: MTLSConfig): CfnDomainName.MutualTlsAuthenticationProperty | undefined {
- if (!mtlsConfig) return undefined;
- return {
- truststoreUri: mtlsConfig.bucket.s3UrlForObject(mtlsConfig.key),
- truststoreVersion: mtlsConfig.version,
- };
};
+
+ // private mtlsConfiguration(mtlsConfig?: MTLSConfig): CfnDomainName.MutualTlsAuthenticationProperty | undefined {
+ // if (!mtlsConfig) return { };
+ // return {
+ // truststoreUri: mtlsConfig.bucket.s3UrlForObject(mtlsConfig.key),
+ // truststoreVersion: mtlsConfig.version,
+ // };
+ // };
}
Still getting the same error.
If you could have a look, that would be fantastic.
I would have thought me commenting out the code would have ruled out if it was my code directly.
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.
To clarify the use of return {}
I had tried return undefined
and return mtlsConfig
and was just trying to try things to try and narrow down the scope of what was causing the break.
Running yarn build
from inside of the aws-apigateway package threw the error every time, couldn't figure out why it was breaking
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.
Sure. I'll take a look.
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.
Lol, it seems the problem is the trailing semicolon at the end of the private method body. JSII seems to not like that. Remove that and you're problem will be fixed 😊
We're tracking this here - aws/jsii#2098
@@ -102,17 +110,25 @@ export class DomainName extends Resource implements IDomainName { | |||
|
|||
const endpointType = props.endpointType || EndpointType.REGIONAL; | |||
const edge = endpointType === EndpointType.EDGE; | |||
|
|||
const getMTLSConfiguration = (mtlsConfig?: MTLSAttributes): CfnDomainName.MutualTlsAuthenticationProperty | undefined => { | |||
if (!mtlsConfig) return mtlsConfig; |
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 (!mtlsConfig) return mtlsConfig; | |
if (!mtlsConfig) return undefined; |
/** | ||
* The mTLS authentication configuration for a custom domain name. | ||
*/ | ||
export interface MTLSAttributes { |
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.
Sorry, I missed this in the first round of reviews. We usually use the Attributes
suffix in conjunction with import APIs - https://github.com/aws/aws-cdk/blob/master/DESIGN_GUIDELINES.md#from-attributes.
What do you think about switching this to MTLSConfig
instead?
/** | ||
* The version of the S3 object that contains your truststore. | ||
* To specify a version, you must have versioning enabled for the S3 bucket. | ||
* @default - Uses current version |
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.
* @default - Uses current version | |
* @default - latest version |
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.
Everything looks great. The only remaining piece is to fix the JSII build failure. See #10521 (comment)
Let me know if that doesn't help.
All sorted, you were right about the trailing semicolon, thanks for the pointer there, would not have known where to start! |
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.
Nice!
Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
Resolves #10487
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license