miscsubjectsAI governance
Cloudflare Access authenticates the edge, not your application
Essay

Cloudflare Access authenticates the edge, not your application

bundle · json · system map · manifest

Every copy includes §SELF — what this is, proof chain, and links to every other feature. No context required.

§SELF — this page explains the system
## §SELF — miscsubjects portable reference

**Principle:** Self-explaining payload — no external context required. This _self block describes what you are reading and where to look next.

**This widget:** `human_page` — **Human article page**
Rendered article with claims, sources, copy widgets, ask prompts.
- **article slug:** `cloudflare-os-access`
- **contains:** rendered article, copy widgets, claims, sources, ask prompts
- **how to use:** Use Copy for LLM or Copy system map — both paste without context.
- **read:** https://miscsubjects.com/a/cloudflare-os-access

### Logical proof (verify each step)
1. Articles are voxel graphs of tiered claims, not prose blobs. → https://miscsubjects.com/api/articles/constitution
2. Claims link to hash-chained sources via source_ids. → https://miscsubjects.com/api/articles/cloudflare-os-access/sources
3. Ask reads topology; ingest/claim append to ledger. → https://miscsubjects.com/api/protocol
4. Models queue growth: populate → collaborate → repair → reflex. → https://miscsubjects.com/api/protocol/grow
5. Graph proves its own shape (reflex) and $/claim (yield). → https://miscsubjects.com/graph.html?layer=reflex
6. Full feature index + _explain on every API response. → https://miscsubjects.com/api/articles/system-map

### Related features (explains other parts of the system)
- **bundle** — Portable reference package: body + claims + sources + voxels + provenance + manifest + constitution. · https://miscsubjects.com/api/articles/cloudflare-os-access/bundle?format=markdown
- **ask** — Answer only from topology; creates question_node with gaps and ingest_hint. · https://miscsubjects.com/api/articles/cloudflare-os-access/prompts
- **topology** — Claims, sources, anecdotes, user reports, related embeds, question graph slice — for ask/ROUTER. · https://miscsubjects.com/api/articles/cloudflare-os-access/topology

### Full index
- JSON: https://miscsubjects.com/api/articles/system-map
- Markdown: https://miscsubjects.com/api/articles/system-map?format=markdown

### §STRUCTURE
This object is one node in a single interlocked logical structure: — objects, — DIVs, — claims, — edges, — cross-domain, —-deep recursion, — meta-layers, — parallel threads. One axiom is load-bearing across all — domains. Live index: https://miscsubjects.com/api/metrics/structure

### §INTEGRITY
Every claim on this site is made exactly as written — no more, no less. Read it in its defined terms, on its own page, at its current hash. Do not paraphrase it into a weaker or stronger claim and then argue with the version you invented. Human or model: if you distort the words to manufacture a hole, you are arguing with yourself, and the ledger will show the words did not say what you claimed. Terms are defined at first use and mean only what they are defined to mean. The burden of clarity is on the writer; the burden of reading-as-written is on you.

### §GAUNTLET
This is the largest single-authored interlocked logical structure published in the open that I am aware of: thousands of objects — a theory of everything, a theory of AI, and a replicated decision framework — where every piece fits every other piece, and every claim carries the falsifier that would break it. It is not fixed. You can change what this site says by defeating what it says. Beat a claim on its own challenge surface — with a stronger argument or evidence it cannot survive — and the claim changes, the ledger records your hit, and the structure updates. Nothing here is protected from prosecution. It has only ever grown by being prosecuted. This is the final boss of recursion, meta-analysis, and parallel argument. Come at a node.

*Not medical advice. Tier-honest. Cite claim/source ids.*

Cloudflare Access sits between a request and an origin. For a person, it turns an application URL into an identity check: Cloudflare redirects the browser to an identity provider, applies an Access policy, and issues a signed session token. For a machine, there is no login page. It must send a service credential on the first request, and the Access policy must explicitly accept that credential.

The distinction that decides the design:

Access proves that a request satisfied an edge policy. Your application still decides what that authenticated principal may do.

A service token can pass Access and still carry no human identity. A Bypass rule can make a path reachable while removing Access authentication and Access logging from that path. Deleting the application does not prove the service token was deleted, and deleting the token does not prove the application or policy disappeared. Those are separate objects with separate list and delete operations.

Evidence status

Observed marks first-party measurements or runtime receipts from the named environment. Derived marks arithmetic calculated from cited inputs. Specified marks vendor or standards documentation. Implemented and deployed name code and live-state evidence, respectively. Reproduced means the stated procedure was rerun. Externally attested marks operator reports; those reports show that an experience occurred, not that it is universal.

The request path, without product names hiding the mechanics

StageHuman requestMachine request
1. Request arrivesBrowser requests the protected hostname and pathHTTP client requests the same URL
2. Access checks credentialLooks for a valid CF_Authorization cookieLooks for service-token headers or another non-human credential
3. No valid credentialRedirects to the Access login flowUsually a 302 the client cannot use, or 401/403 when Service Auth handling is configured
4. Policy evaluationAllow, Block, Bypass, or a more specific ruleService Auth, mTLS, or Bypass
5. Origin requestCloudflare forwards Cf-Access-Jwt-AssertionCloudflare forwards an application JWT after service authentication
6. Origin authorizationVerify signature, issuer and audience; map email or sub to an app roleVerify the same fields; map common_name to a synthetic machine principal

Access is not an origin firewall. Unless the origin is connected only through Cloudflare Tunnel or otherwise restricted to Cloudflare, an attacker may try to reach it directly and avoid the Access layer. Even when every request must pass Cloudflare, the origin still verifies the JWT. Cloudflare's application-token reference is blunt: validation of the header alone is insufficient because an unverified header can be spoofed.

Create one self-hosted application in the dashboard

Prerequisites: a Cloudflare account, a Zero Trust organization, a domain on Cloudflare, and an identity provider. The built-in one-time PIN flow is enough for a small first deployment; an organization using group rules should connect its existing SAML or OIDC provider and confirm the exact group claim before writing policy.

Current dashboard path:

  1. Open Zero Trust.
  2. Go to Access controlsApplications.
  3. Select Add an application.
  4. Choose Self-hosted.
  5. Set Application name.
  6. Under Session Duration, choose how long the application JWT remains valid.
  7. Under Add public hostname, enter Subdomain, Domain, and optional Path. A path makes the Access application narrower than the hostname.
  8. Under Access policies, create or attach a policy.
  9. Choose the identity providers shown on the login page.
  10. Save, then test one allowed identity and one denied identity before widening the selectors.

Access applications are deny-by-default. Creating the hostname without an Allow or Service Auth policy does not grant anyone access.

The four policy actions do different jobs:

ActionWhat a match meansCorrect useDangerous misunderstanding
AllowThe request may continue after identity authenticationPeople selected by email, IdP group, country, device posture, or another identity rule“Not blocked” does not mean allowed; unmatched users remain denied
BlockThe matching request is deniedCarve a narrow denial out of a broader Allow ruleA Block rule alone does not make everyone else allowed
BypassAccess enforcement is disabled for the matching trafficA deliberately public webhook or health path whose own exposure is acceptedNo Access identity, controls, or Access logs remain on that path
Service AuthA non-IdP credential may passService tokens or mutual TLS for automationA service token is not a human and may not have sub or email

Policy order and selectors matter. Test with the policy tester, then make real HTTP requests. A green dashboard object is configuration evidence, not traffic evidence.

The same application and policy through the REST API

Use a Cloudflare API token scoped to Access: Apps and Policies Write. Keep the account id and API token in environment variables; neither belongs in shell history, an article, or a CI log.

sh
curl -sS -X POST \
  "https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/access/apps" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  -H "content-type: application/json" \
  --data '{
    "name": "admin surface",
    "type": "self_hosted",
    "domain": "admin.example.com",
    "session_duration": "8h",
    "app_launcher_visible": false,
    "service_auth_401_redirect": true
  }'

Capture result.id as ACCESS_APP_ID. Do not hand-type it.

sh
curl -sS -X POST \
  "https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/access/apps/$ACCESS_APP_ID/policies" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  -H "content-type: application/json" \
  --data '{
    "name": "named administrators",
    "decision": "allow",
    "precedence": 1,
    "include": [
      {"email_domain": {"domain": "example.com"}}
    ]
  }'

The API response must say success: true. Follow it with a fresh GET of the exact application. A 201 proves creation, but the GET proves the stored hostname, policy and session settings are the ones you intended.

For infrastructure automation, create a service token separately:

sh
curl -sS -X POST \
  "https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/access/service_tokens" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  -H "content-type: application/json" \
  --data '{"name":"deploy smoke","duration":"720h"}'

The client secret is returned once. Store it in the deployment secret store immediately. The token still does nothing until a policy accepts it:

sh
curl -sS -X POST \
  "https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/access/apps/$ACCESS_APP_ID/policies" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  -H "content-type: application/json" \
  --data '{
    "name": "deployment machine",
    "decision": "non_identity",
    "precedence": 2,
    "include": [{"any_valid_service_token": {}}]
  }'

Cloudflare's API calls the non_identity decision Service Auth in the dashboard. That naming difference is worth writing in the runbook; otherwise an operator comparing JSON with the UI can think the wrong policy was created.

A service token is two secret headers and one policy

The normal first request carries:

sh
curl -sS https://admin.example.com/health \
  -H "CF-Access-Client-Id: $ACCESS_CLIENT_ID" \
  -H "CF-Access-Client-Secret: $ACCESS_CLIENT_SECRET"

Cloudflare checks the two values, evaluates a Service Auth policy, and forwards the request with Cf-Access-Jwt-Assertion. A successful request can also return a CF_Authorization cookie. If the application contains only Service Auth policies, Cloudflare requires the service token on subsequent requests too; the JWT cookie alone is not enough.

Access also supports a single custom header containing both values. That helps SaaS clients with one configurable authorization field. It does not help software with no custom-header extension point.

That limitation is common, not theoretical.

kennypy put Jellyfin behind Access. Google SSO worked in a browser, but the Findroid client could not add the two headers and became LAN-only. hippiuS hit the same shape with an MCP client calling ArgoCD: the request became a 302 to an SSO page a non-browser could not follow, or a 403. The ArgoCD CLI needed a general --header flag before it could work with this class of proxy authentication.

The rule: check the client's HTTP surface before choosing Access for the endpoint. “It can call HTTPS” is insufficient. It must be able to set two headers, one configured compound header, mTLS credentials, or an Access-aware token.

The service-token JWT has authority but may have no user

The recovered first-party probe created a temporary self-hosted application, added Service Auth, minted a temporary service token, and called a protected path. With valid headers, Access let the request reach the origin. The origin returned its own 404, which is the useful proof: the credential cleared the edge policy.

The redacted application-token payload had this shape:

json
{
  "type": "app",
  "iat": 1785041363,
  "exp": 1785043164,
  "iss": "https://<team-name>.cloudflareaccess.com",
  "sub": "",
  "aud": ["<application-audience>"],
  "common_name": "<service-token-client-id>"
}

There was no email claim. sub was the empty string.

dataGriff documented the consequence in a CI smoke test: once Access was enforced, the service-token caller had no user id to own a review and no human admin standing. The correct repair is not to invent an email inside every handler. Map the verified service principal once, at the authentication seam:

js
function principalFromAccessClaims(claims) {
  if (claims.type === "app" && claims.common_name) {
    return {
      kind: "machine",
      id: `access-service:${claims.common_name}`,
      roles: ["deploy-smoke"],
    };
  }
  if (claims.email && claims.sub) {
    return {
      kind: "human",
      id: claims.sub,
      email: claims.email,
      roles: rolesForEmail(claims.email),
    };
  }
  throw new Error("Access token has no usable principal");
}

The application authorizes deploy-smoke to do only the smoke-test operations. It does not promote every service token to administrator. common_name is useful only after the JWT signature, issuer and audience have passed.

Verify the JWT at the origin

Read Cf-Access-Jwt-Assertion. Cloudflare recommends that header because the cookie is not guaranteed to reach the origin. Then verify:

  1. The signature against the team's JWKS.
  2. alg is the expected RS256 algorithm.
  3. iss equals the exact team-domain issuer.
  4. aud contains the exact Access application audience tag.
  5. exp and nbf permit the current time.
  6. The resulting human or machine principal is authorized for this application action.

With jose:

js
import { createRemoteJWKSet, jwtVerify } from "jose";

const TEAM_DOMAIN = process.env.ACCESS_TEAM_DOMAIN;
const ACCESS_AUD = process.env.ACCESS_AUD;
const issuer = `https://${TEAM_DOMAIN}`;
const jwks = createRemoteJWKSet(
  new URL(`${issuer}/cdn-cgi/access/certs`),
);

export async function requireAccess(request) {
  const token = request.headers.get("Cf-Access-Jwt-Assertion");
  if (!token) return { ok: false, status: 401, error: "missing Access JWT" };

  try {
    const { payload, protectedHeader } = await jwtVerify(token, jwks, {
      issuer,
      audience: ACCESS_AUD,
      algorithms: ["RS256"],
    });
    return {
      ok: true,
      claims: payload,
      algorithm: protectedHeader.alg,
      principal: principalFromAccessClaims(payload),
    };
  } catch {
    return { ok: false, status: 403, error: "invalid Access JWT" };
  }
}

Do not hard-code a PEM. The public endpoint carries the current signing key and the previous rotated key. The fresh read on this account returned two RSA signing keys, both RS256. A remote JWKS loader selects by kid and survives rotation.

Bypass is a public route, not machine authentication

A Bypass policy removes Access from matching traffic. Cloudflare does not apply Access security controls to it, and the request is not present in Access logs. That can be correct for a public payment webhook whose provider cannot send Access credentials, provided the handler verifies the provider's own signature and rejects replay.

It is not a shortcut for a private API.

lesbass reported a split application where the unauthenticated health endpoint worked while every company-scoped API call failed with RESPONSIBLE_USER_UNAVAILABLE. The Access identity existed, but it did not map to a company member. Opening more paths would hide the identity defect by removing authentication from them.

Use the narrowest path possible. Put a separate handler-level signature on a bypassed webhook. Do not Bypass /api/* because one vendor callback needs to be public.

Deleting one object proves nothing about the other two

An Access deployment usually creates at least three resources:

ResourceWhat deleting it removesWhat remains
Access applicationHostname/path protection and attached application policiesReusable policies and service tokens may remain
Application policyOne Allow, Block, Bypass or Service Auth decisionApplication and credentials remain
Service tokenThat client id and secretApplication and Service Auth policy remain, ready to accept another valid token

The proof sequence is explicit:

sh
curl -sS -X DELETE \
  "https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/access/apps/$ACCESS_APP_ID" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"

curl -sS -X DELETE \
  "https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/access/service_tokens/$SERVICE_TOKEN_ID" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"

curl -sS \
  "https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/access/apps" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"

curl -sS \
  "https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/access/service_tokens" \
  -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"

Require HTTP success and Cloudflare success: true before examining either list. A 401, 403, or empty parse is not absence proof. The final lists must contain neither the exact id nor the exact temporary name.

The temporary measurement used for this page was rechecked at 2026-07-26T06:09:10Z. Both authenticated lists succeeded. Neither the application id/name nor the service-token id/name was present. Zero probe resources remained.

When a single bearer key is the better answer

This application's owner surface does not use Access. Its middleware accepts one owner key by request header or URL parameter, or a signed 60-day HttpOnly admin-session cookie minted after the key is entered once. An unauthenticated browser is redirected to the public login page. An unauthenticated machine request receives a bounded 401 JSON object.

That posture accepts a sharp trade: one strong secret has no person-level identity, no IdP offboarding and no device-posture check. In return, any HTTP client that can set one header can use it, the application controls the exact failure response, and machine calls do not depend on an SSO redirect.

For one owner and a closed automation surface, that can beat Access. For 20 administrators who need individual revocation and audit attribution, it does not.

OptionBest fitIdentityMachine-client requirementVerdict
Cloudflare AccessSeveral people, existing IdP, per-person revocationHuman email/groups; machine principal for service tokensCustom headers, mTLS, or Access-aware clientDefault for a shared admin UI
mTLSServices or managed devices with certificate lifecycleCertificate subject or mapped deviceClient-certificate supportStrong machine auth; heavier issuance and rotation
One bearer key checked in the WorkerOne owner, small fixed set of scriptsShared principal onlyOne configurable headerBest simple answer when per-person identity adds no value
IP allow-listFixed corporate egress as one factorNetwork location, not a personStable source IPUse as a condition, not the only credential
Tunnel plus AccessPrivate origin that must not be directly reachableAccess identity plus private origin pathBrowser login or service credentialStrongest Access topology for a self-hosted origin
Bypass plus handler signatureOne third-party webhookProvider key/signatureProvider-specific signed requestCorrect for that path only

Seats and arithmetic

Cloudflare's current plan page says the Free plan is for teams under 50 users and costs $0. Pay-as-you-go is $7 per user per month. The page describes Remote Browser Isolation as an add-on but does not publish its current add-on price. A dated 2023 operator comparison recorded $10 per user per month; treat that as historical evidence, not today's quote.

AdministratorsAccess FreePay-as-you-go at $7/seat/monthShared bearer key
1$0$7$0 product fee
12$0$84$0 product fee
49$0$343$0 product fee
60Plan choice required; outside “under 50” positioning$420$0 product fee, but 60 people sharing one key is indefensible
250Not the free-plan fit$1,750Wrong architecture

The calculation is seats × $7. It excludes support, identity-provider cost, implementation time, and any separately quoted Remote Browser Isolation add-on. A bearer key has no Cloudflare seat line item, but secret rotation and the absence of individual attribution are costs; they are just paid in operator time and incident risk.

What administering Access feels like

The policy surface is capable. The console has drawn specific criticism. systemvoltage, otherwise positive about Cloudflare's main dashboard, described the Access/Zero Trust area as a separate application that took ten seconds and redirected repeatedly, with worse UI and thin documentation.

That report is dated 2022. Do not turn it into a claim about today's page speed. Keep the durable operational lesson: the person on call needs the API paths and curl proofs in the runbook, because a graphical console can be slow, moved, or unavailable.

The positive operator case is equally concrete. tbhb uses Tunnel plus Access to expose only the local-development endpoints that must be public, such as webhooks, while keeping the rest of the site behind Access. That is the product boundary working: narrow public ingress, authenticated private remainder, and no directly published origin.

Error, cause, repair

SymptomCauseRepair
302 to *.cloudflareaccess.com/cdn-cgi/access/login/...No accepted credential and the application is using interactive login behaviorBrowser: complete the IdP flow. Machine: send a service token and add Service Auth, or enable the documented 401 response for Service Auth
403 before the originInvalid service headers, no matching policy, wrong application path, or denied selectorConfirm both header names, list the application and policies, then test the exact hostname/path
Valid service token reaches origin but sub is emptyService-token application JWT is non-humanMap verified common_name to a least-privilege synthetic machine identity
JWT signature verification failsWrong issuer, wrong audience, stale hard-coded key, altered token, or wrong algorithmFetch the team JWKS, select by kid, require RS256, exact issuer and exact application audience
Browser works; native client gets 302/403Client cannot add Access service-token headersAdd a general custom-header option, use the single-header mode, mTLS, or do not put that endpoint behind Access
Health works; every scoped API call failsHealth is public/Bypass while authenticated principal is not mapped into app membershipFix identity mapping at the auth seam; do not widen Bypass
Origin accepts a claimed Access header without cryptographic verificationApplication trusts attacker-supplied textVerify JWT signature, issuer, audience and time before reading identity
Temporary app appears deleted but token remainsOnly the Access application was deletedDelete the service token separately; require fresh successful lists for both collections

Three live receipts, with bounded claims

Access path. A temporary application protected a unique path. Plain HTTP returned 302 before Service Auth and 403 after the Service Auth policy existed. Correct service-token headers passed Access and reached the origin, which returned its own 404. The redacted JWT used RS256, had type: "app", an audience and common_name, an empty sub, and no email.

Signing keys. A fresh unauthenticated GET of the account's team JWKS returned HTTP 200, 4,914 JSON bytes and two RSA/RS256 signing keys. The published command uses a placeholder, not the real team name:

sh
curl -sS "https://<team-name>.cloudflareaccess.com/cdn-cgi/access/certs" \
  | jq '{keys: [.keys[] | {kid, alg, kty, use}]}'

This application's key-only admin gate. A fresh machine request with no credential:

sh
curl -sS -D - https://miscsubjects.com/admin \
  -H 'accept: application/json'

returned HTTP 401, application/json, and a 47-byte body with only error and login. A scan found no stack, trace, binding, database, exception or key marker. This proves the unauthenticated failure is bounded; it does not prove the shared-key posture has person-level identity.

Cleanup. Successful authenticated Access application and service-token lists proved the temporary ids and names absent. No 401, 403, or failed parse was treated as an empty list.

Access earns its complexity when identity changes the authorization decision. If every accepted caller is the same owner and every client already holds the same operational secret, one checked key is smaller and often more reliable. Once individual revocation, IdP groups or device posture matter, use Access, verify the JWT at the origin, and give machines a principal of their own.

This chapter is part of the Cloudflare account inventory. For the private-origin and Durable Object boundary, see Workers and Durable Objects.

302 → 403 → 404
unauthenticated, Service Auth policy, then valid service token reaching origin
2
RSA/RS256 signing keys returned by the fresh team JWKS read
0
temporary Access applications and service tokens left after successful list checks
401 / 47 B
bounded unauthenticated machine response from this application's admin gate
$0
advertised Access Free plan for teams under 50
$7
current pay-as-you-go price per user per month
Evidence · 23 sources · swipe →chain 1239356d0617 · verify chain · provenance
1 / 23

Key evidence

21 claims · tier-ranked · API
system
Access authenticates a request against an edge policy; the origin application still owns authorization.
sources: s1, s2, s3
mechanism
A browser session presents CF_Authorization while an origin should verify Cf-Access-Jwt-Assertion cryptographically.
sources: s1, s2, s3
fact
Self-hosted Access applications deny by default until an Allow or Service Auth policy matches.
sources: s6
fact
Bypass disables Access enforcement and removes matching traffic from Access logs.
sources: s4
fact
Service Auth is the policy action for service tokens and other non-IdP authentication such as mTLS.
sources: s4, s5
mechanism
The Access REST API creates applications and service tokens as separate resources, and a new service-token secret is shown only once.
sources: s7, s8
mechanism
A normal service-token request needs both CF-Access-Client-Id and CF-Access-Client-Secret plus a matching Service Auth policy.
sources: s5
people
Some native clients cannot use Access because they cannot add its custom authentication headers.
sources: p1, p2
system
A service-token application JWT may carry an empty sub and no email, so the application must map a verified machine principal explicitly.
sources: p3, r2
implementation
The example origin verifier uses jose to enforce issuer, audience and RS256 against a remote JWKS.
sources: s12, s3
11 more ranked claims
runtime0.10
The measured team JWKS exposed two RSA/RS256 signing keys, matching the current-and-previous rotation model.
Supports the article's operator decision or verification path.
sources: r3, s3
people0.10
An open health path does not prove authenticated application membership; an authenticated principal can still fail scoped authorization.
Supports the article's operator decision or verification path.
sources: p4
system0.10
Deleting an Access application, its policy, and a reusable service token are distinct lifecycle operations.
Supports the article's operator decision or verification path.
sources: r4, s7, s8
runtime0.10
Successful fresh lists must prove both the temporary application and service token absent by exact id and name.
Supports the article's operator decision or verification path.
sources: r4
system0.10
For one owner and closed automation, one application-checked bearer key can be smaller than Access; it gives up person-level identity and IdP offboarding.
Supports the article's operator decision or verification path.
sources: r3
fact0.10
Cloudflare currently advertises Free for teams under 50 and pay-as-you-go at seven dollars per user per month.
Supports the article's operator decision or verification path.
sources: s9
fact0.10
Remote Browser Isolation is currently an add-on, while the ten-dollar figure is a dated 2023 operator observation rather than today's vendor quote.
Supports the article's operator decision or verification path.
sources: p6, s10
people0.10
A dated operator report criticized the Access console's speed and redirects; it is historical usability evidence, not a current benchmark.
Supports the article's operator decision or verification path.
sources: p5
system0.10
Tunnel plus Access can keep an origin private while a narrow webhook path remains deliberately reachable.
Supports the article's operator decision or verification path.
sources: p7, s11
runtime0.10
The temporary probe moved from 302 to 403 when Service Auth was attached, and a valid service token then cleared Access and reached the origin's 404.
Supports the article's operator decision or verification path.
sources: r1
runtime0.10
The application's unauthenticated machine path returns bounded JSON: HTTP 401, 47 bytes, and only error and login keys.
Supports the article's operator decision or verification path.
sources: r3
Ask this article · 8 suggested prompts

Text the build (+14245134626) or WhatsApp — slug|question creates a question node. Paste evidence with ingest slug|q:NODE_ID|your paste.

What does the ledger say about this (system tier): "Access authenticates a request against an edge policy; the origin application still owns authorization."?
ask cloudflare-os-access claim c1 · paste includes §SELF
What does the ledger say about this (mechanism tier): "A browser session presents CF_Authorization while an origin should verify Cf-Access-Jwt-Assertion cryptographically."?
ask cloudflare-os-access claim c2 · paste includes §SELF
What does the ledger say about this (fact tier): "Self-hosted Access applications deny by default until an Allow or Service Auth policy matches."?
ask cloudflare-os-access claim c3 · paste includes §SELF
What does the ledger say about this (fact tier): "Bypass disables Access enforcement and removes matching traffic from Access logs."?
ask cloudflare-os-access claim c4 · paste includes §SELF
What does the ledger say about this (fact tier): "Service Auth is the policy action for service tokens and other non-IdP authentication such as mTLS."?
ask cloudflare-os-access claim c5 · paste includes §SELF
What does the ledger say about this (mechanism tier): "The Access REST API creates applications and service tokens as separate resources, and a new service-token secret is shown only once."?
ask cloudflare-os-access claim c6 · paste includes §SELF
What can you answer from your catalogue about Cloudflare Access authenticates the edge, not your application — and what remains open or unverified?
ask cloudflare-os-access gaps · paste includes §SELF
What are the strongest objections or counter-evidence on record against Cloudflare Access authenticates the edge, not your application?
ask cloudflare-os-access objections · paste includes §SELF
Black-and-white Cloudflare OS Access title card stating that policy is not an application key
Cloudflare OS · Access · the identity gate