Skyline-ATS · For the customer's IT team

Setting up a Cognito pool for a training portal

Everything needed to connect one AWS Cognito user pool to a Skyline-hosted training portal. Work through it once per pool and it is done — the checks at the end exist because each one has previously cost a round trip.

Applies to one user pool Console Amazon Cognito Typical time 15 minutes
0 of 0 done

What this achieves

Learners open a training address, sign in with the credentials they already have in your Cognito pool, and go straight into their course. We never see or store a password, and we hold no client secret — the connection is a public OpenID Connect client using PKCE.

  1. You configure the app client below.
  2. You send us three values: region, user pool ID, app client ID.
  3. We connect it and run an automated check against your pool.
01

Create or open the app client

User pool → App clients

If a training app client already exists, open it. If not, create one — a name like skyline-training is fine.

02

Grant the OpenID Connect scopes

App client → Hosted UI / OpenID Connect scopes

03

Allow the app client to read name attributes

App client → Attribute read and write permissions → Edit

This is a different setting from the scopes in step 2, and it is the single most common reason a connection appears to work but learners have no name.

04

Assign a managed login branding style

App client → Managed login pages configuration → Edit

An app client with no branding style assigned returns “Login pages unavailable. Please contact an administrator.” — even when every other setting is correct. The default style is fine to get working; it just has to exist and be saved.

Making it look like your product

This is the one screen in the whole journey where someone types a password, and by default it carries AWS's pastel gradient and no logo at all. The branding editor takes a logo, a background image, colours, fonts and corner radius — enough to sit alongside your own sign-in page. It does not take custom CSS, so effects like an animated background cannot be carried over; exporting a still frame of that background as an image gets very close.

Do it once, then copy it to the other pools

Repeating this by hand for every pool is where the differences creep in. Style one pool in the console until you are happy with it, then copy that exact configuration across with the AWS CLI rather than rebuilding it:

Read the style you have just built
  • aws cognito-idp describe-managed-login-branding \ --user-pool-id <styled-pool> \ --managed-login-branding-id <id> \ --return-merged-resources > branding.json
Apply it to another pool's app client
  • aws cognito-idp create-managed-login-branding \ --user-pool-id <other-pool> \ --client-id <other-app-client> \ --settings file://settings.json \ --assets file://assets.json

The settings and assets come out of the first command — assets are the base64 images, settings the colours and layout. Use update-managed-login-branding instead of create- where a style already exists. Check the exact flags with aws cognito-idp describe-managed-login-branding help, since the branding API is newer than most of Cognito and the parameters have moved.

05

Add the callback URLs we send you

App client → Login pages → Allowed callback URLs

We will send an exact list with this document — one per training address. Cognito matches these character for character, so paste them rather than retyping.

Shape of the values — use the list we send, not these
  • https://<training-address>/auth/callback
06

Set the token lifetimes

App client → Authentication flow session duration / token expiry

07

Sign-out URLs — usually nothing to do

App client → Login pages → Allowed sign-out URLs

Signing out of training clears the training session only and leaves your Cognito session alone, so no sign-out URL is required. Tell us if you would rather signing out of training also signed the user out of Cognito — be aware that would sign them out of any other application sharing the pool — and we will send exact values to register.

08

Point your DNS at us

Your DNS provider · one CNAME per training address

Only needed if the training runs on your own domain, such as academy.example.com. If we have given you an address ending in .learn.skyline-ats.dev, that is already live and there is no DNS to change — skip this step.

One CNAME per address, all to the same target
  • academy.example.com   CNAME   connect.skyline-ats.dev

Every training address points at the same target. That is deliberate and is how your current host works too — the address a visitor typed travels with the request, so one entry point can serve many sites and still show each the right one.

Send us these three values

That is everything we need. All three are safe to send by email — none is a secret.

ValueWhere to find itExample
RegionShown in the console header, or the first part of the pool IDus-east-1
User pool IDUser pool → Overviewus-east-1_AbC123xyz
App client IDApp clients → the client you configured28p36eetg47ol3rj5bi8l3glts

Why this usually takes a second attempt

Every item here has actually happened. They share a shape: the configuration looks complete, every obvious check passes, and something still fails days later.

01

Scopes granted, attributes still unreadable

Granting profile does not make given_name readable — attribute read permissions are a separate screen. The sign-in succeeds, the learner has no name, and their completion certificate prints an email address instead.

Both steps 2 and 3 are required. Neither alone is enough.

02

Callback and sign-out are different fields

They sit next to each other and accept the same-looking values. A previous round of this request put the URLs into Allowed sign-out URLs only, which left sign-in failing with redirect_mismatch while the console looked correctly filled in.

03

No branding style means no login page

An app client without a managed login branding style serves “Login pages unavailable”. Every automated check still passes — the scopes are right, the callback is registered — and a real person still cannot sign in. Deleting a style later un-assigns it and reintroduces this.

04

A 60-minute refresh token is not a session

It is Cognito's minimum, so it looks like a deliberate value. Because it expires with the access token it can never renew anything, and learners are logged out an hour in — which reads as a fault in the training platform rather than a token setting.

05

CAA records left behind by the previous host

Only affects a move from another hosting provider. Some providers add CAA records that name only their own certificate authority, which can block ours from issuing.

There is usually nothing to do: those records sit on the provider's own hostname and stop applying the moment the CNAME points at us. It is worth knowing because it is the reason a certificate can take an extra minute on the first request rather than being instant.