This project adds a business-specific authorization signal to Cloudflare Access: whether a user has completed required training.
It is implemented as a Cloudflare Worker used by an Access External Evaluation rule, with D1 storing training state and an Access-protected administration interface for managing the data.

Authorization flow
User
↓
Identity provider
↓
Cloudflare Access
↓
External Evaluation Worker
↓
D1 training status
↓
completed → allow
other → deny
The Worker does not replace Access. It answers a narrow external policy question that Access consumes as part of the final decision.
Training state
The D1 database stores a small user record containing fields such as:
username
first_name
primary_email
training_status
created_at
updated_at
Training status is constrained to known values:
not started
started
completed
The evaluation path permits access only for completed.
Fail-closed behaviour
If the user is absent from the training database, the request is invalid or the evaluator encounters an error, the result is a denial.
That makes the control predictable for sensitive applications: only a known compliant state is accepted.
Identity synchronization
The project can synchronize identities from Okta into D1.
The live access request does not need to query Okta. Identity synchronization and access evaluation remain separate operational paths.
Administration
Administrative functions are protected by Cloudflare Access and include workflows for:
- database initialization;
- key initialization;
- user synchronization;
- training-status updates;
- dashboard access.
This keeps the external evaluation endpoint separate from privileged management operations.
Signing keys
The implementation validates Access-supplied identity claims and signs its response for Access to verify.
The Worker’s public verification material can be stored in KV while the private signing key remains in Worker secrets.
Browser security
The administration UI applies a Content Security Policy and other security headers in addition to being protected by Access.
The project therefore treats identity-aware access and application-layer browser security as separate controls.
Deployment outline
The repository documents creation of the required D1 database, KV binding, Worker secrets and Access application settings.
The broad flow is:
npm install
npx wrangler d1 create <database-name>
npx wrangler kv namespace create <namespace-name>
npx wrangler deploy
Secrets and Access audience values are then configured through Wrangler/Cloudflare rather than committed to source control.
Related article
See Enforcing Security Training with Cloudflare Access External Evaluation for the architecture and authorization design in more detail.