Gateway passes context as the second argument to GatewayMiddleware.handle(request, context, next). Context describes the original request when Gateway selects a Forward policy. Modifying the Request does not update context.
Field names use camelCase. Optional fields are omitted when unavailable, and empty metadata lists are omitted. Availability depends on the connection method, destination, and authenticated session. Check optional values before using them.
Install @cloudflare/zt-types ↗︎ version 2026.10.1 or later in your Worker project:
npm i -D @cloudflare/zt-typesyarn add -D @cloudflare/zt-typespnpm add -D @cloudflare/zt-typesbun add -d @cloudflare/zt-typesUse import type for Gateway types, as shown in the example and each Worker template. These imports are removed when TypeScript compiles and add no runtime dependency. JavaScript examples omit the type imports and annotations and do not need this package. The package exports the following Gateway types:
| Type | Description |
|---|---|
GatewayMiddlewareContext |
Request metadata, identity getter, and device posture getter. |
GatewayMiddlewareNext |
Continuation that sends a Request through Gateway and returns a Promise<Response>. |
GatewayIdentity |
User identity returned by identity(). |
GatewayIdentityGroup |
A group in the user's identity. |
GatewayDevicePosture |
Device posture returned by devicePosture(). |
GatewayDevicePostureChecks |
Passed posture check identifiers. |
| Field | Type | Description |
|---|---|---|
srcIp |
string |
Source IP address as seen by Gateway. Use this field instead of a client-supplied IP header. |
srcPort |
number |
Source port. |
dstIp |
string, optional |
Destination IP address, when available. |
dstPort |
number, optional |
Destination port, when available. |
networkProtocol |
string |
Network transport protocol, such as tcp. |
sni |
string, optional |
Server Name Indication from the TLS connection. |
onrampType |
string, optional |
Connection method used to reach Gateway. |
vnetId |
string, optional |
Virtual network identifier. |
proxyEndpoint |
string, optional |
Proxy endpoint associated with the connection. |
internalSrcIp |
string, optional |
Internal source IP address, when available. |
accountId |
string |
Cloudflare account identifier. |
policyId |
string |
UUID of the Forward policy that selected this Worker. |
host |
string |
Original request host. |
uri |
string |
Normalized original request URL. |
embeddedProtocols |
readonly string[], optional |
Detected protocols embedded in HTTP traffic. |
domainCategories |
readonly number[], optional |
Destination domain category IDs. |
context.uri includes the scheme and authority. Normalization removes default ports and fragments, sorts query parameters, and normalizes encoding. It can differ from request.url. Use request.url when operating on the request itself and context.uri when comparing normalized metadata.
Use standard Request APIs to access the method, headers, cookies, and body. Context does not include custom function results, DLP match details, or raw internal device records.
Call await context.identity() only when your script needs identity associated with the Gateway session. Its return type is Promise<GatewayIdentity | null>.
The awaited call behaves as follows:
- Returns an identity object when the user is identified.
- Returns
nullwhen there is no identified user. - Throws an error if Gateway cannot retrieve identity.
| Field | Type | Description |
|---|---|---|
email |
string, optional |
User email address. |
name |
string, optional |
User display name. |
groups |
readonly GatewayIdentityGroup[], optional |
Group memberships. Each group can have optional id, email, and name fields. |
samlAttributes |
readonly string[], optional |
SAML attributes associated with the identity. |
oidcClaims |
readonly string[], optional |
OIDC claims associated with the identity. This is a list, rather than a decoded token object. |
Use Gateway-provided identity for user-aware logic. Client-supplied identity headers are not an authoritative substitute.
Check for a missing identity (!identity) to explicitly allow or deny anonymous traffic.
Call await context.devicePosture() to retrieve passed posture check identifiers:
{
"checks": {
"passed": ["<POSTURE_CHECK_UUID>"]
}
}checks.passed is a read-only list of posture check UUIDs. An empty array means no checks passed. When no device is registered, the getter resolves to { checks: { passed: [] } }. A Worker that requires a specific passed check must deny this request.
If Gateway cannot retrieve device posture, awaiting devicePosture() throws an error. Handle this separately from a session with no passed checks.
The getter does not return raw test results or a list of failed checks.
Gateway still invokes the Worker if it cannot retrieve identity or device posture. If either awaited call throws and your Worker does not catch the error, Gateway returns HTTP 500.
Use try/catch to choose how your Worker handles these errors. The example returns HTTP 503 for retrieval errors and HTTP 403 when identity or a required posture check is missing.
If your application deliberately allows traffic when Gateway cannot retrieve identity or posture, return next(request) from the catch block. This continues the request without requiring the missing result.
Only use this approach before calling next(). Call next() at most once per invocation.
This script requires an identity email and a specific passed posture check before continuing. Anonymous traffic and devices without the required check receive a synthetic 403 response.
Identity or posture retrieval errors receive 503. Replace <POSTURE_CHECK_UUID> with a check in your account.
import { WorkerEntrypoint } from "cloudflare:workers";
export class GatewayMiddleware extends WorkerEntrypoint {
async handle(request, context, next) {
try {
const identity = await context.identity();
if (!identity?.email) {
return new Response(null, { status: 403 });
}
const passed = (await context.devicePosture())?.checks.passed ?? [];
if (!passed.includes("<POSTURE_CHECK_UUID>")) {
return new Response(null, { status: 403 });
}
} catch {
return new Response(null, { status: 503 });
}
return next(request);
}
}import { WorkerEntrypoint } from "cloudflare:workers";
import type {
GatewayMiddlewareContext,
GatewayMiddlewareNext,
} from "@cloudflare/zt-types";
export class GatewayMiddleware extends WorkerEntrypoint {
async handle(
request: Request,
context: GatewayMiddlewareContext,
next: GatewayMiddlewareNext,
): Promise<Response> {
try {
const identity = await context.identity();
if (!identity?.email) {
return new Response(null, { status: 403 });
}
const passed = (await context.devicePosture())?.checks.passed ?? [];
if (!passed.includes("<POSTURE_CHECK_UUID>")) {
return new Response(null, { status: 403 });
}
} catch {
return new Response(null, { status: 503 });
}
return next(request);
}
}When the requirement can be expressed using built-in identity selectors or device posture selectors, configure it in your Gateway filtering policy. Use Worker logic for requirements that need custom code.
Gateway combines repeated Cookie headers with semicolons and other repeated headers with commas. Set-Cookie values retain separate entries. Use response.headers.getSetCookie() to read the individual response cookies. When modifying headers, copy them with new Headers(response.headers) to preserve their representation.