LobsterHoney Docs
Deployment

Edge Middleware (npm)

Deploy trap coverage at your own edge with the @lobsterhoney/edge npm package.

Edge middleware is the modern advanced deployment path for JavaScript sites. You install the @lobsterhoney/edge package into your app, and it serves trap content directly from your own edge -- making trap paths indistinguishable from real routes on your domain. Instead of pointing to a beacon domain or wiring up a reverse proxy, protection runs as a middleware inside the platform you already deploy to.

Edge middleware requires a Pro plan or higher and a JavaScript hosting platform (Vercel, Netlify, Cloudflare Pages, or Next.js). Sites on other stacks use beacon mode or proxy mode instead. Upgrade from your dashboard to unlock edge deployment.

How It Works

The middleware fetches a signed manifest from your control-plane origin and serves the server-authored trap content it contains. Every trap body is constructed server-side and delivered pre-built -- the package ships no content generators of its own. When an agent hits a trap path, the middleware reports the request back so it can be scored and correlated in your dashboard.

  • Zero runtime dependencies. It uses only the Web Crypto API, so it runs on Vercel Edge, Cloudflare (Workers runtime), Netlify Edge (Deno), and Node 18+ without a bundler shim.
  • Pinned trust, fail closed. You pin a trust bundle issued to you at onboarding. The manifest is verified with an ECDSA-P256 signature against that pinned bundle before any content is served. If verification fails, nothing is served.
  • Minimal reporting. Reported events carry request metadata only (method, host, client IP, and the ordered list of request header names) -- never header values and never the request body.

Setting Up Edge Middleware

Choose the edge method on the Deploy page

Open the dashboard, go to the Deploy page, and pick your JavaScript platform. Then choose Edge middleware (npm) as your deployment method.

Copy the generated install and snippet

The Deploy page emits the exact npm install command and a middleware snippet with your site already scoped in. This is the authoritative copy -- the examples below are conceptual skeletons.

Set the three environment variables

The snippet reads three environment variables. Set them in your platform's project settings or secrets store. The Deploy page shows you the exact values (your key, your origin, and your trust bundle):

  • LOBSTERHONEY_KEY -- your control-plane API key
  • LOBSTERHONEY_URL -- your control-plane origin
  • LOBSTERHONEY_TRUST_BUNDLE -- the signed trust bundle (stored as JSON)

Deploy to your platform

Commit the middleware and deploy as you normally would. On first request, the middleware fetches and verifies your manifest, then begins serving trap content at your edge.

Run edge verification

From the Deploy page, run the edge verification check to confirm the manifest is loading, signature verification passes, and trap paths are being served. See Verifying Deployment.

Platform Snippets

Each platform imports a small factory from its own entrypoint. These are short skeletons that read the three environment variables above -- the Deploy page generates the copy-ready version scoped to your site.

// middleware.ts
import { createMiddleware } from '@lobsterhoney/edge/vercel';

export default createMiddleware({
  apiKey: process.env.LOBSTERHONEY_KEY!,
  orgSlug: 'your-org',
  manifestUrl: process.env.LOBSTERHONEY_URL!, // origin only
  trustBundle: JSON.parse(process.env.LOBSTERHONEY_TRUST_BUNDLE!),
});

Next.js middleware runs on the Vercel Edge runtime, so it uses the same entrypoint. Place this in your project root as middleware.ts.

// middleware.ts
import { createMiddleware } from '@lobsterhoney/edge/vercel';

export default createMiddleware({
  apiKey: process.env.LOBSTERHONEY_KEY!,
  orgSlug: 'your-org',
  manifestUrl: process.env.LOBSTERHONEY_URL!, // origin only
  trustBundle: JSON.parse(process.env.LOBSTERHONEY_TRUST_BUNDLE!),
});

Netlify Edge Functions run on Deno, so environment variables are read via Deno.env.

import { createNetlifyHandler } from '@lobsterhoney/edge/netlify';

export default createNetlifyHandler({
  apiKey: Deno.env.get('LOBSTERHONEY_KEY')!,
  orgSlug: 'your-org',
  manifestUrl: Deno.env.get('LOBSTERHONEY_URL')!, // origin only
  trustBundle: JSON.parse(Deno.env.get('LOBSTERHONEY_TRUST_BUNDLE')!),
});

Cloudflare Pages runs on the Workers runtime. The handler returns a Response for a matched trap path and null otherwise, so fall through to your origin when it returns null. Pass ctx through so hit reporting runs in the background.

import { createCloudflareHandler } from '@lobsterhoney/edge/cloudflare';

export default {
  async fetch(request, env, ctx) {
    const handler = createCloudflareHandler({
      apiKey: env.LOBSTERHONEY_KEY,
      orgSlug: 'your-org',
      manifestUrl: env.LOBSTERHONEY_URL, // origin only
      trustBundle: JSON.parse(env.LOBSTERHONEY_TRUST_BUNDLE),
    });
    const res = await handler(request, env, ctx);
    return res ?? fetch(request); // null => no match, serve the real origin
  },
};

Environment Variables

The snippet reads these three variables. The Deploy page shows the exact value for each -- store them as secrets, never commit them to your repository.

VariableMaps toWhat it is
LOBSTERHONEY_KEYapiKeyYour control-plane API key
LOBSTERHONEY_URLmanifestUrlYour control-plane origin, e.g. https://<your-lobsterhoney-origin> (origin only -- the client derives the rest)
LOBSTERHONEY_TRUST_BUNDLEtrustBundleThe signed trust bundle, stored as JSON and parsed at startup

manifestUrl is an origin, not a full path -- the client derives its endpoints from it. Keeping the origin in LOBSTERHONEY_URL lets you switch hosts without editing code. Your exact origin is shown on the Deploy page.

Alternative: inline in code. Instead of the LOBSTERHONEY_TRUST_BUNDLE env var, you can commit the trust bundle the dashboard issues you as a JSON file and import it, then pass it as the trustBundle field. The env-var form is what the dashboard generates by default and is recommended so your bundle stays out of source control.

import trustBundle from './lobsterhoney-trust-bundle.json';
// ...pass `trustBundle` to the config above instead of JSON.parse(...)

Trust Bundle & Key

Your API key and trust bundle are issued in the dashboard on the Deploy page. The trust bundle is the sole root of trust the middleware pins -- there is no remote trust fetch, so the client fails closed if a bundle is not supplied. Manifests are ECDSA-P256 verified against the pinned bundle before any content is served: the signing key is selected by key id, checked against the bundle's validity window, and the manifest's own expiry is enforced.

Treat both the key and the trust bundle as secrets. Copy their exact values from the Deploy page -- this documentation never contains real values.

What Gets Protected

Edge middleware serves your static file and page traps -- the portable subset that can be precomputed and delivered in the signed manifest. For a typical organization, that's around 9 of 16 active traps. Your interactive traps -- the ones that need live request handling, such as API and login flows -- continue to be served by the control plane, so your full trap surface stays active across both.

This split is by design: the edge handles the traps that benefit most from living on your own domain, while the control plane keeps serving the ones that require server-side logic. You don't lose coverage by deploying at the edge -- you add the on-domain layer on top.

Verifying

After deploying, run the edge verification check from the Deploy page. It confirms the manifest loads, its signature verifies, and trap paths respond at your edge. If verification fails, the report tells you which check did not pass. See Verifying Deployment for details and common fixes.

See Also

On this page