Skip to content
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): add accessLogField static method #22322

Merged
merged 2 commits into from
Oct 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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