Skyline-ATS · For the customer's IT team
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.
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.
User pool → App clients
If a training app client already exists, open it. If not, create one — a name like
skyline-training is fine.
App client → Hosted UI / OpenID Connect scopes
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.
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:
aws cognito-idp describe-managed-login-branding \
--user-pool-id <styled-pool> \
--managed-login-branding-id <id> \
--return-merged-resources > branding.jsonaws 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.
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.
https://<training-address>/auth/callbackApp client → Authentication flow session duration / token expiry
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.
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.
academy.example.com CNAME connect.skyline-ats.devEvery 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.
That is everything we need. All three are safe to send by email — none is a secret.
| Value | Where to find it | Example |
|---|---|---|
| Region | Shown in the console header, or the first part of the pool ID | us-east-1 |
| User pool ID | User pool → Overview | us-east-1_AbC123xyz |
| App client ID | App clients → the client you configured | 28p36eetg47ol3rj5bi8l3glts |
Every item here has actually happened. They share a shape: the configuration looks complete, every obvious check passes, and something still fails days later.
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.
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.
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.
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.
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.