Edge Deployment

Deploy Blazen as a WASM component on ZLayer or edge platforms

Overview

blazen-wasm is the deployment-ready WASM component designed for ZLayer and other edge platforms. It packages your Blazen workflows and agents into a single WASM binary that runs at the edge with minimal cold-start overhead.

ZImagefile

A ZImagefile defines the build and deployment spec for your WASM component, similar to a Dockerfile:

FROM blazen-wasm:latest

COPY ./src /app/src
COPY ./package.json /app/package.json

RUN npm install --production
RUN blazen-wasm build --entry /app/src/index.ts --output /app/dist/handler.wasm

EXPOSE 8080
ENTRYPOINT ["blazen-wasm", "serve", "--port", "8080"]

Project structure

A typical edge deployment looks like this:

my-blazen-edge/
  src/
    index.ts        # Entry point -- exports the request handler
    tools.ts        # Tool handler implementations
  ZImagefile
  package.json

Entry point

Your entry point exports a handler function that receives HTTP requests:

import init, { OpenRouterProvider, ChatMessage, runAgent } from '@blazen/sdk';

await init();

export async function handler(request: Request): Promise<Response> {
  const { prompt } = await request.json();
  // Construct the provider directly, then adapt it for runAgent via toModel().
  // With no apiKey, it reads OPENROUTER_API_KEY from the runtime env -- set it
  // via your platform's secret store before invoking the handler.
  const model = new OpenRouterProvider({ apiKey: process.env.OPENROUTER_API_KEY }).toModel();

  const result = await runAgent(
    model,
    [ChatMessage.user(prompt)],
    tools,
    toolHandler,
    { maxIterations: 5 }
  );

  return new Response(JSON.stringify({ content: result.response.content }), {
    headers: { 'Content-Type': 'application/json' },
  });
}

API key strategies

Edge functions need access to provider API keys without exposing them to clients.

Store keys as platform secrets. ZLayer injects them as environment variables at runtime:

zlayer secret set OPENAI_API_KEY sk-...
function getApiKey(): string {
  return process.env.OPENAI_API_KEY!;
}

Encrypted config

Bundle an encrypted config file and decrypt at startup using a platform-provided key:

import { decrypt } from './crypto';

const config = decrypt(await Deno.readFile('./config.enc'), process.env.DECRYPT_KEY!);
const apiKey = JSON.parse(config).openaiKey;

Proxy

Route all LLM requests through a central proxy that injects keys server-side. The edge function never sees the raw upstream key. Configure your proxy to accept requests on an OpenAI-compatible /v1 endpoint, then supply the short-lived proxy token via OPENAI_API_KEY in the runtime env:

# Set OPENAI_API_KEY to the per-deployment proxy token.
zlayer secret set OPENAI_API_KEY edge-token
import { OpenAiProvider } from '@blazen/sdk';

// With no apiKey, the provider reads OPENAI_API_KEY from the runtime
// environment. The proxy at proxy.yourcompany.com intercepts requests,
// swaps 'edge-token' for the real API key, and forwards upstream.
const model = new OpenAiProvider({ apiKey: process.env.OPENAI_API_KEY });

Runtime injection

Standalone providers accept apiKey and baseUrl on their constructor (e.g. new OpenAiProvider({ apiKey, baseUrl })), so you can set a per-request key directly. In an edge function, though, the safer pattern is still to point the SDK at a proxy via baseUrl and let the proxy decide which upstream key to use based on per-request metadata such as a header — the raw upstream key never touches client-reachable code:

const callerToken = request.headers.get('X-Caller-Token');
// Forward callerToken to your proxy via the request URL or a custom header;
// the proxy uses it to look up the correct upstream API key.

Deploying to ZLayer

# Build the WASM component
zlayer build

# Deploy
zlayer deploy --name my-blazen-agent --region us-east-1

# Check status
zlayer status my-blazen-agent

ZLayer handles TLS termination, auto-scaling, and geographic routing.

Scaling

WASM components on ZLayer scale to zero by default and spin up in under 5ms. Key considerations:

  • Cold start — the WASM binary is pre-compiled to native code at deploy time. No JIT warmup.
  • Memory — each instance gets a dedicated linear memory. Default limit is 256 MB, configurable in the ZImagefile.
  • Concurrency — each instance handles one request at a time. ZLayer spawns additional instances automatically.
  • Regions — deploy to multiple regions with --region us-east-1,eu-west-1,ap-northeast-1.

Other edge platforms

The @blazen/sdk WASM module works on any platform that supports WebAssembly:

  • Cloudflare Workers — import the SDK and call init() in your worker entry.
  • Vercel Edge Functions — use the SDK in an edge-runtime function.
  • Deno Deploy — import from npm and call init().
  • Fastly Compute — compile the Rust crate directly to wasm32-wasi.

Next steps