cloudflare-zero-trust-access — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited cloudflare-zero-trust-access (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Integrate Cloudflare Zero Trust Access authentication with Cloudflare Workers applications using proven patterns and templates.
This skill provides complete integration patterns for Cloudflare Access, enabling application-level authentication for Workers without managing your own auth infrastructure.
What is Cloudflare Access? Cloudflare Access is Zero Trust authentication that sits in front of your application, validating users before they reach your Worker. After authentication, Access issues JWT tokens that your Worker validates.
Key Benefits:
Trigger this skill when tasks involve:
Keywords to Trigger: cloudflare access, zero trust, access authentication, JWT validation, service tokens, cloudflare auth, hono access, workers authentication, protect worker routes, admin authentication
Use @hono/cloudflare-access for one-line Access integration.
When to Use:
Template: templates/hono-basic-setup.ts
Setup:
import { Hono } from 'hono'
import { cloudflareAccess } from '@hono/cloudflare-access'
const app = new Hono<{ Bindings: Env }>()
// Public routes
app.get('/', (c) => c.text('Public page'))
// Protected routes
app.use(
'/admin/*',
cloudflareAccess({
domain: (c) => c.env.ACCESS_TEAM_DOMAIN,
})
)
app.get('/admin/dashboard', (c) => {
const { email } = c.get('accessPayload')
return c.text(`Welcome, ${email}!`)
})Configuration (wrangler.jsonc):
{
"vars": {
"ACCESS_TEAM_DOMAIN": "your-team.cloudflareaccess.com",
"ACCESS_AUD": "your-app-aud-tag"
}
}Benefits:
Use Web Crypto API for custom validation logic.
When to Use:
Template: templates/jwt-validation-manual.ts
Key Functions:
// Validate JWT signature and claims
async function validateAccessJWT(
token: string,
env: Env
): Promise<AccessJWTPayload> {
// 1. Decode header to get kid
// 2. Fetch public keys (with caching)
// 3. Verify signature using Web Crypto API
// 4. Validate aud, exp, iss
// 5. Return payload
}Complexity: ~100 lines Dependencies: None (uses Web Crypto API)
Use service tokens for machine-to-machine auth.
When to Use:
Template: templates/service-token-auth.ts
Client Side (sending request):
const response = await fetch('https://api.example.com/data', {
headers: {
'CF-Access-Client-Id': env.SERVICE_TOKEN_ID,
'CF-Access-Client-Secret': env.SERVICE_TOKEN_SECRET,
},
})Server Side (Worker):
// Same validation as user JWTs - middleware handles both
app.use('/api/*', cloudflareAccess({
domain: (c) => c.env.ACCESS_TEAM_DOMAIN
}))
app.get('/api/data', (c) => {
const payload = c.get('accessPayload')
// Detect service token vs user
const isService = !payload.email && payload.common_name
return c.json({
authenticated_by: isService ? 'service-token' : 'user',
identifier: payload.email || payload.common_name,
})
})Setup Guide: references/service-tokens-guide.md
Handle cross-origin requests with Access authentication.
When to Use:
Template: templates/cors-access.ts
CRITICAL: CORS middleware MUST come before Access middleware!
import { cors } from 'hono/cors'
import { cloudflareAccess } from '@hono/cloudflare-access'
// ✅ CORRECT ORDER
app.use('*', cors({
origin: 'https://app.example.com',
credentials: true, // Allow cookies
}))
app.use('/api/*', cloudflareAccess({
domain: (c) => c.env.ACCESS_TEAM_DOMAIN
}))
// ❌ WRONG ORDER - WILL FAIL!
// Access blocks OPTIONS preflight requestsWhy: OPTIONS preflight requests don't include auth headers. If Access runs first, it blocks them with 401.
Frontend:
fetch('https://api.example.com/api/data', {
credentials: 'include', // ← Critical!
method: 'POST',
})Different Access configurations per tenant/organization.
When to Use:
Template: templates/multi-tenant.ts
Architecture:
Example:
// Subdomain-based: tenant1.example.com, tenant2.example.com
app.use('/app/*', async (c, next) => {
const tenantId = getTenantFromSubdomain(c.req.url)
const tenant = await getTenantConfig(tenantId, c.env.DB)
// Apply tenant-specific Access
return cloudflareAccess({
domain: tenant.access_team_domain
})(c, next)
})This skill prevents 8 documented errors. Full details: references/common-errors.md
Problem: OPTIONS requests return 401, breaking CORS
Solution: CORS middleware BEFORE Access middleware
// ✅ Correct
app.use('*', cors())
app.use('/api/*', cloudflareAccess({ domain: '...' }))Problem: Request not going through Access, no JWT header
Solution: Access Worker through Access URL, not direct *.workers.dev
✅ https://team.cloudflareaccess.com/...
❌ https://worker.workers.devProblem: Hardcoded or wrong team name causes "Invalid issuer"
Solution: Use environment variables
// ✅ Correct
cloudflareAccess({ domain: (c) => c.env.ACCESS_TEAM_DOMAIN })
// ❌ Wrong
cloudflareAccess({ domain: 'my-team.cloudflareaccess.com' })Problem: First request fails, subsequent work
Solution: Use @hono/cloudflare-access (handles caching automatically)
Problem: Wrong header names, token doesn't work
Solution: Use exact header names:
// ✅ Correct
'CF-Access-Client-Id': '...'
'CF-Access-Client-Secret': '...'
// ❌ Wrong
'Authorization': 'Bearer ...'Problem: Users suddenly get 401 after 1 hour
Solution: Handle gracefully, redirect to login
if (error.message.includes('expired')) {
return c.json({ error: 'Session expired', code: 'TOKEN_EXPIRED' }, 401)
}Problem: Overlapping Access applications cause conflicts
Solution: Use most specific paths, avoid overlaps
Problem: Code works in dev, fails in prod
Solution: Environment-specific configs
{
"env": {
"dev": {
"vars": { "ACCESS_TEAM_DOMAIN": "dev-team.cloudflareaccess.com" }
},
"production": {
"vars": { "ACCESS_TEAM_DOMAIN": "prod-team.cloudflareaccess.com" }
}
}
}Total Time Saved: ~2.5 hours per implementation
Comprehensive guides in references/:
Located in scripts/:
./test-access-jwt.sh <jwt-token>./create-service-token.sh [token-name]npm install hono @hono/cloudflare-accessDashboard:
wrangler.jsonc:
{
"vars": {
"ACCESS_TEAM_DOMAIN": "your-team.cloudflareaccess.com",
"ACCESS_AUD": "your-aud-tag"
}
}Use templates/hono-basic-setup.ts as starting point:
import { Hono } from 'hono'
import { cloudflareAccess } from '@hono/cloudflare-access'
const app = new Hono<{ Bindings: Env }>()
app.use('/admin/*', cloudflareAccess({
domain: (c) => c.env.ACCESS_TEAM_DOMAIN
}))
app.get('/admin/dashboard', (c) => {
const { email } = c.get('accessPayload')
return c.json({ email })
})
export default appnpx wrangler deployAccess: https://your-worker.example.com/admin/dashboard
Expected: Redirect to Access login, then back to dashboard after auth.
Requirements: Protect admin routes with email authentication
Template: hono-basic-setup.ts
Policy: Emails ending in @company.com
Requirements: Protect API, allow public pages
Template: hono-basic-setup.ts + separate routes
Policy: Service tokens + employee emails
Requirements: React app calling authenticated API
Template: cors-access.ts
Critical: CORS middleware before Access
Requirements: GitHub Actions calling Worker API
Template: service-token-auth.ts
Setup: Service token in GitHub Secrets
Requirements: Different Access per organization
Template: multi-tenant.ts
Architecture: Tenant config in D1, dynamic middleware
| Package | Version | Purpose |
|---|---|---|
| @hono/cloudflare-access | 0.3.1 | Hono middleware (recommended) |
| hono | 4.10.3 | Web framework |
| @cloudflare/workers-types | 4.20251014.0 | TypeScript types |
Verified: 2025-10-28
No Node.js Dependencies: All packages use Web Standards APIs, fully compatible with Workers runtime.
Without Skill: ~5,550 tokens
With Skill: ~2,300 tokens
Savings: 3,250 tokens (~58%)
Library: @hono/cloudflare-access actively maintained Downloads: ~3,000/week GitHub: Part of Hono middleware collection (10k+ stars)
Production Use: Verified working in commercial projects.
When user requests Access integration:
templates/ACCESS_TEAM_DOMAIN and ACCESS_AUD in wrangler.jsoncreferences/access-policy-setup.md)references/common-errors.mdThis skill is for Cloudflare Workers with Cloudflare Access. Do not use for:
@cloudflare/pages-plugin-cloudflare-access instead)For those, use appropriate skills or libraries.
Cloudflare Documentation:
Packages:
Dashboard:
Skill Version: 1.0.0 Last Updated: 2025-10-28 Errors Prevented: 8 Token Savings: 58% Time Savings: 2.5 hours Production Tested: ✅
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.