Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/worker-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"./kilo-pass-bonus-projection": "./src/kilo-pass-bonus-projection.ts",
"./git-url": "./src/git-url.ts",
"./callback-token": "./src/callback-token.ts",
"./cf-access": "./src/cf-access.ts",
"./cloud-agent-next-client": "./src/cloud-agent-next-client.ts",
"./cloud-agent-session-access": "./src/cloud-agent-session-access.ts",
"./kilo-model-id": "./src/kilo-model-id.ts",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import { createMiddleware } from 'hono/factory';
import { seconds } from 'itty-time';
import { z } from 'zod';
import type { GastownEnv } from '../gastown.worker';

/**
* Validate a raw Request against Cloudflare Access.
Expand All @@ -23,27 +20,6 @@ export async function validateCfAccessRequest(
await validateAccessJWT({ request, accessTeamDomain, accessAud });
}

export function withCloudflareAccess({
team,
audience,
}: {
team: AccessTeam;
audience: AccessAudience;
}) {
return createMiddleware<GastownEnv>(async (c, next) => {
try {
await validateCfAccessRequest(c.req.raw, { team, audience });
} catch (e) {
console.warn(`validateAccessJWT failed ${e instanceof Error ? e.message : 'unknown'}`, {
error: e,
});
return c.json({ success: false, error: 'Unauthorized' }, 401);
}

await next();
});
}

// Access validation code adapted from:
// https://github.com/cloudflare/pages-plugins/blob/main/packages/cloudflare-access/functions/_middleware.ts?at=90281ad52b77506bb7723a8db813e19723725509#L88

Expand Down Expand Up @@ -81,6 +57,18 @@ function asciiToUint8Array(s: string): ArrayBuffer {
return new Uint8Array(chars).buffer;
}

// The certs endpoint supports Cloudflare's edge-cache `cf` fetch options, which
// are a Workers-only RequestInit extension absent from the standard webworker
// lib, so the fetch init is typed locally rather than adding workers-types here.
type CloudflareFetchInit = RequestInit & {
cf?: {
cacheEverything?: boolean;
cacheTtl?: number;
};
};

const CF_ACCESS_CERTS_CACHE_TTL_SECONDS = 86_400; // 1 day

async function validateAccessJWT({
request,
accessTeamDomain,
Expand All @@ -101,12 +89,13 @@ async function validateAccessJWT({
const textDecoder = new TextDecoder('utf-8');
const { kid } = AccessHeader.parse(JSON.parse(textDecoder.decode(base64URLDecode(header))));
const certsURL = new URL('/cdn-cgi/access/certs', accessTeamDomain);
const certsResponse = await fetch(certsURL.toString(), {
const certsFetchInit: CloudflareFetchInit = {
cf: {
cacheEverything: true,
cacheTtl: seconds('1 day'),
cacheTtl: CF_ACCESS_CERTS_CACHE_TTL_SECONDS,
},
});
};
const certsResponse = await fetch(certsURL.toString(), certsFetchInit);
const { keys } = AccessCertsResponse.parse(await certsResponse.json());
const jwk = keys.find(key => key.kid === kid);
if (!jwk) {
Expand Down
2 changes: 1 addition & 1 deletion services/gastown/src/gastown.worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
type AuthVariables,
} from './middleware/auth.middleware';
import { kiloAuthMiddleware } from './middleware/kilo-auth.middleware';
import { validateCfAccessRequest } from './middleware/cf-access.middleware';
import { validateCfAccessRequest } from '@kilocode/worker-utils/cf-access';

import { trpcServer } from '@hono/trpc-server';
import { wrappedGastownRouter } from './trpc/router';
Expand Down
232 changes: 0 additions & 232 deletions services/wasteland/src/middleware/cf-access.middleware.ts

This file was deleted.

2 changes: 1 addition & 1 deletion services/wasteland/src/wasteland.worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { useWorkersLogger } from 'workers-tagged-logger';
import type { MiddlewareHandler } from 'hono';
import type { AuthVariables } from './middleware/auth.middleware';
import { kiloAuthMiddleware } from './middleware/kilo-auth.middleware';
import { validateCfAccessRequest } from './middleware/cf-access.middleware';
import { validateCfAccessRequest } from '@kilocode/worker-utils/cf-access';
import { timingMiddleware } from './middleware/analytics.middleware';
import { wrappedWastelandRouter } from './trpc/router';
import { getWastelandRegistryStub } from './dos/WastelandRegistry.do';
Expand Down