Bilko — Chrome-specific login failure (Brave OK) — browser-compat troubleshooting — MC #8919

Bilko — Chrome-specific login failure (Brave OK) — browser-compat troubleshooting

MC #8919 | Priority L | Category frontend | Last verified 2026-08-08

Symptom

A real Chrome browser cannot complete login on the Bilko web app, while Brave (also Chromium-based) logs in fine on the same machine, and an automated Playwright/Chromium run also logs in fine.

Because Playwright's clean Chromium profile succeeds, the failure is not in Bilko's server-side code, CSP, or headers — it is local to the affected Chrome profile (extensions, cached state, cookies, or autofill extensions racing the login form). This runbook gives support staff a fast path to confirm that and fix the local profile, plus a script to re-verify the server side in seconds if this ever needs re-checking.

Current architecture (verified live 2026-08-08)

Bilko login is not a simple username/password POST — it goes through Microsoft Entra External ID (CIAM). The web app CSP must allow the CIAM domains for the login iframe/redirect to work at all:

Note on the original task's URL: the task was filed against bilko-demo.alai.no. That domain is retired — it was dropped from the post-deploy smoke checks in MC #105368 ("dropped dead bilko-demo.alai.no domain check", see DEPLOY-MAP.md). The live demo entry points are app.bilko.io / app.bilko.cloud / app.bilko.company. If a user reports this again, confirm which host they actually used first.

Note on the "raw run.app URL" long-term fix mentioned in the original task: this is already done. The web app is served from a custom domain (app.bilko.io etc.) via a Cloudflare Worker, not a raw *.azurecontainerapps.io URL — so the "ad-blockers flag .run.app/.azurecontainerapps.io" concern this task raised no longer applies to the primary login path.

Step 1 — Rule out the server side (30 seconds)

bash ~/system/tools/bilko-header-debug.sh app.bilko.io api.bilko.io

This fetches live headers from both hosts and checks that the web app's CSP still allowlists the CIAM domains (if it doesn't, that's a real CSP bug — stop here and file a build task). As of 2026-08-08 this passes: both CIAM domains are present in connect-src, and frame-src allows https://*.ciamlogin.com.

If this script passes, the problem is downstream of the server — i.e. it's the affected Chrome profile, per Step 2.

Step 2 — Browser-side checklist (Chrome-specific)

Work through these in order; each takes under a minute:

  1. Clean profile test. Open Chrome in a fresh/guest profile (or chrome --user-data-dir=/tmp/chrome-clean-test) and try login there. If it works, the problem is 100% the original profile's extensions/state — skip to step 3. If it still fails in a clean profile, this is no longer a "local issue" — escalate and re-open this task as a real bug.
  2. DevTools Network tab, filter by ciamlogin and microsoftonline. Look for requests with status (failed) net::ERR_BLOCKED_BY_CLIENT — that status specifically means a browser extension blocked the request, not a server/CSP problem.
  3. DevTools Console, look for Refused to connect/frame ... because it violates the following Content Security Policy directive. If you see this, capture the exact directive and re-run Step 1 — the live CSP may have regressed.
  4. Known culprits to disable one at a time (re-test login after each):
    • uBlock Origin — filter lists such as EasyPrivacy commonly block *.microsoftonline.com / *.ciamlogin.com as "MS telemetry". Toggle the extension off for the site, or check the blocked-request log (uBlock icon → the red counter → look for ciamlogin.com / microsoftonline.com entries).
    • Privacy Badger — blocks third-party cookies from domains it deems trackers after repeated visits; CIAM's cross-domain auth flow relies on a third-party cookie/redirect round-trip. Check its site report for "blocked" entries on the CIAM domains.
    • 1Password / other password-manager autofill — can race the login form's React state (autofill writes to the DOM input directly, bypassing React's controlled-input onChange, so the form's internal state never updates and submit sends empty/stale values). Test with the extension disabled, or manually re-type the last character in each field before submitting.
  5. Cookies for the CIAM domains. Chrome's third-party cookie handling differs by version/flag state from Brave's shields. Check chrome://settings/content/all (or the padlock → cookies) for ciamlogin.com / login.microsoftonline.com and clear them, then retry.

Step 3 — Fix and document

Once the culprit is identified (extension, stale cookie, or autofill race), the fix is local to that Chrome profile — there is nothing to change in the Bilko codebase for that specific case. Log the confirmed culprit here (append below) so future occurrences can skip straight to the fix:

Date Confirmed culprit Fix applied
(none confirmed yet — original 2026-04-23 report was never root-caused because Playwright already proved the server side clean; awaiting a reproduction with DevTools open)

Revision #2
Created 2026-08-08 04:55:45 UTC by John
Updated 2026-08-10 07:38:09 UTC by John