An extensible set of AWS Lambda handlers for Amazon Cognito triggers. The project is hook-agnostic; PreSignUp is implemented first, and the same core will be reused for additional hooks over time.
A policy layer (OPA, Rego v1) makes allow/deny decisions and can set Cognito response flags. Optionally, policy input is enriched with SendGrid email verification data. A local debug runner lets you exercise fixtures without real credentials.
- multi-hook architecture: common types and helpers live under
internal
; each hook has its own handler and a smallcmd/<hook>/main.go
- presignup (implemented): clean handling of Cognito PreSignUp events
- policy-based decisions (rego v1): allow/deny and optionally set
autoConfirmUser
,autoVerifyEmail
, andautoVerifyPhone
- optional sendgrid verification: include verdict and score in policy input; trusted domains can be allowlisted to bypass checks
- local debug mode: run integration tests against fixture events and policies with zero external dependencies
- structured logging: json logs via
slog
with runtime level control
notes future hooks may be added using the same pattern (e.g., PostConfirmation, PreAuthentication, CustomMessage). timelines are intentionally unspecified.
Configure Lambda or local runs via environment variables. See .env.sample
for a ready-to-copy template.
Variable | Description | Default |
---|---|---|
APP_LOG_LEVEL |
log level: debug , info , warn , error |
info (or debug if dbg) |
APP_DEBUG_ENABLED |
enable extra debug logging | false |
APP_DEBUG_DATA_PATH |
path to JSON array of sample events | fixtures/debug-data.json |
APP_POLICY_PATH |
path to Rego policy (v1) | required |
APP_EMAIL_VERIFICATION_ENABLED |
enable sendgrid verification | false |
APP_EMAIL_VERIFICATION_FOR_TRIGGER_SOURCES |
comma delimited string of triggers to verify | PreSignUp_SignUp |
APP_EMAIL_VERIFICATION_WHITELIST |
comma delimited string of domains to auto-allow (lowercased) | "" |
APP_SENDGRID_API_HOST |
sendgrid api base url | https://api.sendgrid.com |
APP_SENDGRID_EMAIL_VERIFICATION_API_KEY |
sendgrid api key | required if verification |
note: when
APP_DEBUG_ENABLED=true
, log level is forced todebug
.
The handler queries: data.cognito_hook_presignup.result
{
"action": "allow | deny",
"reason": "string (only when deny)",
"response": {
"autoConfirmUser": true,
"autoVerifyEmail": false,
"autoVerifyPhone": false
}
}
This policy denys on explicit invalid, otherwise allows.
package cognito_hook_presignup
import rego.v1
result := deny_result if {
input.emailVerification != null
input.emailVerification.valid == false
}
result := allow_result if {
not deny_result
}
allow_result := { "action": "allow", "response": {} }
deny_result := {
"action": "deny",
"reason": "invalid email address"
} if {
input.emailVerification != null
input.emailVerification.valid == false
}
Use the debug runner to process fixture events with your policy.
-
Copy
.env.sample
to.env
and adjust values. -
Run with defaults:
make debug
-
Override paths:
go run ./cmd/debug \ -data ./fixtures/debug-data.json \ -policy ./fixtures/debug-policy.rego
The runner logs each event’s computed response and any handler error. Fixture
events live in fixtures/debug-data.json
.
Build a Linux binary and zip it for Lambda.
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 \
go build -trimpath -ldflags "-s -w" \
-o dist/presignup ./cmd/presignup
cd dist && zip presignup.zip presignup
Create a Lambda function:
- runtime: Go or provided.al2/al2023 (custom) as you prefer
- architecture:
arm64
(orx86_64
if you built that) - handler:
presignup
(the binary name) - upload
presignup.zip
- set environment variables from the table above
- attach the user pool’s Pre sign-up trigger to this function
No special IAM permissions are required unless your VPC settings restrict egress to SendGrid.