The invitation Cognito could not send.
A live test email put the username and temporary password together. The documented customization paths kept them together—so I kept Cognito for identity and moved delivery across a boundary we could test.
The security review started with evidence, not theory: Cognito delivered a real test invitation containing both a username and a temporary password. I wanted the credential email to contain the secret alone.
The first assumption was that I could remove the username in a template or Custom Message Lambda. AWS’s current documentation says a customized administrator invitation must include both supplied values. Cognito was behaving as documented; our requirement did not fit its managed invitation.
Two customization layers preserved the same constraint.
AWS documents both the static invitation template and the Custom Message trigger for administrator-created users as including the username and temporary credential placeholders.
Both parameters returned
usernameParametercodeParameterIt was a boundary our requirement could not cross.
Leave the mailer. Keep the identity service.
The replacement flow suppresses Cognito’s managed invitation and gives CareFlow control of the credential message. Exact API choices and temporary-password behavior must still be validated for the configured user pool.
Suppress managed delivery
Create the administrator-managed account without the default invitation.
Set a temporary password
Leave the user in the expected first-sign-in challenge state.
Send through SES
Own the content contract, sender, monitoring, and failures.
Require a new password
Let Cognito continue to manage identity and the challenge.
The first fix still carried the door with the key.
A password-only email was not actually password-only while it also named the sign-in location and told the recipient which identifier to use.
Temporary secret only
No username, address, URL, or sign-in instruction.
Location and context
The account instructions arrive separately through a verified process.
It does not make a compromised mailbox harmless.
Make the narrow boundary executable.
A test can protect a precisely defined message contract. It cannot certify the security of the entire onboarding system.
| Assertion | What it prevents | What it does not prove |
|---|---|---|
| No identifier or @ sign | The credential email does not label the account | That aliases and recovery settings are safe |
| No URL or sign-in phrase | The message does not disclose the entry point | That the second channel is independent |
| Managed invitation suppressed | Cognito does not send a competing message | That retries and resends are abuse-resistant |
| Secret absent from logs | Common observability paths do not retain it | That every downstream system is clean |
The documentation behind the decision.
These are current AWS primary sources; behavior and service guidance can change.
Before shipping a credential message.
Use these prompts with the application’s own threat model and security review.
The invitation Cognito could not send.
A narrated walkthrough of the documented invitation constraint, the self-managed delivery boundary, and the test that keeps secret and context apart.