06-reference/research

hq raydata co access policy verification

2026-07-22·research-brief·source: deep-research·by Ray Data Co (deep-research synthesis)
cloudflareaccesssecurityhq-raydata-coverification

The live hq.raydata.co Access policy is literal-email — close the item, but the login method is one-time PIN, not the Google SSO the vault assumed

The question

Is the live hq.raydata.co Access policy literal-email or domain? — quick check, then either close or fix.

Follow-up #2 from the 2026-05-11 Cloudflare Tunnel security brief, and item #1 on that brief's "live discipline TODAY" checklist — an open founder action since May.

What we already know (from the vault)

What the live config says

VERIFIED live, read-only, 2026-07-22 via ~/.claude/scripts/cloudflare-api.sh against account 5d4a0efe3ae671cf9cf3265eb1ff738c ("Ben@raydata.co's Account").

Six Access applications exist. The target app:

{
  "id": "c0c24227-b228-45bf-81df-45943b56ccd4",
  "name": "HQ Ray Data",
  "domain": "hq.raydata.co",
  "type": "self_hosted",
  "session_duration": "24h",
  "allowed_idps": [],
  "auto_redirect_to_identity": false,
  "policies": [
    {
      "id": "d9a4fa4e-d3d9-4145-93e3-beabe8bd2606",
      "name": "Allow Ben only",
      "decision": "allow",
      "include": [ { "email": { "email": "ben@raydata.co" } } ],
      "exclude": [],
      "require": [],
      "session_duration": null
    }
  ]
}

This is an email rule (literal address), not email_domain, not an access group, not a login-method rule. One policy, one include, decision allow. No exclude, no require, no bypass policy, no non_identity (service-token) policy on this app. Session duration 24h. Not even ray@raydata.co is on it.

Account-wide there are zero Access groups (GET /access/groups"result": []), so nothing can be widening the policy indirectly.

The sibling API app, for completeness:

{
  "id": "44f3e75d-298f-4cf8-bad0-08078ac78b2b",
  "name": "HQ Ray Data API",
  "domain": "hq-api.raydata.co",
  "session_duration": "24h",
  "policies": [
    { "name": "Allow Ben", "decision": "allow",
      "include": [ { "email": { "email": "ben@raydata.co" } } ] },
    { "name": "Allow hq-frontend service token", "decision": "non_identity",
      "include": [ { "service_token": { "token_id": "6b0fa8f4-dd8a-41c6-ab4f-87acf7cef600" } } ] }
  ]
}

The service token is hq-frontend-to-api (client_id d409f137c2c6036fa5274abffbff7c88.access), scoped to the hq-api.raydata.co app only — it does not appear on the hq.raydata.co app. That is the correct per-app scoping the May brief asked for. Its expires_at is 2126-03-30T11:02:00Z — a 100-year expiry.

The quick-sites apps alongside (checked as instructed, not the target) are all literal-email as well: *.rdco.dev "owners only" = ben@raydata.co + ray@raydata.co; home.rdco.dev and demo.rdco.dev add bwilson668@gmail.com; ink.rdco.dev = akim@phdata.io + ben@ + ray@. No email_domain include rule exists anywhere on the account.

The one live/vault divergence: the only identity provider configured on the account is

[ { "id": "cb1a29d5-a57c-4f20-a877-db9f8ead64ec", "name": "", "type": "onetimepin" } ]

There is no Google/Workspace IdP. allowed_idps: [] on the app means "all configured IdPs," and the only one configured is one-time PIN. So HQ login is email OTP to ben@raydata.co, not the Google SSO the proposal and the May brief both describe.

Commands run (all read-only GETs; nothing mutated): cloudflare-api.sh whoami; GET /accounts/<acct>/access/apps?per_page=50; GET /accounts/<acct>/access/apps/{c0c24227…, 44f3e75d…, ddd7fa5b…, 31f6d6eb…, 88aac54a…, 49e1de4a…}; GET /accounts/<acct>/access/groups; GET /accounts/<acct>/access/identity_providers; GET /accounts/<acct>/access/service_tokens.

What the web says

Convergences and contradictions

Synthesis for RDCO

CLOSE the item as asked. The question was literal-email or domain; the answer is literal-email, verified against raw API output, with zero access groups and zero bypass or non-identity policies on the HQ app that could widen it out of band. Item #1 on the May 11 "live discipline TODAY" checklist and follow-up #2 are both retired. No remediation command is warranted, and nothing was mutated in the course of checking. With the board-router item retired on 2026-07-16, the May brief's founder-action checklist now has only FileVault verification outstanding.

But the check surfaced a different, more interesting finding than the one it went looking for. The vault's stated security model for HQ — "Google SSO, MFA enforced at the Google account" — is not what is live. There is no Google IdP on the Zero Trust org at all. The actual chain is: request page → Access issues a 10-minute single-use PIN to ben@raydata.co → possession of that mailbox is the entire authentication factor. That is a materially different threat model from SSO. Under SSO, compromising Google mail alone is not enough; a phishing-resistant second factor stands between an attacker and HQ. Under OTP, mailbox compromise (or mail-forwarding-rule compromise, or a rogue mail-security scanner consuming the link — a documented Cloudflare failure mode) is HQ compromise. The blast radius is the founder's whole generative-UI substrate, including whatever the hq-api tunnel exposes off the Mac mini. This does not make the current setup bad — for a single-user internal dashboard with a literal-email include, OTP is a defensible posture and Cloudflare's docs treat it as supported — but the vault should describe it accurately, because a future decision ("can we let a contractor into HQ?", "should the CAF client demos live here?") will be reasoned from that description.

Recommended, not applied (read-only mandate): first, correct the record — [[2026-04-22-hq-proposal-v1.md]] and [[2026-05-11-cloudflare-tunnel-security-mac-mini.md]] both assert Google SSO and should be annotated with the live reality. Second, consider adding an IdP. Cloudflare made its own identity provider the default for new orgs on 2026-06-18 specifically because OTP was a weak default; adding the Cloudflare IdP (or Google Workspace SSO, which the proposal already intended) alongside OTP is additive and non-breaking — existing orgs keep OTP until they choose otherwise, and allowed_idps: [] would then accept either. That is a founder-gated change: it requires an OAuth dance the agent cannot complete, and it should be done with a second browser session open so a misconfiguration doesn't lock the founder out of his own dashboard. Third, a hygiene note orthogonal to the question: the hq-frontend-to-api service token expires in 2126. A 100-year non-expiring credential sitting in front of the Mac-mini API is worse hygiene than the literal-email policy is good; a 1-year expiry with a calendared rotation is the cheap fix.

The wider lesson repeats [[2026-07-16-fat-cat-board-router-token-scope.md]] almost exactly: the vault's security claims about Cloudflare Access all trace back to an April proposal document, and each one that gets checked against live config comes back partly wrong. Two for two now. Any remaining Access assertion in the vault should be treated as unverified until an API call says otherwise — and the API call takes under a minute.

Why this is in the vault

Closes follow-up #2 and retires live-discipline item #1 from [[2026-05-11-cloudflare-tunnel-security-mac-mini.md]], the security brief governing the Mac-mini Tunnel expansion of hq.raydata.co. It also corrects the authentication model recorded in [[2026-04-22-hq-proposal-v1.md]], which every future "who can reach HQ" decision (contractor access, CAF client demos, sharing a decision page) will otherwise be reasoned from incorrectly.

Open follow-ups

Related

Sources

Live configuration (primary evidence) — read-only, 2026-07-22, via ~/.claude/scripts/cloudflare-api.sh (1Password item Cloudflare Ray Account API Key, vault Ray Agent), account 5d4a0efe3ae671cf9cf3265eb1ff738c:

Vault

Web