Flue Zero to Expert, Part 6: Production Routing and Deployment

Protect Flue routes with Hono, build the Node target, manage runtime secrets, and choose safe sandbox boundaries.

Series map

Part 1: Your First Flue Agent · Part 2: Typed Workflows · Part 3: Safe Tools · Part 4: Autonomous Agents · Part 5: Persistence and Durable Execution · Part 6: Production Routing and Deployment · Part 7: Operate Like an Expert

Part 6: Production Routing and Deployment

Own the HTTP boundary

Flue can generate a default HTTP application. Production services often need more control.

Add src/app.ts when you need authentication, health checks, prefixes, or custom routes. It is a normal Hono application.

Mount flue() inside that application. Middleware registered before the mount protects the matching Flue routes.

Mounting Flue does not expose every module automatically. Agents and workflows must export their HTTP route handlers. Workflow run resources also require a runs middleware export.

A complete Hono application

Install Hono because the authored application imports it directly:

npm install hono

Create src/app.ts:

import { flue } from '@flue/runtime/routing';
import { Hono, type MiddlewareHandler } from 'hono';

const apiToken = process.env.API_TOKEN;

if (!apiToken) {
  throw new Error('API_TOKEN is required');
}

const requireApiToken: MiddlewareHandler = async (c, next) => {
  const authorization = c.req.header('authorization');

  if (authorization !== `Bearer ${apiToken}`) {
    return c.json({ error: 'Unauthorized' }, 401);
  }

  await next();
};

const app = new Hono();

app.get('/health', (c) => c.json({ ok: true }));

app.use('/agents/*', requireApiToken);
app.use('/workflows/*', requireApiToken);
app.use('/runs/*', requireApiToken);

app.route('/', flue());

export default app;

The public health route returns no configuration. Agent, workflow, and run routes require the bearer token before flue() handles them.

This service-wide boundary fits one trusted credential. Multi-user systems need resource-level authorization.

For multi-user systems, also check access to the selected agent instance. Application middleware on /runs/* can enforce shared authentication, but it does not expose a run. The workflow's runs export exposes and authorizes its run resources. Without that export, existing and unknown runs return the same generic 404.

Do not treat an unexported route as authorization. Exposure controls availability. Trusted middleware controls access.

Environment

Keep secrets outside source control:

cat > .env <<'EOF'
API_TOKEN="replace-with-a-long-random-token"
OPENAI_API_KEY="your-provider-key"
EOF

printf '\n.env\n' >> .gitignore

flue build loads the project-root .env while evaluating the build. It does not package .env credentials into the generated server.

The built server reads only the environment provided when it starts. Supply production secrets through your host, container platform, or secret manager.

Do not set FLUE_MODE, FLUE_CLI_*, or FLUE_INTERNAL_CLI_IPC. Flue reserves those variables. In particular, production should not run with FLUE_MODE=local.

Build and run

Build the Node target:

npx flue build --target node

The default output is dist/. Dependencies remain external, so production still needs the project’s node_modules.

Run the generated server with the local environment:

set -a; source .env; set +a
node dist/server.mjs

It listens on port 3000 by default. Set PORT when the platform requires another port:

PORT=8080 node dist/server.mjs

Check the public health route:

curl http://localhost:3000/health

Call a protected workflow:

curl http://localhost:3000/workflows/review \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"text":"Deploy every change directly to production."}'

Keep liveness checks fast. Add dependencies only to a separate readiness check.

Sandbox boundaries

The default virtual sandbox starts with an empty filesystem. Prefer it for agents that only need prompts and small generated files. It is not a network-isolation boundary.

A local sandbox can access host files and commands. It has no second isolation layer. Run it only in a trusted container, CI runner, or virtual machine. Pass only the environment variables its shell needs.

Use a remote sandbox when work must not run on the application host. Commands, network access, isolation, persistence, and lifecycle depend on the selected adapter. Routing authentication does not isolate agent execution. The HTTP boundary and sandbox boundary solve different problems.

Sources

  • https://flueframework.com/docs/guide/routing/
  • https://flueframework.com/docs/ecosystem/deploy/node/
  • https://flueframework.com/docs/guide/sandboxes/

Next, continue to Part 7: Operate Like an Expert to add logs, evals, and schedules.