Identity providers
FunctionPilot signs users in through an Amazon Cognito user pool in your account. The pool federates to your identity provider. This guide covers:
- IAM Identity Center, the primary option;
- Microsoft Entra ID and Okta over SAML 2.0;
- OIDC;
- Cognito-only users, with no external identity provider.
IAM Identity Center and Cognito-only users work on every plan. Other SAML identity providers and OIDC
are part of the Team plan and above. You choose one with the stack parameter IdentityProvider.
In every case, the IdP must send:
email. It is required, and it is the identity used for roles, grants, saved tests and the audit log.groups(optional). Used for group-based roles and grants.
Because roles and grants are keyed on email, the email must be one users can't set for themselves:
| How the user signs in | Email trusted when |
|---|---|
| SAML: IAM Identity Center, Entra ID, Okta | Always: it is asserted by your directory and signed by the IdP. Map it from an attribute only administrators control (see the notes per IdP below) |
| OIDC | The IdP says the email is verified (email_verified, or the claim you name in OidcEmailVerifiedClaim) |
| Cognito user pool user | The email is marked verified. Users can't change their own email |
A user whose email isn't trusted is refused on every request, sees a message that their email address isn't trusted, and can't use the portal at all. See the Security overview.
Sessions: ID tokens last one hour and are renewed with a refresh token that lasts 8 hours and is revoked when the user signs out. Your IdP's own session and MFA rules apply at each sign-in.
IAM Identity Center
IAM Identity Center can't be configured by CloudFormation for a customer managed SAML application, so the setup takes two steps.
Step 1: Deploy the stack
Deploy with IdentityProvider = IAMIdentityCenter and leave SamlMetadataUrl empty. When the
stack is complete, copy these outputs:
SamlAcsUrl:https://<NamePrefix>-<account>.auth.<region>.amazoncognito.com/saml2/idpresponseSamlAudienceUri:urn:amazon:cognito:sp:<user pool id>PortalUrl
Step 2: Create the custom SAML 2.0 application
- Open the IAM Identity Center console, in the Region where your Identity Center instance lives (this can differ from the stack's Region).
- Go to Applications › Add application. Choose I have an application I want to set up, then SAML 2.0, then Next.
- Fill in the configuration:
- Display name:
FunctionPilot(shown in the AWS access portal). - Application start URL: the
PortalUrloutput. With this set, the access portal tile starts a sign-in from FunctionPilot, which is what Cognito expects. - Relay state: leave it empty.
- IAM Identity Center metadata: copy the IAM Identity Center SAML metadata file URL. You need it in step 5.
- Application metadata: choose Manually type your metadata values:
- Application ACS URL: the
SamlAcsUrloutput. - Application SAML audience: the
SamlAudienceUrioutput.
- Application ACS URL: the
- Display name:
- Choose Submit.
Step 3: Attribute mappings
Open the application and go to Actions › Edit attribute mappings:
| User attribute in the application | Maps to this value | Format |
|---|---|---|
Subject | ${user:email} | emailAddress |
email | ${user:email} | unspecified |
groups (optional, see below) | ${user:groups} | unspecified |
Save the changes.
Groups and IAM Identity Center. Identity Center doesn't officially support sending group names in SAML assertions.
${user:groups}is available but not documented as a supported attribute, and it sends group IDs (GUIDs such as90677c4b-...), not display names. If you map it:
- Assign roles and grants to groups in FunctionPilot using the group ID as the group name. Find it in Identity Center under Groups, on the group's page.
- Cognito stores a user's groups in a 2,048-character attribute. Users in many groups (more than about 50 GUIDs) may have the list cut short, or the sign-in may fail. Keep group membership for this application focused.
If you don't map groups, assign roles and grants per user (by email). This is the simplest and fully supported approach.
Step 4: Assign users and groups
In the application, open Assigned users and groups › Assign users and groups. Add the people or groups who may use FunctionPilot. Only assigned users can sign in.
Step 5: Update the stack
Update the stack with the current template, keep every other parameter, and set
SamlMetadataUrl to the metadata URL you copied in step 2. The update:
- creates the Cognito SAML provider
IAMIdentityCenter; - switches the portal's app client to that provider;
- redeploys the portal configuration, so users go straight to Identity Center.
Step 6: Test
Open PortalUrl, or the tile in the AWS access portal. Sign in as BootstrapAdminEmail. You should
land on the Functions page with Administration in the top bar.
If your Identity Center certificate is rotated, Cognito picks up the new certificate from the metadata
URL. If you replace the application, update SamlMetadataUrl.
Identity Center and personal AWS access
If you also set IdentityCenterStartUrl (or turn on IAM Identity Center in
Administration › Settings › Personal AWS access), people who sign in through Identity Center work
with their own permission sets instead of FunctionPilot grants: after sign-in they connect their
Identity Center session and choose accounts and permission sets. See
Personal AWS access. Without it, they use grants like everyone else.
Other SAML identity providers
Team plan and above. Deploy with IdentityProvider = SAML, follow the two-step pattern above, and
enter the values below in your IdP.
Microsoft Entra ID
- Go to Enterprise applications › New application › Create your own application. Choose Integrate any other application you don't find in the gallery.
- Single sign-on › SAML. In Basic SAML Configuration:
- Identifier (Entity ID):
SamlAudienceUri - Reply URL (Assertion Consumer Service URL):
SamlAcsUrl - Sign on URL:
PortalUrl
- Identifier (Entity ID):
- Attributes & Claims:
- Unique User Identifier (Name ID):
user.userprincipalnameoruser.mail, in theEmail addressformat. - Add a claim with the name
email(no namespace) and the source attributeuser.mail. - Add a group claim. Choose Groups assigned to the application. Set the source attribute to
Cloud-only group display names for names, or Group ID otherwise. Under Advanced options,
select Customize the name of the group claim and set the name to
groups.
- Unique User Identifier (Name ID):
- Copy the App Federation Metadata Url into
SamlMetadataUrl. - Assign users and groups to the enterprise application.
Entra ID sends group display names only for cloud-only groups. For synced groups, use
sAMAccountName or IDs.
The email claim is trusted. user.mail is set by administrators (or synced from Active Directory)
for member users. If guests (B2B) are assigned to the application, or users can edit mail in your
tenant, use user.userprincipalname instead, where the UPN is the user's email.
Okta
- Go to Applications › Create App Integration › SAML 2.0.
- Fill in the SAML settings:
- Single sign-on URL:
SamlAcsUrl. Tick Use this for Recipient URL and Destination URL. - Audience URI (SP Entity ID):
SamlAudienceUri. - Name ID format:
EmailAddress. Application username:Email. - Attribute statement:
emailfromuser.email. - Group attribute statement:
groups, filter Matches regex.*. A narrower filter, such as^functionpilot-, is recommended.
- Single sign-on URL:
- On the Sign On tab, copy the Metadata URL into
SamlMetadataUrl. - Assign people and groups.
The email attribute is trusted. In Okta, make sure end users can't change their own primary email
without verification: in Directory › Profile Editor › User (default), set email to Read only
for users, or keep Okta's default of verifying a changed email before it takes effect.
OIDC identity providers
Team plan and above. Store the client secret in AWS Secrets Manager (a plain-text secret value), then
deploy with IdentityProvider = OIDC and set OidcIssuer, OidcClientId and OidcClientSecretArn.
The identity deploying the stack needs secretsmanager:GetSecretValue on that secret. There is no
second step.
In your IdP, create a confidential web client:
- Redirect URI:
<CognitoDomain>/oauth2/idpresponse, for examplehttps://functionpilot-123456789012.auth.eu-west-2.amazoncognito.com/oauth2/idpresponse. - Scopes:
openid email profile. - Claims:
email, a claim saying the email is verified (see below), and optionallygroups. Cognito reads claims from the userinfo endpoint, so make sure your IdP includesgroupsthere. Okta needs a groups claim on the authorization server; Entra ID needs groups added under Token configuration.
The issuer must serve /.well-known/openid-configuration.
Verified email (required)
Many OIDC IdPs let users, or guests from other organisations, set their own email address. Because
roles and grants are keyed on email, the stack maps the IdP claim named by the OidcEmailVerifiedClaim
parameter (default email_verified) to Cognito's email_verified, and FunctionPilot refuses any OIDC
user for whom it isn't true, including the BootstrapAdminEmail user.
| IdP | What to do |
|---|---|
| Okta | Nothing: Okta sends email_verified with the email scope. Keep primary email changes verified (see Okta). |
| Google Workspace, Auth0, Keycloak, Ping | Nothing: they send email_verified. In Keycloak, keep Verify email on (or mark users' emails as verified) in the realm. |
| Microsoft Entra ID | Entra ID doesn't send email_verified. Prefer SAML. For OIDC, in the app registration open Token configuration › Add optional claim › ID and add xms_edov (email domain owner verified), then set OidcEmailVerifiedClaim = xms_edov. It is true only when the email's domain is verified in the user's tenant. Use a single-tenant app registration (issuer https://login.microsoftonline.com/<tenant id>/v2.0), never common or organizations. |
| Other | Find the claim your IdP uses to say the email is verified and set OidcEmailVerifiedClaim to its name. If your IdP has no such claim, use SAML instead. |
Cognito updates mapped attributes only when a user signs in through the IdP, so after you deploy or change this, users who were refused must sign out of the portal and sign in again.
How groups reach FunctionPilot
The IdP's groups attribute is mapped to the Cognito attribute custom:groups, which appears in the
ID token FunctionPilot reads.
When the IdP sends several values, Cognito joins them into one string of the form [groupA,groupB],
and URL-encodes values that contain characters other than letters, digits, ., -, * and _.
FunctionPilot decodes this format. When you assign roles or grants to a group, type the group name
exactly as the IdP sends it (group names are case-sensitive).
Cognito-only users
With IdentityProvider = CognitoOnly, users exist only in the Cognito user pool:
- Self sign-up is disabled; administrators create users.
- Passwords need at least 14 characters with lower and upper case letters, digits and symbols. Temporary passwords are valid for 3 days.
- TOTP MFA (an authenticator app) is required for everyone.
Create users in the Cognito console (User pools, the <NamePrefix>-users pool, Users ›
Create user), or from the AWS CLI:
aws cognito-idp admin-create-user --user-pool-id <UserPoolId> \
--username [email protected] \
--user-attributes Name=email,[email protected] Name=email_verified,Value=true \
--desired-delivery-mediums EMAILThe email must be verified: in the console, tick Mark email address as verified when you create the user. Users whose email isn't verified are refused. To fix an existing user:
aws cognito-idp admin-update-user-attributes --user-pool-id <UserPoolId> \
--username [email protected] --user-attributes Name=email_verified,Value=trueUsers can't change their own email. If an administrator changes a user's email, Cognito keeps the old,
verified address in effect until the new one is verified (or the administrator sets
email_verified=true in the same call).
To use groups with Cognito-only users, create groups in the user pool (Groups › Create group) and add users to them. FunctionPilot reads the user pool groups from the ID token, so roles and grants on those group names apply.
By default, Cognito sends a limited number of emails per day. For more than a handful of users, configure Amazon SES for the user pool.
Something unclear or missing? Email [email protected].