Skip to content

Commit

Permalink
feat(apigateway): add accessLogField static method (#22322)
Browse files Browse the repository at this point in the history
Closes #21650

Add missing context fields.

----

### 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)?
	* [x] 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*
  • Loading branch information
shotaoni authored Oct 2, 2022
1 parent 25ca80c commit 3ce8e47
Show file tree
Hide file tree
Showing 8 changed files with 197 additions and 9 deletions.
3 changes: 2 additions & 1 deletion packages/@aws-cdk/aws-apigateway/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1085,7 +1085,8 @@ new apigateway.RestApi(this, 'books', {
deployOptions: {
accessLogDestination: new apigateway.LogGroupLogDestination(logGroup),
accessLogFormat: apigateway.AccessLogFormat.custom(
`${apigateway.AccessLogField.contextRequestId()} ${apigateway.AccessLogField.contextErrorMessage()} ${apigateway.AccessLogField.contextErrorMessageString()}`
`${apigateway.AccessLogField.contextRequestId()} ${apigateway.AccessLogField.contextErrorMessage()} ${apigateway.AccessLogField.contextErrorMessageString()}
${apigateway.AccessLogField.contextAuthorizerError()} ${apigateway.AccessLogField.contextAuthorizerIntegrationStatus()}`
)
}
});
Expand Down
175 changes: 175 additions & 0 deletions packages/@aws-cdk/aws-apigateway/lib/access-log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,66 @@ export class AccessLogField {
return '$context.identity.sourceIp';
}

/**
* The PEM-encoded client certificate that the client presented during mutual TLS authentication.
* Present when a client accesses an API by using a custom domain name that has mutual TLS enabled.
* Present only in access logs if mutual TLS authentication fails.
*/

public static contextIdentityClientCertPem() {
return '$context.identity.clientCert.clientCertPem';
}

/**
* The distinguished name of the subject of the certificate that a client presents.
* Present when a client accesses an API by using a custom domain name that has mutual TLS enabled.
* Present only in access logs if mutual TLS authentication fails.
*/

public static contextIdentityClientCertSubjectDN() {
return '$context.identity.clientCert.subjectDN';
}

/**
* The distinguished name of the issuer of the certificate that a client presents.
* Present when a client accesses an API by using a custom domain name that has mutual TLS enabled.
* Present only in access logs if mutual TLS authentication fails.
*/

public static contextIdentityClientCertIssunerDN() {
return '$context.identity.clientCert.issuerDN';
}

/**
* The serial number of the certificate.
* Present when a client accesses an API by using a custom domain name that has mutual TLS enabled.
* Present only in access logs if mutual TLS authentication fails.
*/

public static contextIdentityClientCertSerialNumber() {
return '$context.identity.clientCert.serialNumber';
}

/**
* The date before which the certificate is invalid.
* Present when a client accesses an API by using a custom domain name that has mutual TLS enabled.
* Present only in access logs if mutual TLS authentication fails.
*/

public static contextIdentityClientCertValidityNotBefore() {
return '$context.identity.clientCert.validity.notBefore';
}

/**
* The date after which the certificate is invalid.
* Present when a client accesses an API by using a custom domain name that has mutual TLS enabled.
* Present only in access logs if mutual TLS authentication fails.
*/

public static contextIdentityClientCertValidityNotAfter() {
return '$context.identity.clientCert.validity.notAfter';
}

/**
* The principal identifier of the user making the request. Used in Lambda authorizers.
* @see https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-lambda-authorizer-output.html
Expand Down Expand Up @@ -449,6 +509,121 @@ export class AccessLogField {
public static contextStatus() {
return '$context.status';
}

/**
* The authorization error message.
*/
public static contextAuthorizeError() {
return '$context.authorize.error';
}

/**
* The authorization latency in ms.
*/
public static contextAuthorizeLatency() {
return '$context.authorize.latency';
}

/**
* The status code returned from an authorization attempt.
*/
public static contextAuthorizeStatus() {
return '$context.authorize.status';
}

/**
* The error message returned from an authorizer.
*/
public static contextAuthorizerError() {
return '$context.authorizer.error';
}

/**
* The status code returned from a Lambda authorizer.
*/
public static contextAuthorizerIntegrationStatus() {
return '$context.authorizer.integrationStatus';
}

/**
* The authorizer latency in ms.
*/
public static contextAuthorizerLatency() {
return '$context.authorizer.latency';
}

/**
* The AWS endpoint's request ID.
*/
public static contextAuthorizerRequestId() {
return '$context.authorizer.requestId';
}

/**
* The status code returned from an authorizer.
*/
public static contextAuthorizerStatus() {
return '$context.authorizer.status';
}

/**
* The error message returned from an authentication attempt.
*/
public static contextAuthenticateError() {
return '$context.authenticate.error';
}

/**
* The authentication latency in ms.
*/
public static contextAuthenticateLatency() {
return '$context.authenticate.latency';
}

/**
* The status code returned from an authentication attempt.
*/
public static contextAuthenticateStatus() {
return '$context.authenticate.status';
}

/**
* The path for an API mapping that an incoming request matched.
* Applicable when a client uses a custom domain name to access an API. For example if a client sends a request to
* https://api.example.com/v1/orders/1234, and the request matches the API mapping with the path v1/orders, the value is v1/orders.
* @see https://docs.aws.amazon.com/en_jp/apigateway/latest/developerguide/rest-api-mappings.html
*/
public static contextCustomDomainBasePathMatched() {
return '$context.customDomain.basePathMatched';
}

/**
* A string that contains an integration error message.
*/
public static contextIntegrationErrorMessage() {
return '$context.integrationErrorMessage';
}

/**
* The error message returned from AWS WAF.
*/
public static contextWafError() {
return '$context.waf.error';
}

/**
* The AWS WAF latency in ms.
*/
public static contextWafLatency() {
return '$context.waf.latency';
}

/**
* The status code returned from AWS WAF.
*/
public static contextWafStatus() {
return '$context.waf.status';
}
}

/**
Expand Down
8 changes: 7 additions & 1 deletion packages/@aws-cdk/aws-apigateway/test/access-log.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,13 @@ describe('access log', () => {
sub: apigateway.AccessLogField.contextAuthorizerClaims('sub'),
email: apigateway.AccessLogField.contextAuthorizerClaims('email'),
},
clientCertPem: apigateway.AccessLogField.contextIdentityClientCertPem(),
subjectDN: apigateway.AccessLogField.contextIdentityClientCertSubjectDN(),
issunerDN: apigateway.AccessLogField.contextIdentityClientCertIssunerDN(),
serialNumber: apigateway.AccessLogField.contextIdentityClientCertSerialNumber(),
validityNotBefore: apigateway.AccessLogField.contextIdentityClientCertValidityNotBefore(),
validityNotAfter: apigateway.AccessLogField.contextIdentityClientCertValidityNotAfter(),
}));
expect(testFormat.toString()).toEqual('{"requestId":"$context.requestId","sourceIp":"$context.identity.sourceIp","method":"$context.httpMethod","callerAccountId":"$context.identity.accountId","ownerAccountId":"$context.accountId","userContext":{"sub":"$context.authorizer.claims.sub","email":"$context.authorizer.claims.email"}}');
expect(testFormat.toString()).toEqual('{"requestId":"$context.requestId","sourceIp":"$context.identity.sourceIp","method":"$context.httpMethod","callerAccountId":"$context.identity.accountId","ownerAccountId":"$context.accountId","userContext":{"sub":"$context.authorizer.claims.sub","email":"$context.authorizer.claims.email"},"clientCertPem":"$context.identity.clientCert.clientCertPem","subjectDN":"$context.identity.clientCert.subjectDN","issunerDN":"$context.identity.clientCert.issuerDN","serialNumber":"$context.identity.clientCert.serialNumber","validityNotBefore":"$context.identity.clientCert.validity.notBefore","validityNotAfter":"$context.identity.clientCert.validity.notAfter"}');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ class Test extends cdk.Stack {
sub: apigateway.AccessLogField.contextAuthorizerClaims('sub'),
email: apigateway.AccessLogField.contextAuthorizerClaims('email'),
},
clientCertPem: apigateway.AccessLogField.contextIdentityClientCertPem(),
subjectDN: apigateway.AccessLogField.contextIdentityClientCertSubjectDN(),
issunerDN: apigateway.AccessLogField.contextIdentityClientCertIssunerDN(),
serialNumber: apigateway.AccessLogField.contextIdentityClientCertSerialNumber(),
validityNotBefore: apigateway.AccessLogField.contextIdentityClientCertValidityNotBefore(),
validityNotAfter: apigateway.AccessLogField.contextIdentityClientCertValidityNotAfter(),
}));

const logGroup = new logs.LogGroup(this, 'MyLogGroup');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"validateOnSynth": false,
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}",
"cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}",
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/bfcd014ed17d9d37eb988448edc7e87eb2ab77e6f7508bf3de2714a6322c99b3.json",
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/0605fe9fb02ad31c3236b358b7605999f20ba079969b6fad8e9cd3878d869ee6.json",
"requiresBootstrapStackVersion": 6,
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version",
"additionalDependencies": [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"version": "21.0.0",
"files": {
"bfcd014ed17d9d37eb988448edc7e87eb2ab77e6f7508bf3de2714a6322c99b3": {
"0605fe9fb02ad31c3236b358b7605999f20ba079969b6fad8e9cd3878d869ee6": {
"source": {
"path": "test-apigateway-access-logs.template.json",
"packaging": "file"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "bfcd014ed17d9d37eb988448edc7e87eb2ab77e6f7508bf3de2714a6322c99b3.json",
"objectKey": "0605fe9fb02ad31c3236b358b7605999f20ba079969b6fad8e9cd3878d869ee6.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
"Arn"
]
},
"Format": "{\"requestId\":\"$context.requestId\",\"sourceIp\":\"$context.identity.sourceIp\",\"method\":\"$context.httpMethod\",\"callerAccountId\":\"$context.identity.accountId\",\"ownerAccountId\":\"$context.accountId\",\"userContext\":{\"sub\":\"$context.authorizer.claims.sub\",\"email\":\"$context.authorizer.claims.email\"}}"
"Format": "{\"requestId\":\"$context.requestId\",\"sourceIp\":\"$context.identity.sourceIp\",\"method\":\"$context.httpMethod\",\"callerAccountId\":\"$context.identity.accountId\",\"ownerAccountId\":\"$context.accountId\",\"userContext\":{\"sub\":\"$context.authorizer.claims.sub\",\"email\":\"$context.authorizer.claims.email\"},\"clientCertPem\":\"$context.identity.clientCert.clientCertPem\",\"subjectDN\":\"$context.identity.clientCert.subjectDN\",\"issunerDN\":\"$context.identity.clientCert.issuerDN\",\"serialNumber\":\"$context.identity.clientCert.serialNumber\",\"validityNotBefore\":\"$context.identity.clientCert.validity.notBefore\",\"validityNotAfter\":\"$context.identity.clientCert.validity.notAfter\"}"
},
"DeploymentId": {
"Ref": "MyApiDeploymentECB0D05E81594d6748b4b291f993111a5070d710"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"path": "Tree",
"constructInfo": {
"fqn": "constructs.Construct",
"version": "10.1.95"
"version": "10.1.108"
}
},
"test-apigateway-access-logs": {
Expand Down Expand Up @@ -173,7 +173,7 @@
"Arn"
]
},
"format": "{\"requestId\":\"$context.requestId\",\"sourceIp\":\"$context.identity.sourceIp\",\"method\":\"$context.httpMethod\",\"callerAccountId\":\"$context.identity.accountId\",\"ownerAccountId\":\"$context.accountId\",\"userContext\":{\"sub\":\"$context.authorizer.claims.sub\",\"email\":\"$context.authorizer.claims.email\"}}"
"format": "{\"requestId\":\"$context.requestId\",\"sourceIp\":\"$context.identity.sourceIp\",\"method\":\"$context.httpMethod\",\"callerAccountId\":\"$context.identity.accountId\",\"ownerAccountId\":\"$context.accountId\",\"userContext\":{\"sub\":\"$context.authorizer.claims.sub\",\"email\":\"$context.authorizer.claims.email\"},\"clientCertPem\":\"$context.identity.clientCert.clientCertPem\",\"subjectDN\":\"$context.identity.clientCert.subjectDN\",\"issunerDN\":\"$context.identity.clientCert.issuerDN\",\"serialNumber\":\"$context.identity.clientCert.serialNumber\",\"validityNotBefore\":\"$context.identity.clientCert.validity.notBefore\",\"validityNotAfter\":\"$context.identity.clientCert.validity.notAfter\"}"
},
"deploymentId": {
"Ref": "MyApiDeploymentECB0D05E81594d6748b4b291f993111a5070d710"
Expand Down Expand Up @@ -272,7 +272,7 @@
"path": "apigateway-access-logs/DefaultTest/Default",
"constructInfo": {
"fqn": "constructs.Construct",
"version": "10.1.95"
"version": "10.1.108"
}
},
"DeployAssert": {
Expand Down

0 comments on commit 3ce8e47

Please sign in to comment.