Skip to main content

Plugins

Every node in a featherbit policy graph is a plugin. A single factory — create_plugin() in src/plugins/mod.rs — maps each node's type string from the YAML config to a plugin instance. The plugin system is two-tier:

  • Native plugins — node types implemented in Rust and compiled into the binary. Two of them, listener and client, are structural: they mark the entry and exit of every graph, take no configuration, and are documented together on their own page.
  • Scripted plugins — the script node runs custom plugin logic written in Lua (Luau runtime), loaded from a file or inline.

Every plugin implements the same contract: async fn execute(ctx, named_inputs) -> Result<PluginOutput, PluginExecutionError>. On success, the (possibly mutated) Context flows out of the node's success port; on failure, the error carries the Context so the graph engine can route it through the node's error port instead. Invalid node configuration is rejected by the plugin's from_config at config load time, never at request time.

featherbit expresses the classic proxy phase model (rewrite/access/header_filter/body_filter) as explicit graph position: a "request-phase" plugin is a node wired before upstream; a "response-phase" plugin comes after it. Where a plugin supports a subset of a config schema, its page carries a note describing the exact behavior.

Structural & core proxy

TypeDescription
listener / clientFixed graph entry and exit nodes (no config)
upstreamForward to a backend pool with round-robin, least-connections, or IP-hash balancing
proxy-rewriteRewrite request path and headers
response-rewriteRewrite response status, headers, and body (regex filters, encoding-aware)
body-transformerRewrite request/response JSON bodies via templates
degraphqlExpose a REST endpoint backed by a GraphQL upstream
redirectHTTP redirect, or force HTTP→HTTPS
echoWrap or replace the response body (demo/testing)
gzip / brotliCompress the response body when the client accepts it
request-idAttach a unique request-id header
real-ipRecover the client IP from a trusted proxy header

Error handling & mocking

TypeDescription
error-handlerRender custom error responses with template variables
error-pageReplace 404/500/502/503 bodies with configured pages
exit-transformerRemap status and rewrite the body of gateway-generated exits
mockingRespond with a configured mock instead of proxying (terminal node)

Security & access control

TypeDescription
corsCORS preflight and response header management
csrfDouble-submit CSRF token validation
ip-restrictionAllow/deny by IP or CIDR
ua-restrictionAllow/deny by User-Agent regex
referer-restrictionAllow/deny by Referer host
uri-blockerBlock requests matching URI regex rules
request-size-limitReject over-sized request bodies
request-validationValidate headers/body against JSON Schema
data-maskMask or remove sensitive fields in bodies, headers, query

Traffic control

Several traffic plugins need to act both before and after the upstream call. featherbit expresses this as a pair of nodes wired around upstream, both configured with the same id (or key) and sharing process-wide state — the same request/response split proxy-rewrite uses. Each such page documents the pairing.

TypeDescription
rate-limitToken-bucket rate limiting per IP or header key
limit-countFixed-window request-count limiting (shared counters)
limit-connConcurrent-request limiting (acquire/release node pair)
api-breakerCircuit breaker on unhealthy upstreams (check/observe pair)
traffic-splitWeighted / conditional traffic steering (canary, blue-green)
proxy-mirrorFire-and-forget clone of requests to a shadow upstream
proxy-cacheCache upstream responses (lookup/store node pair)
fault-injectionInject delays and abort responses (percentage + vars gated)
workflowOrdered rules — reject or rate-limit the first matching case
traffic-labelTag matching requests with headers and context labels

Serverless & FaaS

The FaaS plugins invoke an external function and return its reply as the gateway response — they replace the upstream, so wire their success edge to client.in. The serverless functions run inline Lua at a graph position (before or after the upstream) via the same runtime as the script node.

TypeDescription
serverless-pre-functionRun inline Lua before the upstream
serverless-post-functionRun inline Lua after the upstream
oas-validatorValidate requests against an inline OpenAPI 3 spec
aws-lambdaInvoke an AWS Lambda (SigV4 or API-key auth)
azure-functionsInvoke an Azure Function
openwhiskInvoke an Apache OpenWhisk action
openfunctionInvoke an OpenFunction function

Observability & logging

Logger plugins ship access logs to an external sink. They are fire-and-forget: a logger node builds a JSON entry from the request, hands it to a shared batch queue (BatchSink), and returns immediately — the request path never blocks on log I/O. Place a logger after upstream (so status and body are populated); wire it on error paths too if you want failures logged. All loggers share the batch keys (batch_max_size, inactive_timeout, buffer_duration, max_retry_count, retry_delay) and an optional log_format map of name → "$var" templates.

TypeDescription
loggingStructured JSON access logging to stdout
http-loggerShip logs to an HTTP endpoint
tcp-logger / udp-loggerShip logs over a raw TCP / UDP socket
syslogShip logs via syslog (RFC 5424) over TCP or UDP
file-loggerAppend logs to a local file
error-log-loggerShip request-level errors to a TCP sink
elasticsearch-loggerBulk-index logs into Elasticsearch
clickhouse-loggerInsert logs into ClickHouse
loki-loggerPush logs to Grafana Loki
splunk-hec-loggingShip logs to Splunk HEC
datadogEmit DogStatsD metrics to the Datadog agent
logglyShip logs to SolarWinds Loggly
google-cloud-loggingShip logs to Google Cloud Logging
sls-loggerShip logs to Alibaba Cloud SLS
tencent-cloud-clsShip logs to Tencent Cloud CLS
skywalking-loggerShip logs to Apache SkyWalking
lagoMeter requests as Lago billing events

Tracing & metrics

featherbit exposes built-in Prometheus metrics (per-route request counts and latency, per-node execution metrics) at the admin /metrics endpoint — always on, no plugin required (see Observability). The plugins here add distributed tracing and extra metric dimensions.

The three tracers are start/end node pairs: a start node (placed after the listener) extracts or creates the trace context, propagates it to the upstream, and stores the span; an end node (after the upstream) exports the finished span to the collector, fire-and-forget. The span is carried per-request, so the pair needs no shared id.

TypeDescription
prometheusAdds a per-consumer request counter to the built-in metrics
opentelemetryOTLP/HTTP trace export with W3C traceparent propagation
zipkinZipkin v2 trace export with B3 propagation
skywalkingSkyWalking segment export with sw8 propagation

Authentication & consumers

featherbit models API clients as consumers — named identities with per-auth-plugin credentials, declared under consumers: in gateway.yaml and managed via /api/consumers. Auth plugins with use_consumers: true resolve the presented credential to a consumer and attach its identity (consumer.* keys in context.message, X-Consumer-* headers); the restriction plugins then act on it.

TypeDescription
key-authAPI-key auth via header or query; consumer-aware
basic-authHTTP Basic authentication; consumer-aware
jwt-authHMAC JWT validation, inline or per-consumer secrets
hmac-authHMAC request signing (access-key/secret-key), consumer-aware
jwe-decryptDecrypt a JWE token (dir + A256GCM) into a forwarded header
multi-authChain auth plugins — accept the first that succeeds
ldap-authAuthenticate HTTP Basic credentials against an LDAP server
consumer-restrictionAllow/deny by consumer name or group
aclAllow/deny by consumer group
attach-consumer-labelCopy consumer labels into upstream request headers

External auth & authorization

These plugins delegate the auth or authorization decision to an external service over HTTP (via the shared outbound client). The SSO plugins support interactive browser login as well as stateless token validation: featherbit has no server-side session store, but the interactive flows keep all state in an encrypted client-side cookie (see the cookie-session codec), so they work across a horizontally-scaled deployment as long as instances share the session secret. Each page's Deviations section states the exact behavior and the one remaining limitation (no server-side revocation before cookie expiry).

TypeDescription
forward-authDelegate the decision to an external HTTP auth service
opaDelegate authorization to an Open Policy Agent instance
authz-casbinEmbedded Casbin RBAC/ABAC enforcement (no network)
authz-keycloakKeycloak UMA permission check
authz-casdoorCasdoor: bearer-token introspection or interactive OAuth login
openid-connectOIDC: bearer-token validation or interactive Authorization Code login
cas-authCAS: ticket validation or interactive SSO login
wolf-rbacWolf RBAC token check
dingtalk-authDingTalk code/token validation
feishu-authFeishu/Lark code/token validation

Scripting

TypeDescription
scriptCustom plugin logic written in Lua (Luau), from a file or inline

Reading the reference pages

Each plugin page documents:

  • Configuration — the keys the plugin's from_config accepts, with types, defaults, and which malformed shapes are rejected at config load.
  • Behavior — what the plugin reads and writes on the Context (request, response, message, errors), when it takes the success versus error port, and the error codes it can emit.

Unknown type strings fail policy compilation with Unknown plugin type: <name>.