What Are Gatekeepers in Cloudflare OS? A Technical Guide to Capability-Based Adapters

Gatekeepers in Cloudflare OS are capability-based adapters that expose external services to AI-driven gadgets through a three-layer architecture of Durable Objects, enforcing fine-grained permissions and audit trails via an ApprovalQueue.

Cloudflare OS—internally codenamed the "Gadgets Workshop"—uses Gatekeepers to safely bridge AI agents with third-party APIs like Google Workspace, GitHub, and Home Assistant. As implemented in the cloudflare/cloudflare-os repository, these components act as secure, auditable intermediaries that translate natural language requests into authenticated API calls while maintaining strict user consent boundaries.

Core Architecture: The Three Layers of Cloudflare OS Gatekeepers

The Gatekeeper system organizes access control into three distinct Durable Object layers, each defined in packages/workshop-shared/src/gatekeeper.ts.

GatekeeperVendor: The Entry Point

The GatekeeperVendor serves as the durable-object entry point for service integration. It handles OAuth initialization, lists available resource types, and can auto-provision accounts. When the Workshop UI needs to display available connectors, it calls GatekeeperVendor.describe() to retrieve metadata including the vendor name, logo, and supported authentication flows.

GatekeeperUser: Account Management

Once a user completes OAuth, the system instantiates a GatekeeperUser durable object representing that specific connected account. This layer surfaces account information, enumerates grantable resources via getGatekeeperClassFor(url), and manages the credential lifecycle. Each connected Google or GitHub account maintains its own GatekeeperUser instance that persists the access tokens and refresh logic.

Gatekeeper: Resource-Specific Access

The Resource Gatekeeper implements the Gatekeeper<Session> interface as a Durable Object facet bound to a specific resource URL—such as https://docs.google.com/document/d/XYZ. This layer exposes the concrete API methods (e.g., listDocuments, sendEmail) through a session RPC that gadgets invoke. Crucially, it routes all read operations through ObservationAuthorizer.authorizeObservation() and queues write operations in the ApprovalQueue for explicit user approval.

Key Types and Interfaces Defined in gatekeeper.ts

The shared API contract in packages/workshop-shared/src/gatekeeper.ts defines the metadata structures that enable type-safe integration:

  • VendorDescription: UI metadata including the vendor name, logo URL, tagline, and a boolean flag indicating if the vendor supports sign-in capabilities.
  • AccountDescription: Data structure representing a connected account in the UI, potentially declaring a singleton agent or management interface.
  • SupportedResource: Declares resource types the vendor can bind, including URL patterns like https://docs.google.com/* for Google Docs.
  • ResourceDescription: Metadata returned by resource-specific Gatekeepers containing the URL, title, suggested binding name, and TypeScript type definitions.
  • AgentCatalog: A bounded discovery index that exposes reachable objects to the AI agent without requiring full session data retrieval.

Runtime Lifecycle: How Gatekeepers Work in Practice

The execution flow follows a strict six-phase pattern enforced by the Overseer:

  1. Vendor discovery: The Workshop UI calls GatekeeperVendor.describe() to enumerate available connectors.
  2. Account connection: The UI invokes GatekeeperVendor.connectAccount(callback, options), returning an OAuth URL. The callback's complete(user, expiresAt) method persists the GatekeeperUser after authorization.
  3. Resource selection: The system may spawn a configurator iframe via startResourceConfigurator to capture the specific resource URL.
  4. Class resolution: The Overseer calls GatekeeperUser.getGatekeeperClassFor(url) to retrieve the Durable Object class implementing Gatekeeper<Session> for that resource type.
  5. Session start: The gadget invokes Gatekeeper.startSession(approvalQueue) to obtain a session stub providing the concrete API.
  6. Observations and actions: Read operations pass through ObservationAuthorizer.authorizeObservation(), while writes are submitted via approvalQueue.submitAction() and only executed after user approval triggers applyAction().
// 1. List available vendors (UI side)
const vendors = await gatekeeperVendor.describe();

// 2. Connect a Google account (user clicks “Connect”)
const {url} = await gatekeeperVendor.connectAccount(callback, {scopes: "full"});
window.open(url, "_blank");

// 3. After OAuth completes, callback.complete(user) stores the account.
//    The Workshop now has a GatekeeperUser fetcher.

// 4. Resolve a specific resource (e.g. a Google Doc)
const {class: GatekeeperClass, resource} = await gatekeeperUser.getGatekeeperClassFor(
    "https://docs.google.com/document/d/XYZ");

// 5. Instantiate the resource Gatekeeper within the Overseer
const gatekeeper = ctx.facets.add(GatekeeperClass, { /* props with credentials */ });

// 6. Start a session for the gadget
const session = await gatekeeper.startSession(approvalQueue);

// 7. Read data (observation)
await observationAuthorizer.authorizeObservation({
  description: "Read document title",
  resourceId: resource.id,
});
const title = await session.getTitle();

// 8. Request a write (action)
const actionId = await session.createComment({text: "Hello"});
await approvalQueue.submitAction(actionId, {
  // ActionDescription describing the write
});

Implementation Examples in the Cloudflare OS Repository

The cloudflare/cloudflare-os monorepo contains several reference implementations demonstrating the Gatekeeper pattern:

Summary

  • Gatekeepers provide capability-based security for AI gadget integration with external APIs.
  • The architecture separates concerns into three Durable Object layers: Vendor (service definition), User (account management), and Resource (concrete API access).
  • All interactions are audited and permissioned through the ObservationAuthorizer for reads and the ApprovalQueue for writes.
  • The core RPC contracts reside in packages/workshop-shared/src/gatekeeper.ts.
  • Concrete implementations follow a six-phase lifecycle from vendor discovery to action execution.

Frequently Asked Questions

What is the primary purpose of Gatekeepers in Cloudflare OS?

Gatekeepers serve as secure intermediaries that expose external services to AI-driven gadgets while enforcing user consent and maintaining audit trails. They prevent unauthorized access by requiring explicit approval for all write operations through the ApprovalQueue.

How does the ApprovalQueue enforce security in Gatekeeper sessions?

When a gadget requests a write operation, the Resource Gatekeeper generates an action identifier and submits it to the ApprovalQueue rather than executing immediately. The Overseer only invokes applyAction() on the Gatekeeper after the user explicitly approves the operation in the Workshop UI, creating a mandatory authorization checkpoint for all state-changing operations.

What distinguishes GatekeeperVendor from GatekeeperUser?

GatekeeperVendor is a singleton Durable Object that handles service-level concerns like OAuth flow initialization and resource type enumeration, while GatekeeperUser represents a specific authenticated instance of that service for one user, managing account-specific tokens and resolving resource URLs to concrete Gatekeeper classes.

Where are the Gatekeeper interfaces defined in the source code?

The central RPC contracts defining GatekeeperVendor, GatekeeperUser, and Gatekeeper<Session> reside in packages/workshop-shared/src/gatekeeper.ts, which also exports the shared type definitions including VendorDescription, AccountDescription, and SupportedResource.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →