Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* Copyright 2026 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://aws.amazon.com/apache2.0/
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.amazonaws.serverless.proxy.model;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

/**
* Client certificate metadata included in API Gateway proxy request events when mutual TLS is enabled.
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class ApiGatewayClientCertificate {
private String clientCertPem;
private String subjectDN;
private String issuerDN;
private String serialNumber;
private Validity validity;

public String getClientCertPem() {
return clientCertPem;
}

public void setClientCertPem(String clientCertPem) {
this.clientCertPem = clientCertPem;
}

public String getSubjectDN() {
return subjectDN;
}

public void setSubjectDN(String subjectDN) {
this.subjectDN = subjectDN;
}

public String getIssuerDN() {
return issuerDN;
}

public void setIssuerDN(String issuerDN) {
this.issuerDN = issuerDN;
}

public String getSerialNumber() {
return serialNumber;
}

public void setSerialNumber(String serialNumber) {
this.serialNumber = serialNumber;
}

public Validity getValidity() {
return validity;
}

public void setValidity(Validity validity) {
this.validity = validity;
}

@JsonIgnoreProperties(ignoreUnknown = true)
public static class Validity {
private String notBefore;
private String notAfter;

public String getNotBefore() {
return notBefore;
}

public void setNotBefore(String notBefore) {
this.notBefore = notBefore;
}

public String getNotAfter() {
return notAfter;
}

public void setNotAfter(String notAfter) {
this.notAfter = notAfter;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public class ApiGatewayRequestIdentity {
private String sourceIp;
private String accountId;
private String accessKey;
private ApiGatewayClientCertificate clientCert;


//-------------------------------------------------------------
Expand Down Expand Up @@ -179,4 +180,14 @@ public String getAccessKey() {
public void setAccessKey(String accessKey) {
this.accessKey = accessKey;
}


public ApiGatewayClientCertificate getClientCert() {
return clientCert;
}


public void setClientCert(ApiGatewayClientCertificate clientCert) {
this.clientCert = clientCert;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2026 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://aws.amazon.com/apache2.0/
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.amazonaws.serverless.proxy.model;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

/**
* Authentication metadata included in an API Gateway HTTP API v2 request context.
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class HttpApiV2Authentication {
private ApiGatewayClientCertificate clientCert;

public ApiGatewayClientCertificate getClientCert() {
return clientCert;
}

public void setClientCert(ApiGatewayClientCertificate clientCert) {
this.clientCert = clientCert;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public class HttpApiV2ProxyRequestContext {

private HttpApiV2HttpContext http;
private HttpApiV2AuthorizerMap authorizer;
private HttpApiV2Authentication authentication;

public String getAccountId() {
return accountId;
Expand Down Expand Up @@ -118,6 +119,14 @@ public void setAuthorizer(HttpApiV2AuthorizerMap authorizer) {
this.authorizer = authorizer;
}

public HttpApiV2Authentication getAuthentication() {
return authentication;
}

public void setAuthentication(HttpApiV2Authentication authentication) {
this.authentication = authentication;
}

public AlbContext getElb() {
return this.elb;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.amazonaws.serverless.proxy.model;

import com.amazonaws.serverless.proxy.internal.LambdaContainerHandler;
import com.amazonaws.serverless.proxy.internal.testutils.AwsProxyRequestBuilder;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

class ApiGatewayClientCertificateTest {
private static final String CERTIFICATE_JSON = "\"clientCert\": {"
+ "\"clientCertPem\": \"-----BEGIN CERTIFICATE-----\\ncertificate\\n-----END CERTIFICATE-----\","
+ "\"subjectDN\": \"CN=client\","
+ "\"issuerDN\": \"CN=issuer\","
+ "\"serialNumber\": \"01:02:03\","
+ "\"validity\": {\"notBefore\": \"May 28 12:30:02 2019 GMT\","
+ "\"notAfter\": \"Aug 5 09:36:04 2021 GMT\"}"
+ "}";

@Test
void deserialize_restApiIdentityClientCertificate() throws Exception {
String requestJson = "{\"requestContext\": {\"identity\": {" + CERTIFICATE_JSON + "}}}";

AwsProxyRequest request = new AwsProxyRequestBuilder().fromJsonString(requestJson).build();
ApiGatewayClientCertificate certificate = request.getRequestContext().getIdentity().getClientCert();

assertCertificate(certificate);
}

@Test
void deserialize_httpApiV2AuthenticationClientCertificate() throws Exception {
String requestJson = "{\"requestContext\": {\"authentication\": {" + CERTIFICATE_JSON + "}}}";

HttpApiV2ProxyRequest request = LambdaContainerHandler.getObjectMapper()
.readValue(requestJson, HttpApiV2ProxyRequest.class);
ApiGatewayClientCertificate certificate = request.getRequestContext().getAuthentication().getClientCert();

assertCertificate(certificate);
}

private void assertCertificate(ApiGatewayClientCertificate certificate) {
assertNotNull(certificate);
assertEquals("-----BEGIN CERTIFICATE-----\ncertificate\n-----END CERTIFICATE-----", certificate.getClientCertPem());
assertEquals("CN=client", certificate.getSubjectDN());
assertEquals("CN=issuer", certificate.getIssuerDN());
assertEquals("01:02:03", certificate.getSerialNumber());
assertNotNull(certificate.getValidity());
assertEquals("May 28 12:30:02 2019 GMT", certificate.getValidity().getNotBefore());
assertEquals("Aug 5 09:36:04 2021 GMT", certificate.getValidity().getNotAfter());
}
}