From ebe38d988fd6f254f2c818c1bd12e15df52577f3 Mon Sep 17 00:00:00 2001 From: Maxim Rubchinsky Date: Thu, 26 Feb 2026 14:22:35 +0200 Subject: [PATCH] add support for Cognito Inbound federation Lambda trigger Signed-off-by: Maxim Rubchinsky --- events/cognito.go | 40 +++++++++++++++++++ events/cognito_test.go | 14 +++++++ ...ent-userpools-inbound-federation-oidc.json | 39 ++++++++++++++++++ ...ent-userpools-inbound-federation-saml.json | 29 ++++++++++++++ 4 files changed, 122 insertions(+) create mode 100644 events/testdata/cognito-event-userpools-inbound-federation-oidc.json create mode 100644 events/testdata/cognito-event-userpools-inbound-federation-saml.json diff --git a/events/cognito.go b/events/cognito.go index 3d7bd4c4..0b350a90 100644 --- a/events/cognito.go +++ b/events/cognito.go @@ -368,3 +368,43 @@ type CognitoEventUserPoolsCustomMessageResponse struct { EmailMessage string `json:"emailMessage"` EmailSubject string `json:"emailSubject"` } + +// CognitoFederationProviderType is the type of the external identity provider. +type CognitoFederationProviderType string + +const ( + CognitoFederationProviderTypeOIDC CognitoFederationProviderType = "OIDC" + CognitoFederationProviderTypeSAML CognitoFederationProviderType = "SAML" + CognitoFederationProviderTypeFacebook CognitoFederationProviderType = "Facebook" + CognitoFederationProviderTypeGoogle CognitoFederationProviderType = "Google" + CognitoFederationProviderTypeSignInWithApple CognitoFederationProviderType = "SignInWithApple" + CognitoFederationProviderTypeLoginWithAmazon CognitoFederationProviderType = "LoginWithAmazon" +) + +// CognitoEventUserPoolsInboundFederation is sent by Amazon Cognito User Pools when a user signs in +// through a third-party identity provider, allowing a Lambda to inspect and transform federated user attributes. +type CognitoEventUserPoolsInboundFederation struct { + CognitoEventUserPoolsHeader + Request CognitoEventUserPoolsInboundFederationRequest `json:"request"` + Response CognitoEventUserPoolsInboundFederationResponse `json:"response"` +} + +// CognitoEventUserPoolsInboundFederationRequest contains the request portion of an InboundFederation event +type CognitoEventUserPoolsInboundFederationRequest struct { + ProviderName string `json:"providerName"` + ProviderType CognitoFederationProviderType `json:"providerType"` + Attributes CognitoEventUserPoolsInboundFederationAttributes `json:"attributes"` +} + +// CognitoEventUserPoolsInboundFederationAttributes contains the identity provider attributes +type CognitoEventUserPoolsInboundFederationAttributes struct { + TokenResponse map[string]string `json:"tokenResponse,omitempty"` + IDToken map[string]string `json:"idToken,omitempty"` + UserInfo map[string]string `json:"userInfo,omitempty"` + SAMLResponse map[string]string `json:"samlResponse,omitempty"` +} + +// CognitoEventUserPoolsInboundFederationResponse contains the response portion of an InboundFederation event +type CognitoEventUserPoolsInboundFederationResponse struct { + UserAttributesToMap map[string]string `json:"userAttributesToMap"` +} diff --git a/events/cognito_test.go b/events/cognito_test.go index c363421c..7a18e601 100644 --- a/events/cognito_test.go +++ b/events/cognito_test.go @@ -284,3 +284,17 @@ func TestCognitoEventUserPoolsCustomMessageMarshaling(t *testing.T) { func TestCognitoUserPoolsCustomMessageMarshalingMalformedJson(t *testing.T) { test.TestMalformedJson(t, CognitoEventUserPoolsCustomMessage{}) } + +func TestCognitoEventUserPoolsInboundFederationOIDCMarshaling(t *testing.T) { + var inputEvent CognitoEventUserPoolsInboundFederation + test.AssertJsonFile(t, "./testdata/cognito-event-userpools-inbound-federation-oidc.json", &inputEvent) +} + +func TestCognitoEventUserPoolsInboundFederationSAMLMarshaling(t *testing.T) { + var inputEvent CognitoEventUserPoolsInboundFederation + test.AssertJsonFile(t, "./testdata/cognito-event-userpools-inbound-federation-saml.json", &inputEvent) +} + +func TestCognitoEventUserPoolsInboundFederationMarshalingMalformedJson(t *testing.T) { + test.TestMalformedJson(t, CognitoEventUserPoolsInboundFederation{}) +} diff --git a/events/testdata/cognito-event-userpools-inbound-federation-oidc.json b/events/testdata/cognito-event-userpools-inbound-federation-oidc.json new file mode 100644 index 00000000..a673de27 --- /dev/null +++ b/events/testdata/cognito-event-userpools-inbound-federation-oidc.json @@ -0,0 +1,39 @@ +{ + "version": "1", + "triggerSource": "InboundFederation_ExternalProvider", + "region": "us-east-1", + "userPoolId": "us-east-1_EXAMPLE", + "userName": "testuser", + "callerContext": { + "awsSdkVersion": "aws-sdk-unknown-unknown", + "clientId": "1example23456789" + }, + "request": { + "providerName": "ExampleOIDCProvider", + "providerType": "OIDC", + "attributes": { + "tokenResponse": { + "access_token": "eyExample", + "token_type": "Bearer", + "expires_in": "3600" + }, + "idToken": { + "sub": "user123", + "email": "testuser@example.com", + "email_verified": "true" + }, + "userInfo": { + "email": "testuser@example.com", + "given_name": "Test", + "family_name": "User" + } + } + }, + "response": { + "userAttributesToMap": { + "email": "testuser@example.com", + "given_name": "Test", + "family_name": "User" + } + } +} diff --git a/events/testdata/cognito-event-userpools-inbound-federation-saml.json b/events/testdata/cognito-event-userpools-inbound-federation-saml.json new file mode 100644 index 00000000..84771450 --- /dev/null +++ b/events/testdata/cognito-event-userpools-inbound-federation-saml.json @@ -0,0 +1,29 @@ +{ + "version": "1", + "triggerSource": "InboundFederation_ExternalProvider", + "region": "us-east-1", + "userPoolId": "us-east-1_EXAMPLE", + "userName": "testuser", + "callerContext": { + "awsSdkVersion": "aws-sdk-unknown-unknown", + "clientId": "1example23456789" + }, + "request": { + "providerName": "ExampleSAMLProvider", + "providerType": "SAML", + "attributes": { + "samlResponse": { + "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress": "testuser@example.com", + "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname": "Test", + "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname": "User" + } + } + }, + "response": { + "userAttributesToMap": { + "email": "testuser@example.com", + "given_name": "Test", + "family_name": "User" + } + } +}