Skip to content

Send product User-Agent on backend calls to clear Cloudflare BIC#56

Merged
Daliys merged 1 commit into
developfrom
fix-broker-cloudflare-bic-ua
Jun 23, 2026
Merged

Send product User-Agent on backend calls to clear Cloudflare BIC#56
Daliys merged 1 commit into
developfrom
fix-broker-cloudflare-bic-ua

Conversation

@Daliys

@Daliys Daliys commented Jun 23, 2026

Copy link
Copy Markdown
Member

Problem (RC#1)

A server-mode broker (CI_SCOPE_SERVER_MODE=1) claimed no jobs for any repo for ~24h. moodling PR #66 sat queued, runner=none.

Root cause: every backend call in backend_request() used Python's default Python-urllib/x.y User-Agent. Cloudflare's Browser Integrity Check bans that UA with 403, error code 1010, at the edge — before the Worker runs. server_claim_queue recorded the 403 and returned nothing. Because it's UA-based, it hit every repo.

Proof — identical request, UA the only variable:

  • default curl UA → 401 (Worker reached)
  • Python-urllib/3.11 → 403, error 1010, server: cloudflare

Fix

backend_request() (the single chokepoint for heartbeat, claim, snapshot, and SSE) now sends User-Agent: CI-Scope-Broker/1.0, overridable via CI_SCOPE_USER_AGENT. Patching the UA locally flipped 403 → 401, confirming the edge clears.

New test: test_backend_request_sends_non_bot_user_agent. All 10 broker tests pass.

Not in this PR (need decisions / server side)

  • RC#2 token/contract mismatch — after the edge clears, heartbeat returns 401 authentication_required, which the server-queue Worker doesn't emit (it returns invalid_token), and the broker calls /v1/snapshot + /v1/events/stream which that Worker lacks. Deployed ci.forkhorizon.com is a different build than this branch. Needs: confirm what's deployed, reconcile CI_SCOPE_BACKEND_TOKEN ↔ backend CI_SCOPE_LOCAL_TOKEN, align /v1/* vs /api/ci/local/*.
  • RC#3 label routing — already operator-tunable via CI_SCOPE_MACHINE_LABELS; whether the backend should fan per-repo labels to brokers is a design call.
  • Observability — alert when backend.connected=false > N min (status is already persisted); unbuilt pending a yes.

🤖 Generated with Claude Code

Server-mode broker calls used Python's default Python-urllib/x.y
User-Agent, which Cloudflare's Browser Integrity Check 403s (error
1010) at the edge before the Worker runs. server_claim_queue saw the
403 and claimed nothing, for every repo, silently for ~24h.

Send User-Agent: CI-Scope-Broker/1.0 (overridable via
CI_SCOPE_USER_AGENT) from the single backend_request() chokepoint,
covering heartbeat, claim, snapshot, and SSE.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Daliys Daliys merged commit 728ab2d into develop Jun 23, 2026
3 checks passed
@Daliys Daliys deleted the fix-broker-cloudflare-bic-ua branch June 23, 2026 13:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant