Runtime Behavior
Gateway owns public ingress behavior for Layeron backend apps. This page describes how it routes requests, normalizes errors, emits logs, and keeps security-sensitive data out of Gateway configuration.
Routing
Section titled “Routing”Gateway uses Hono as the route engine. Routes declared with app.get,
app.post, app.put, app.patch, app.delete, app.head, and
app.routeOptions are registered into the Gateway route table.
When backend({ endpoint }) includes a host, Gateway only serves requests for
that host. A request to the same path on another host returns 404. When the
endpoint includes a base path, Gateway registers public routes under that base
path.
During layer dev, keep endpoint as the deployed URL. The local server uses
the host and port selected by the CLI and applies the endpoint base path
automatically. The endpoint host remains deploy ingress metadata. For
endpoint: "https://api.example.com/v1" and app.get("/api/health"), call
http://localhost:8787/v1/api/health when layer dev uses port 8787.
Parameterized paths use Hono path matching:
app.get("/api/posts/:id", async (request) => { return { ok: true, }})When a path exists and the requested method is missing, Gateway returns 405
with an Allow header. When a path is missing, Gateway returns 404.
Explicit OPTIONS routes are respected. If a path exists and you do not define
an OPTIONS route, Gateway can return an automatic 204 response for method
discovery and CORS preflight.
Auth Policy
Section titled “Auth Policy”Routes use their own auth value first. When a route omits auth, Gateway
uses gateway.defaultAuth. The default value is public.
Supported policies:
| Policy | Runtime behavior |
|---|---|
public | The request reaches the handler without Auth Product verification. |
user | Gateway requires a valid Auth session and a user subject. |
service | Gateway requires a valid Auth session and a service subject, role, or scope. |
admin | Gateway requires a valid Auth session and an admin role or scope. |
Authenticated routes require one Auth module in the app. Gateway calls Auth Product RPC to verify the access token and resolve the subject.
CORS preflight handling is path-aware. Gateway returns 404 for preflight
requests to unknown paths. Gateway returns 403 when the origin, requested
method, or requested headers fail the configured policy.
Successful preflight responses include Access-Control-Allow-Origin,
Access-Control-Allow-Methods, configured request headers, exposed response
headers, credentials, max age, and the request id response header.
Error Responses
Section titled “Error Responses”Gateway normalizes runtime errors into JSON responses:
{ "error": { "code": "route_not_found", "message": "Route not found: GET /missing.", "requestId": "req_..." }}Known client-facing errors expose their messages:
| Code | Status | Meaning |
|---|---|---|
route_not_found | 404 | No route matched the request path. |
method_not_allowed | 405 | The path exists, but the requested method is not declared. |
response_invalid | 500 | A handler returned a value that Layeron cannot serialize. |
Unexpected handler failures return 500 with Internal server error. by
default. Set runtime debug mode in local tooling when you need implementation
details during development.
Gateway Logs
Section titled “Gateway Logs”The log payload includes product identity, request id, trace id, method, path,
host, origin, status, duration, CORS decisions, and normalized error codes.
Header values are recorded only when includeHeaders lists them, and sensitive
headers are redacted by default.
Gateway emits structured log records through the runtime observability sink. The current Cloudflare target writes those records to Worker logs.
Gateway log events:
| Event | Default control |
|---|---|
request.finish | Enabled by gateway.logs.request or error severity. |
request.error | Enabled by gateway.logs.errors; enabled by default for errors. |
route.not_found | Enabled by gateway.logs.errors; enabled by default for errors. |
method.not_allowed | Enabled by gateway.logs.errors; enabled by default for errors. |
cors.preflight | Enabled by gateway.logs.cors or warning and error severity. |
route.matched | Enabled by gateway.logs.routeMatch. |
Current Boundaries
Section titled “Current Boundaries”Gateway records inputSchemaId, outputSchemaId, and route bodyMode in
contracts and topology metadata. Runtime request body validation, response
validation, and raw body preservation require the schema registry and body mode
contracts to be present on route declarations before runtime enforcement can be
enabled.
Gateway records route-level secret references in topology metadata when guards or modules declare them. The app runtime receives the Worker environment for its runtime unit. Use dedicated runtime placement when a capability needs a narrower Worker-level secret scope.
Security Notes
Section titled “Security Notes”- Keep CORS origins as exact production origins when using credentials.
- Keep
authorization,cookie,set-cookie, and API key headers out of Gateway logs. - Use route-level auth policies for authorization decisions.
- Use modules such as Captcha or webhook verification for capability-specific ingress checks.
- Keep secrets in the Secret product. Gateway configuration should contain only public routing and policy values.