Phase 2: harden Compass fetcher for the Cloudflare login-POST challenge
- retry the login on a fresh browser context (stale cf_chl_rc_ni cookies loop the next challenge) and fail loudly with cloudflare_login_post_challenge - detect the Compass login-rejection message and second-factor prompts - docs: record that Cloudflare's managed challenge blocks the headless login POST (GET passes), what was tried, and the unblock options Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
# Phase 2 — Compass login + fetch notes
|
||||
|
||||
Status: **partially proven.** The browser path to Compass works; the login and
|
||||
per-child fetch are blocked on a Compass credential that is not available to the
|
||||
agent. See AUD-104.
|
||||
Status: **blocked on Cloudflare.** The credential is available and the login
|
||||
page loads, but Cloudflare's managed challenge blocks the login **POST** under
|
||||
the headless harness. See AUD-104.
|
||||
|
||||
## Harness used
|
||||
|
||||
@@ -41,6 +41,27 @@ The fix that works:
|
||||
With both, the challenge clears in ~5 s and the real login page loads. Both are
|
||||
implemented in `scripts/compass-fetch.mjs`.
|
||||
|
||||
### The login POST is the hard part
|
||||
|
||||
When the form is submitted (`POST /login?handler=Login`) Cloudflare returns a
|
||||
**403 managed challenge** and serves `Just a moment...`. Under headless Chrome
|
||||
that challenge does not clear (`iframes=0`, body "Compass is verifying your
|
||||
connection..."), so Compass never sees the login. Captured response headers on
|
||||
the blocked POST show `server: cloudflare`; the GET of the same page passes.
|
||||
|
||||
Tested and did **not** fix it: a normal desktop-Chrome UA override, isolated
|
||||
browser contexts, `Sec-CH-UA` user-agent metadata, focus/visibility emulation,
|
||||
client hints, and long waits (up to 4 minutes).
|
||||
|
||||
The POST passes only intermittently. It was observed returning `200` twice, but
|
||||
five further attempts (including after a 75 s cooldown, each in a fresh context)
|
||||
were all challenged. `scripts/compass-fetch.mjs` retries the login on a fresh
|
||||
browser context up to `COMPASS_LOGIN_ATTEMPTS` (default 4) and fails loudly with
|
||||
`cloudflare_login_post_challenge` (exit 2) if none get through.
|
||||
|
||||
This is the Phase 2 risk: the harness can read Compass but cannot log in from
|
||||
headless Chrome.
|
||||
|
||||
## Proof stored (2026-10-15)
|
||||
|
||||
```
|
||||
@@ -56,17 +77,21 @@ var/raw/harry/<runId>/manifest.json
|
||||
|
||||
## Blocked on
|
||||
|
||||
A Compass account credential (not `HeadlessChrome`-related, not a Cloudflare
|
||||
issue). Nothing matching `COMPASS*`, `SCHOOL*`, `NORTHCOTE*`, `HARRY*`, `FINN*`,
|
||||
or `TEAMS*` exists in `~/.config/environment.d/10-secrets.conf` or the paperclip
|
||||
secrets available to the agent. The account can be a parent/guardian account or
|
||||
per-child; confirmation of whether Compass enforces a one-time code on a new
|
||||
device is also needed.
|
||||
A reliable way past Cloudflare's managed challenge for the login POST. The
|
||||
credential itself is no longer missing: it is in
|
||||
`~/.config/environment.d/10-secrets.conf` as `COMPASS_USERNAME` / `COMPASS_PASSWORD`.
|
||||
|
||||
Options (owner: Sam, because they are host/infra or browser decisions):
|
||||
|
||||
1. Give the harness a **headful** Chrome (e.g. add `xvfb` to the `.13` NixOS
|
||||
config and run Chrome non-headless). Managed challenges normally pass there.
|
||||
2. Supply a `cf_clearance` cookie from a real browser session on the same public
|
||||
IP and user agent, as a secret to inject.
|
||||
3. Confirm a non-CF login path (SAML/SSO or the Compass mobile API) to pursue.
|
||||
|
||||
## Smallest useful scope for Phase 3
|
||||
|
||||
The login page exposes a username/password form and a parent one-time-code
|
||||
option. Until a login succeeds we cannot enumerate the per-child page URLs, so
|
||||
the smallest useful scope cannot be fixed yet. It is expected to be the
|
||||
Until a login succeeds we cannot enumerate the per-child page URLs, so the
|
||||
smallest useful scope cannot be fixed yet. It is expected to be the
|
||||
"today/planner" page plus the messages/notices list, which is what answers "what
|
||||
is overdue".
|
||||
|
||||
Reference in New Issue
Block a user