Skip to content

Cloudflare Workers Deployment

Cloudflare Workers is the recommended deployment platform for GLACIS sidecars. With 300+ edge locations, sub-millisecond cold starts, and native integration with GLACIS services, it provides the best performance for global deployments.

Why Cloudflare Workers?

Global Edge

Deploy to 300+ locations worldwide. Requests are processed at the edge location closest to your users.

Zero Cold Start

Sub-millisecond cold starts mean no latency penalty, even for infrequent requests.

Native Integration

GLACIS witness and receipt services run on Cloudflare, minimizing network hops.

Cost Effective

Pay per request with generous free tier. No idle compute costs.

Prerequisites

Before starting, ensure you have:

Quick Start

  1. Create a new Worker project

    Terminal window
    npm create cloudflare@latest glacis-sidecar -- --template https://github.com/glacis-io/sidecar-cf-template
    cd glacis-sidecar
  2. Install dependencies

    Terminal window
    npm install
  3. Configure secrets

    Terminal window
    # GLACIS credentials
    npx wrangler secret put GLACIS_API_KEY
    # Enter your API key when prompted
    npx wrangler secret put GLACIS_ORG_ID
    # Enter your organization ID
    # AI provider credentials
    npx wrangler secret put OPENAI_API_KEY
    # Enter your OpenAI API key
  4. Update wrangler.toml

    name = "glacis-sidecar"
    main = "src/index.ts"
    compatibility_date = "2024-01-01"
    [vars]
    GLACIS_RECEIPT_URL = "https://receipts.glacis.io"
    GLACIS_WITNESS_URL = "https://witness.glacis.io"
    SAMPLING_RATE = "100"
  5. Deploy

    Terminal window
    npx wrangler deploy

Configuration

wrangler.toml

name = "glacis-sidecar"
main = "src/index.ts"
compatibility_date = "2024-01-01"
# Account configuration
account_id = "your-account-id"
# Environment variables
[vars]
GLACIS_RECEIPT_URL = "https://receipts.glacis.io"
GLACIS_WITNESS_URL = "https://witness.glacis.io"
SAMPLING_RATE = "100"
POLICIES = "toxicity,pii"
# Routes (optional - for custom domains)
routes = [
{ pattern = "ai.yourdomain.com/*", zone_name = "yourdomain.com" }
]
# Durable Objects (for state management)
[[durable_objects.bindings]]
name = "TOKEN_CACHE"
class_name = "TokenCache"
[[migrations]]
tag = "v1"
new_classes = ["TokenCache"]

Worker Code

src/index.ts
import { GlacisSidecar, type SidecarConfig } from '@glacis/sidecar-cf';
export interface Env {
GLACIS_API_KEY: string;
GLACIS_ORG_ID: string;
OPENAI_API_KEY: string;
GLACIS_RECEIPT_URL: string;
GLACIS_WITNESS_URL: string;
SAMPLING_RATE: string;
POLICIES: string;
TOKEN_CACHE: DurableObjectNamespace;
}
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
const config: SidecarConfig = {
orgId: env.GLACIS_ORG_ID,
apiKey: env.GLACIS_API_KEY,
provider: {
type: 'openai',
apiKey: env.OPENAI_API_KEY,
},
sampling: {
rate: parseInt(env.SAMPLING_RATE),
policies: env.POLICIES.split(',') as PolicyType[],
},
services: {
receipt: env.GLACIS_RECEIPT_URL,
witness: env.GLACIS_WITNESS_URL,
},
};
const sidecar = new GlacisSidecar(config, {
tokenCache: env.TOKEN_CACHE,
waitUntil: ctx.waitUntil.bind(ctx),
});
return sidecar.handleRequest(request);
},
};
// Durable Object for token caching
export { TokenCache } from '@glacis/sidecar-cf';

Advanced Configuration

Custom Routes

Route specific paths to different AI providers:

const sidecar = new GlacisSidecar(config, {
routes: [
{
path: '/v1/chat/completions',
provider: 'openai',
model: 'gpt-4',
},
{
path: '/v1/messages',
provider: 'anthropic',
model: 'claude-3-opus',
},
],
});

Adaptive Sampling

Configure rules-based sampling:

const config: SidecarConfig = {
// ... other config
sampling: {
rate: 100, // Default: 1 in 100
rules: [
{
// Sample all GPT-4 requests
condition: { field: 'model', operator: 'eq', value: 'gpt-4' },
rate: 1,
},
{
// Sample more for long prompts
condition: { field: 'content_length', operator: 'gt', value: 1000 },
rate: 10,
},
],
},
};

Custom Policy Checks

Add organization-specific policy evaluations:

const config: SidecarConfig = {
// ... other config
policies: {
builtin: ['toxicity', 'pii', 'bias'],
custom: [
{
name: 'compliance_keywords',
evaluate: async (request, response) => {
const keywords = ['confidential', 'restricted'];
const hasKeyword = keywords.some(k =>
response.content.toLowerCase().includes(k)
);
return {
score: hasKeyword ? 1.0 : 0.0,
flagged: hasKeyword,
metadata: { keywords: hasKeyword ? keywords : [] },
};
},
},
],
},
};

Monitoring

Worker Analytics

View real-time metrics in the Cloudflare dashboard:

  • Request volume
  • Latency percentiles
  • Error rates
  • CPU time

GLACIS Dashboard Integration

Attestations flow to your GLACIS dashboard:

  1. Navigate to Attestations in the GLACIS dashboard
  2. Filter by source: cloudflare-worker
  3. View attestation details and Merkle proofs

Logging

Enable structured logging for debugging:

const config: SidecarConfig = {
// ... other config
logging: {
level: 'info', // 'debug' | 'info' | 'warn' | 'error'
format: 'json',
includeRequestId: true,
},
};

View logs in Cloudflare:

Terminal window
npx wrangler tail

Performance Optimization

Token Caching

Use Durable Objects to cache bearer tokens:

// Token is refreshed 5 minutes before expiration
// Cached across all Worker instances in the same region
const tokenCache = env.TOKEN_CACHE.get(
env.TOKEN_CACHE.idFromName('default')
);

Request Batching

For high-volume deployments, batch attestations:

const config: SidecarConfig = {
// ... other config
batching: {
enabled: true,
maxSize: 100,
maxWaitMs: 1000,
},
};

Connection Reuse

The sidecar automatically reuses connections to:

  • AI providers
  • GLACIS services
  • Reduces cold-start latency

Security

Secret Management

Never expose secrets in code or config:

Terminal window
# Add secrets via Wrangler CLI
npx wrangler secret put GLACIS_API_KEY
npx wrangler secret put OPENAI_API_KEY
# Or via dashboard:
# Workers & Pages → Your Worker → Settings → Variables

IP Allowlisting

Restrict Worker access by IP:

export default {
async fetch(request: Request, env: Env): Promise<Response> {
const clientIP = request.headers.get('CF-Connecting-IP');
if (!env.ALLOWED_IPS.includes(clientIP)) {
return new Response('Forbidden', { status: 403 });
}
// ... continue with sidecar
},
};

Rate Limiting

Use Cloudflare’s built-in rate limiting:

wrangler.toml
[[rules]]
type = "RateLimit"
expression = "true"
action = "block"
characteristics = ["cf.colo.id", "ip.src"]
period = 60
requests_per_period = 1000

Troubleshooting

Common Issues

“Invalid API key” error

Terminal window
# Verify secret is set
npx wrangler secret list
# Re-set if needed
npx wrangler secret put GLACIS_API_KEY

High latency

  1. Check Worker analytics for CPU time
  2. Verify token caching is working
  3. Consider enabling request batching

Missing attestations

  1. Check Worker logs: npx wrangler tail
  2. Verify GLACIS_RECEIPT_URL is correct
  3. Check network connectivity to receipts.glacis.io

Debug Mode

Enable verbose logging:

Terminal window
# Deploy with debug logging
LOGGING_LEVEL=debug npx wrangler deploy

Migration Guide

From Direct AI Calls

// Before: Direct OpenAI call
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${OPENAI_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'gpt-4',
messages: [{ role: 'user', content: 'Hello' }],
}),
});
// After: GLACIS sidecar (deployed at ai.yourdomain.com)
const response = await fetch('https://ai.yourdomain.com/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
// No API key needed - sidecar handles authentication
},
body: JSON.stringify({
model: 'gpt-4',
messages: [{ role: 'user', content: 'Hello' }],
}),
});

Next Steps