cdc-rba-site: a plain CDC login page for the RBA rules tests
Live at https://ppp.rba-rules.morenorub.io/ and https://stg.rba-rules.morenorub.io/
(DreamHost shared hosting, Apache, the two hosts serve the one folder
~/ppp.rba-rules.morenorub.io, beside the other IOC PoCs; the previous host,
ppp.morenorub.io, redirects there with a 301).
Static pages with the SAP CDC Web SDK and a screen-set, nothing else: no OIDC,
no backend, no build step. It exists to try every risk-based authentication
(RBA) rule of a site and watch what the SDK reports. It is an educational PoC,
so every page sits at its own visible route. The root redirects to the login
page (302, in the .htaccess).
Pages
| Page | What it shows |
|---|---|
login.html |
Opens the login screen when there is no session; onLogin goes to the console with the risk assessment. |
register.html |
Opens the registration screen, same header and session line, to see which rules fire on a new account. |
findings.html |
The main findings of the RBA tests so far, public and without detail: generated at deploy from findings.md. Linked from the header of every page. |
tests.html |
One line per test run (date, tenant, what, outcome), generated from tests.md. |
readme.html |
This file as a page of the site, generated at deploy from README.md with marked and page-template.html. README.md itself is still served as plain text (.htaccess). |
Sites and the selector
The page talks to one CDC site at a time and the selector in the header
switches between the ones listed in sites.js. The same files are published
under one host per tenant (ppp.rba-rules.morenorub.io,
stg.rba-rules.morenorub.io), so the address bar names the tenant under
test: the host decides the site, and picking another site in the selector
moves to its host. The page reloads because gigya.js is loaded once per
page and cannot change apiKey while it runs. On a host that is not in the
list (a local copy) the query parameter decides (?site=stg), then the last
choice stored in localStorage (key rba.site), then the first entry of the
list (PPP).
| Site | apiKey | What it is |
|---|---|---|
| PPP · RBA test site (default) | 4_uVG18hGCJy1mRnrse6eJAg |
Juan's own site inside the Olympics PPP group, data center EU1. The RBA policy is the group's, on the parent; the "Test -" rules of the group list only this key. Screen-set: the console default (OIDC-RegistrationLogin today). |
| STG · captcha-stg-olympics | 4_7r7E7H56wqkX8L3HHq92Fg |
The standalone STG site of the enforced-captcha PoC (morenorub.io/cdc/cdc-enforced-captcha/, August 2026), where the counters, the captcha box recipe and the ATO measurements were made. Its rules and ATO switch are its own. Screen-set: Captcha-Test-RegistrationLogin, set in sites.js because it carries the captcha widget. |
Under the header, the environment band says where the page is (tenant pill,
apiKey, data center, screen-set) and, in a box closed by default that
remembers its state, lists what the configuration of that site allows, read from the settings the SDK downloads for the apiKey
(gigya.partnerSettings), without any call to CDC:
| Check | Why it matters |
|---|---|
| Captcha keys | Captcha credentials are per site, not inherited from the group. Without them a rule with action captcha still answers 401020 and the user has no widget to clear it: only lockout rules (403120) can be shown. The check reads the provider and the reCAPTCHA site keys (Enterprise, v2, invisible). Whether the screen-set carries the widget is not in the config: open the login screen and look. |
| Trusted domain | The Trusted Site URLs the site config carries. Information only: a host added at group level does not appear in the site's own list, and the SDK does not stop on an untrusted host, it only sends a report. |
| Screen-set | Where the collection the page opens comes from: the site list, the console default or the fallback. An empty screen means the name does not exist on that site. |
| Site group | A member shares the RBA policy of the parent (ssoKey in the config names it); a standalone site owns its rules. |
| Proxy in the path | storageDomainOverride in the global configuration sends the SDK frames to that host. On the PPP group it is olympicid.ppp-www.olympics.com, behind Akamai Bot Manager: headless Chromium is cut there, real Chrome passes. |
If the SDK answers with a domain error, the host is missing from the
trusted site URLs of that site in the CDC console (the band says so). The PPP
site has no CNAME prefix, so the SDK talks to accounts.eu1.gigya.com
directly and no reverse proxy is needed (the Olympics PPP sites use the
prefix olympicid, which on this domain has no certificate; that is why the
page has a site of its own). If the page loads but the screen stays empty, the
site has no default screen-set in the console and the fallback name does not
exist: set the default in the console, add a screenSet to the site entry or
change FALLBACK_SCREEN_SET.
Files
| File | Role |
|---|---|
login.html |
The header (Olympic rings, Olympics.com, the site selector, the RBA tests tag), the environment band, the session line, the Login and Register buttons, #container for the screen-set. Loads sites.js and rba.js; there is no static gigya.js tag, rba.js inserts the one of the chosen site once it is parsed. data-start-screen="gigya-login-screen" on the body. |
sites.js |
The list of CDC sites (SITES: id, label, env, apiKey, optional screenSet override), currentSite() (query parameter, then stored choice, then the first entry), switchSite() (store, put in the URL, reload) and loadGigyaSdk() (inserts the SDK tag for an apiKey). |
register.html |
Same page with data-start-screen="gigya-register-screen": the registration screen opens on load. |
rba.js |
onGigyaServiceReady registers onLogin and onLogout once, paints the environment band and its checks from gigya.partnerSettings, and asks CDC for the session: a live session paints the green line, no session paints the screen named by the body attribute. Every event payload goes to the console. loginWithRaaS, registerWithRaaS, logoutWithRaaS wrap showScreenSet and accounts.logout. Fills the site selector on DOMContentLoaded and, as its last statement, loads the SDK of the current site. |
(CDN) @animateicons/vanilla@0.2.0, lucide.js |
Draws the animated file-text icon of the README link (<animate-icons>). A trial of AnimateIcons for the fleet: pinned version, 948 KB raw / 109 KB gzip, played from rba.js on hover of the whole link. |
page-template.html |
The head and the header of the site around two markers where the deploy puts the page title and the converted Markdown (findings.md, tests.md, README.md). |
rba.css |
Colours as variables, then one block per band of the page: header and selector, environment band and checks, session line, title and actions, screen-set container. |
.htaccess |
Apache rules: dotfiles answer 404, the root goes to login.html, README.md is plain text, 10 minute cache on .js and .css. |
deploy-rba-site.sh |
Generates the Markdown pages (marked, pinned) and uploads the files to the folder on DreamHost over rsync (dreamhost), comparing each one back over HTTP. Both hosts serve that folder. |
Where the look comes from
The header follows olympics.com: a thin white bar with a light line under it,
the five rings at a discreet size and the name in a system sans. The page
started from the OP test pages in docs/la28-new-op-pages/ (live under
ioc/ on morenorub.io) and kept only their centered container; every OIDC
piece of those pages (the OIDC SDK, consent and error pages, logout pages)
stays out.
Deploy
./deploy-rba-site.sh
The .htaccess caches .js and .css for 10 minutes (DreamHost's default
is 30 days), so a hard reload shows the new version at once. The ?v=
suffix in the pages is kept as a habit and is bumped on bigger changes (2026-10-26d today).
What to look at during the RBA tests
- Open
/login.htmlwith DevTools on the Console tab. Check the environment band: the tenant you mean to test, and no warning about captcha keys or the trusted domain. Switch sites with the selector in the header. - Log in with an account of that site. Every challenge a rule triggers (captcha, TFA, account lock, an extra screen) is rendered by CDC inside the screen-set.
- On success the console prints
onLoginwith the full event payload, and the same object stays inwindow.lastLoginEventfor inspection. The session line under the bar shows the email and the UID. - Logout from the button on the session line;
onLogoutis logged too and the screen of the page comes back for the next case. With a session still open the page shows no form: every case starts from a logout, so RBA evaluates a clean login each time.
Errors the page shows
Every screen-set is opened with onAfterSubmit and onError, so a refused
submit reaches the page. The session line turns red and says the code and a
text (403120 · Account temporarily locked out (RBA rule)), the response is
logged and kept in window.lastSubmitResponse. For every code except
403042 (wrong login or password) and 403043 (login identifier exists),
whose field text the screen-set already explains, the same line replaces the
error text inside the form. The codes with a text of their own are in
ERROR_TEXTS in rba.js: 403042, 403043, 403120, 403100 (password change
required), 403101 and 403102 (two-factor pending), 206001 and 206002
(registration and email verification pending). Any other code shows the
errorMessage CDC sends.
The skill cdc-screensets-poc describes the pattern this page follows.