# What Is the gatekeeper-kit Package? OAuth Primitives for Cloudflare OS

> Discover the gatekeeper-kit package, Cloudflare OS's OAuth primitives library. It simplifies authentication, credential management, and policy observation, reducing boilerplate code across gatekeeper implementations.

- Repository: [Cloudflare/cloudflare-os](https://github.com/cloudflare/cloudflare-os)
- Tags: deep-dive
- Published: 2026-09-04

---

**The `gatekeeper-kit` package provides the canonical library of reusable OAuth primitives that abstracts common authentication workflows, credential lifecycles, and observation policies, eliminating hundreds of lines of duplicated boilerplate across Cloudflare's gatekeeper implementations.**

The `gatekeeper-kit` package within the `cloudflare/cloudflare-os` repository supplies the core building blocks required by every OAuth-style gatekeeper implemented on Cloudflare Workers. By extracting shared logic into a structured two-layer architecture, this library enables developers to build secure, provider-specific gatekeepers—such as those for GitHub, Supabase, or Google—without rewriting common nonce handling, credential storage, or handshake sequencing.

## Architecture of the gatekeeper-kit Package

The package is organized into two distinct architectural layers that separate standalone utilities from high-level composition logic.

### Layer 1 - Leaf Modules (Standalone Primitives)

**Layer 1** consists of tiny, stand-alone primitives that can be imported and used independently without depending on higher-level assembly logic. These leaf modules handle specific concerns such as nonce generation, credential storage, HTTP-error helpers, and simulation utilities.

Key leaf modules include `connect-nonce`, `connect-handshake`, `credentials`, `observers`, and `simulation`. Each module is designed to be imported individually, allowing gatekeepers to use only the specific utilities they require.

### Layer 2 - The Assembly (Factory and Base Classes)

**Layer 2** provides the assembly framework that composes Layer 1 primitives into a cohesive gatekeeper structure. At the heart of this layer is the `gatekeeperKit<Env, Grant, Exports, Public>()` factory function, defined in [`src/endpoint.ts`](https://github.com/cloudflare/cloudflare-os/blob/main/src/endpoint.ts), which generates typed specifications and abstract base classes.

The assembly exposes four critical base classes that concrete gatekeepers must extend:

- **KitVendorBase** – handles provider-specific vendor logic
- **KitUserAccountBase** – manages account-level state and credential coordination
- **KitUserBase** – handles user-level authentication flow
- **KitGatekeeperBase** – orchestrates the overall gatekeeper lifecycle

## Why the gatekeeper-kit Package Exists

Prior to the kit's introduction, every gatekeeper implementation (GitHub, Supabase, Google, etc.) contained approximately 400–500 lines of near-identical plumbing code. This duplication included nonce state machines, Durable Object handling for credential storage, expiry latching mechanisms, and observer bookkeeping logic.

By extracting this plumbing into `@gadgets/gatekeeper-kit`, new gatekeepers can be authored with significantly fewer lines of code, reducing bug surface area and ensuring that security-critical sequencing changes—such as nonce handling updates or refresh fences—apply uniformly across all gatekeepers.

## Core Components and Source Files

### Nonce Management ([`connect-nonce.ts`](https://github.com/cloudflare/cloudflare-os/blob/main/connect-nonce.ts))

The [`src/connect-nonce.ts`](https://github.com/cloudflare/cloudflare-os/blob/main/src/connect-nonce.ts) module provides cryptographic utilities for OAuth nonce generation and validation. It exports constants such as `NONCE_BYTES` (defining nonce entropy) and `CONNECT_TIMEOUT_MS` (defining validity windows), along with functions for generating and verifying nonces.

```typescript
import {
  generateNonce,
  isLiveNonce,
  NONCE_BYTES,
  CONNECT_TIMEOUT_MS,
} from '@gadgets/gatekeeper-kit/connect-nonce';

// Create a fresh nonce for the initiation step
const nonce = generateNonce();          // → 64‑hex‑character string
const stored = { value: nonce, expiresAt: Date.now() + CONNECT_TIMEOUT_MS };

// Later, when the client returns the nonce:
if (isLiveNonce(stored, returnedNonce, Date.now())) {
  // ✅ Nonce is valid – continue OAuth flow
}

```

*Source:* [connect-nonce.ts](https://github.com/cloudflare/cloudflare-os/blob/main/packages/gatekeeper-kit/src/connect-nonce.ts)

### Handshake Orchestration ([`connect-handshake.ts`](https://github.com/cloudflare/cloudflare-os/blob/main/connect-handshake.ts))

The [`src/connect-handshake.ts`](https://github.com/cloudflare/cloudflare-os/blob/main/src/connect-handshake.ts) module implements the two-stage handshake sequence required for OAuth flows. It manages the transition from initiation to OAuth completion using `putInitiation`, `advanceToOAuth`, and `claimOAuth`.

```typescript
import {
  putInitiation,
  advanceToOAuth,
  claimOAuth,
  StoredNonce,
} from '@gadgets/gatekeeper-kit/connect-handshake';

// Step 1 – store an initiation nonce
putInitiation(kv, initiationNonce, Date.now());

// Step 2 – client completes OAuth, we advance to the OAuth stage
const oauthNonce = advanceToOAuth(kv, initiationNonce, Date.now(), { pkceVerifier: '…' });

// Step 3 – finally claim the OAuth nonce once the provider redirects back
const stored: StoredNonce = claimOAuth(kv, oauthNonce, Date.now());
if (stored) {
  // stored.extra contains any extra fields passed in advanceToOAuth
}

```

*Source:* [connect-handshake.ts](https://github.com/cloudflare/cloudflare-os/blob/main/packages/gatekeeper-kit/src/connect-handshake.ts)

### Credential Coordination ([`credentials.ts`](https://github.com/cloudflare/cloudflare-os/blob/main/credentials.ts))

The [`src/credentials.ts`](https://github.com/cloudflare/cloudflare-os/blob/main/src/credentials.ts) module provides the `CredentialCoordinator` class, which handles secure credential storage, automatic expiration checking, and **refresh coalescing**—a critical mechanism that prevents thundering-herd problems when multiple requests simultaneously attempt to refresh an expired token.

```typescript
import {
  CredentialCoordinator,
  CredentialsExpiredError,
} from '@gadgets/gatekeeper-kit/credentials';

// Initialise the coordinator inside a UserAccount Durable Object
const coordinator = new CredentialCoordinator(kv, {
  expiresAt: (c) => c.expiresAt,
  refreshSkewMs: 60_000,
});

// Connect (store new credentials)
coordinator.connect({ accessToken: 'abc', expiresAt: Date.now() + 3_600_000 });

// Refresh the token, automatically coalescing concurrent refreshes
await coordinator.fresh(async (current) => {
  const refreshed = await fetchNewToken(current.refreshToken);
  return { ...refreshed, expiresAt: Date.now() + refreshed.expiresIn * 1000 };
});

```

*Source:* [credentials.ts](https://github.com/cloudflare/cloudflare-os/blob/main/packages/gatekeeper-kit/src/credentials.ts)

### Observer Tracking ([`observers.ts`](https://github.com/cloudflare/cloudflare-os/blob/main/observers.ts))

The [`src/observers.ts`](https://github.com/cloudflare/cloudflare-os/blob/main/src/observers.ts) module implements privacy-policy enforcement through the `ObserverTracker` class. This utility manages which external entities can observe credential sets, implementing strategies such as "private-only" access where only the account owner may view credentials.

```typescript
import { ObserverTracker } from '@gadgets/gatekeeper-kit/observers';

// Create a tracker for a “private‑only” strategy
const tracker = new ObserverTracker({
  kv,
  maxTrackedSets: 500,
  maxObservers: 10,
  vendorId: 'my-gatekeeper',
  // Simple verifier that only allows the account owner
  verifyBaseline: async (verifier) => { /* throw if not owner */ },
  hasSetAccess: async (verifier, setIds) =>
    setIds.map(() => false), // no external set access
});

await tracker.addObserver('observer-id', userVerifier);

```

*Source:* [observers.ts](https://github.com/cloudflare/cloudflare-os/blob/main/packages/gatekeeper-kit/src/observers.ts)

### The Assembly Factory ([`endpoint.ts`](https://github.com/cloudflare/cloudflare-os/blob/main/endpoint.ts))

The [`src/endpoint.ts`](https://github.com/cloudflare/cloudflare-os/blob/main/src/endpoint.ts) file exports the `gatekeeperKit` factory that assembles all primitives into a deployable gatekeeper structure. This factory uses a fluent API pattern to define RPC specifications, resource paths, and authentication strategies.

```typescript
import { gatekeeperKit } from '@gadgets/gatekeeper-kit/endpoint';
import { oauth2 } from '@gadgets/gatekeeper-kit/auth-retry';

// Assemble a gatekeeper that uses the OAuth2 strategy
export const MyGatekeeper = gatekeeperKit<MyEnv, MyGrant, MyExports, MyPublic>()
  .define({
    // RPC spec – exported functions
    getSession: async (env) => { /* … */ },
  })
  .resource({
    // Resource URL grammar (e.g., “/connect”, “/callback”)
    path: '/my-gatekeeper',
  })
  .authStrategy(oauth2({ clientId: env.CLIENT_ID, clientSecret: env.CLIENT_SECRET }))
  .build();

```

*Source:* [endpoint.ts](https://github.com/cloudflare/cloudflare-os/blob/main/packages/gatekeeper-kit/src/endpoint.ts)

## Package Configuration and Deployment Model

The `gatekeeper-kit` package is configured as a **private, non-deployable library** within the Cloudflare OS monorepo. As defined in [`packages/gatekeeper-kit/package.json`](https://github.com/cloudflare/cloudflare-os/blob/main/packages/gatekeeper-kit/package.json), the package lacks a `wrangler.jsonc` configuration file, indicating it is intended solely as a shared dependency for other gatekeeper worker packages rather than as a standalone deployed service.

This design ensures that the kit remains an internal implementation detail, allowing the Cloudflare OS team to evolve the OAuth primitives without maintaining backward compatibility for external consumers.

## Summary

- The `gatekeeper-kit` package eliminates ~400–500 lines of duplicated code per gatekeeper by extracting common OAuth plumbing into reusable modules.
- It implements a two-layer architecture: **Layer 1** provides standalone leaf modules (nonce, credentials, observers), while **Layer 2** provides the assembly factory and base classes (`KitVendorBase`, `KitUserAccountBase`, `KitUserBase`, `KitGatekeeperBase`).
- Key utilities include `generateNonce` and `isLiveNonce` for cryptographic validation, `CredentialCoordinator` for refresh coalescing, and `ObserverTracker` for privacy enforcement.
- The package is strictly internal to the `cloudflare/cloudflare-os` repository and cannot be deployed as a standalone Worker.

## Frequently Asked Questions

### What is the primary purpose of the gatekeeper-kit package?

The primary purpose is to serve as the **canonical library of reusable gatekeeper primitives** that abstracts common OAuth workflows, credential lifecycles, and observation-policy logic. It allows each concrete gatekeeper to focus exclusively on provider-specific pieces (such as token exchange or URL grammar) while reusing shared sequencing logic.

### How does gatekeeper-kit reduce code duplication?

Previously, each gatekeeper implementation contained nearly identical boilerplate for nonce machines, Durable Object handling, credential expiry logic, and observer bookkeeping. By extracting these into the kit's Layer 1 and Layer 2 modules, new gatekeepers require significantly less code, and security updates apply uniformly across all implementations.

### Can gatekeeper-kit be deployed as a standalone worker?

No. The package is explicitly **private and non-deployable**, as indicated by the absence of `wrangler.jsonc` in [`packages/gatekeeper-kit/package.json`](https://github.com/cloudflare/cloudflare-os/blob/main/packages/gatekeeper-kit/package.json). It functions purely as a shared library for other gatekeeper packages within the Cloudflare OS ecosystem.

### What are the base classes provided by the assembly layer?

The assembly layer in [`src/endpoint.ts`](https://github.com/cloudflare/cloudflare-os/blob/main/src/endpoint.ts) provides four abstract base classes through the `gatekeeperKit()` factory: `KitVendorBase` (provider logic), `KitUserAccountBase` (account state management), `KitUserBase` (user authentication flow), and `KitGatekeeperBase` (lifecycle orchestration). Concrete gatekeeper implementations subclass these bases to inject provider-specific behavior.