| flow | 0..* | |
| rules | 0..* | |
| accessLog | 0..1 | Writes one access-log line per completed exchange through a Log4j appender. The line follows the Apache Common Log Format by default; add additionalPatternList entries to append your own SpEL-evaluated fields. Where the line is written and in which format is controlled by the Log4j configuration (log4j2.xml). Typically configured under global so it covers every API. See the tutorials under tutorials/logging. |
| acmeHttpChallenge | 0..1 | Answers ACME HTTP-01 challenges (RFC 8555, section 8.3). A request to /.well-known/acme-challenge/<token> for a host with a pending challenge gets the key authorization as application/octet-stream. Any other token gets 404. If the ACME account key cannot be processed, the response is a 500 internal problem detail. See the documentation of the acme element for the certificate setup. |
| adminApi | 0..1 | Provides a JSON-based Admin API (health, apis, calls, exchange details, suggestions, ws) backed by the ExchangeStore. |
| adminConsole | 0..1 | Displays up-to-date statistics, recent exchanges and, by default, allows live modification of Membrane's configuration. |
| analyser | 0..1 | Analyses XML bodies and stores extracted root element + SOAP operation metadata in Exchange properties (request/response). |
| apiDocs | 0..1 | Publishes an overview of all OpenAPI-enabled proxies and serves Swagger UI under /api-docs/ui/*. |
| apiKey | 0..1 | Validates an API key extracted from each request and resolves its scopes from the configured stores. On success it adds an ApiKeySecurityScheme carrying the scopes to the Exchange, which later plugins test with hasScope("..."). A missing key returns 401 and an invalid key 403 as Problem Details, unless required is false, in which case requests pass and scopes are attached only when a valid key is present. |
| apisJson | 0..1 | Publishes every API deployed on this gateway as an APIs.json 0.24 document, a collection a crawler or registry can index. The catalog is collected from the running configuration on each request and therefore never goes stale. |
| authHead2Body | 0..1 | Moves the credentials of a SOAP authorization element out of the request body into username/password child elements of the payload element, for a backend that expects them inline. Requests without an authorization element pass through unchanged. |
| balancer | 0..1 | Distributes requests across a set of backend nodes. Nodes are grouped into one or more clusters, and the configured dispatching strategy picks a node for each request, defaulting to round-robin. Failover is always on: the remaining nodes are added as fallback destinations, so a request retries the next node when one fails. When a sessionIdExtractor is configured, requests carrying a known session are pinned to the node that first served it (sticky sessions). On dispatch the chosen node is stored on the exchange and its statistics are updated when the response returns; if no node is available the request is answered with 503. Can only be used inside an api or serviceProxy. See the tutorials under distribution/tutorials/loadbalancing. |
| basicAuthentication | 0..1 | Requires HTTP Basic credentials (the Authorization: Basic header) on each request and verifies them against the configured users or user data provider. On success the request continues and an HTTP Basic security scheme carrying the username is attached to the exchange; the Authorization header is removed before the request is forwarded. A missing or invalid credential is rejected with 401 and a WWW-Authenticate challenge. See the tutorials tutorials/security/10-Basic-Authentication.yaml, 11-Basic-Authentication-htpasswd.yaml and 12-Basic-Authentication-database.yaml. |
| beautifier | 0..1 | Pretty-prints the message body according to its Content-Type. JSON, JSON5, XML and plain text are reindented; any other content type is left unchanged. Runs in both the request and the response flow and is best-effort: an empty or unparseable body passes through untouched and the exchange never fails. See the tutorials under tutorials/json and tutorials/xml. |
| cache | 0..1 | Don't use, this does NOT implement valid HTTP caching. |
| call | 0..1 | Calls an external HTTP endpoint and merges its response into the current message. The endpoint's response body replaces the message body, and its headers are copied onto the message except Server, Content-Encoding and Transfer-Encoding. Runs in both the request and the response flow. The url may contain ${...} expressions that are evaluated against the exchange before each call; a URL without a template marker is used verbatim. On an unknown host or a failed call the exchange is aborted with a Problem Details response. See the tutorials under tutorials/orchestration. |
| choices | 0..* | |
| clamav | 0..1 | ClamAV is an open-source antivirus engine whose daemon, clamd, scans data sent to it over TCP. This plugin streams the headers and body of each message to clamd and blocks the message if a signature matches. |
| clusterNotification | 0..1 | Receives control requests at /clustermanager/{up|down|takeout}, with host and port (and optional balancer/cluster) query parameters, and applies them to update a load balancer's node status. Responds with 204 on success, 400 when required parameters are missing or invalid, and 403 when the request's time parameter is older than timeout. |
| correlationId | 0..1 | Reads a correlation id from a request header (or generates one if absent), writes it back into that header and adds it to the SLF4J MDC logging context so it appears in every log line of the request. The MDC entry is removed again on the response (and on abort). |
| cors | 0..1 | Cross-Origin Resource Sharing (CORS) plugin that enables secure cross-origin HTTP requests. |
| counter | 0..1 | Returns a simple HTML page and counts how often it was requested (increments per request). |
| destination | 0..1 | Sets the destination URL for the exchange. This overrides any previous destination. |
| dispatching | 0..1 | This interceptor adds the destination specified in the target element to the list of destinations of the exchange object. It must be placed into the transport to make Service Proxies Work properly. It has to be placed after the ruleMatching interceptor. The ruleMatching interceptor looks up a service proxy for an incoming request and places it into the exchange object. The dispatching interceptor needs the service proxy to get information about the target. |
| echo | 0..1 | Returns the flow of plugins and copies the content of the request into a new response. The response has a status code of 200. Useful for testing. |
| exchangeStore | 0..1 | Adds the current state of HTTP requests and responses to an "exchange store" so they can be inspected later. Depending on the store implementation, both the request and the response phase may need to run before an exchange is saved. |
| flowInitiator | 0..1 | Starts a named OAuth2 login flow other than the client's default one. It triggers the configured oauth2 client's normal login redirect internally, then rewrites the Location header and the body of that redirect so the browser is sent to triggerFlow instead of the client's defaultFlow, merging in any configured login parameters. |
| for | 0..1 | Iterates over a collection and runs its nested flow once per element. The in expression is evaluated against the exchange and must yield a List; for each item the nested plugins run with the current item exposed as the exchange property it. Iteration happens only in the request flow and only when the expression yields a list; any other value passes through unchanged. If the expression fails to evaluate, the exchange is aborted with a Problem Details response. See the tutorials under tutorials/orchestration. |
| formValidation | 0..* | Using the formValidation interceptor you can validate the input of HTML forms. |
| graphQLProtection | 0..1 | Check GraphQL-over-HTTP requests, enforcing several limits and/or restrictions. This effectively helps to reduce the attack surface. |
| greaser | 0..1 | Randomly applies greasing strategies to request/response messages (rate 0..1) to stress-test parsers (e.g., JSON/XML). |
| groovy | 0..1 | Runs a Groovy script against the current exchange to read or modify messages and steer the flow. The script runs in the request, response, and abort flows. Its return value decides what happens next: |
| filterRules | 0..* | |
| http2xml | 0..1 | |
| httpClient | 0..1 | The httpClient sends the request of an exchange to a Web Server using the HTTP protocol. Usually it will be globally used inside the transport. However, it is also possible to use it inside a proxy to give the proxy an individual configuration for its outgoing HTTP connection that is different from the global configuration in the transport. |
| idempotency | 0..1 | Prevents duplicate request processing based on a dynamic idempotency key. |
| if | 0..1 | if allows conditional execution of nested interceptors. |
| index | 0..1 | The index feature lists available proxys at a simple Web page. To use this feature just add a serviceProxy containing the index element. Of course you can protect the service proxy by using SSL or Username and Password. |
| interceptor | 0..1 | Wraps an interceptor provided as Spring bean (refid) or as nested interceptor (child element) and delegates all calls. |
| internalRouting | 0..1 | Routes a request to another proxy configured in the same router when its current destination is an internal:// URI, running that proxy's interceptor chain in-process instead of over the network. If an interceptor along that chain returns early, the corresponding response handlers are invoked on the way back before control returns to the original proxy's flow. |
| javascript | 0..1 | Executes a Javascript. The script can access and manipulate data from the request and response. Use this or the Groovy plugin to extend the functions of Membrane by scripting. See the samples in examples/javascript. |
| jmsProducer | 0..1 | Sends the body of the request or the response as a message to a JMS queue or topic. |
| json2Xml | 0..1 | Converts a JSON message body to XML. A body that is not JSON passes through unchanged. The result is UTF-8 encoded, begins with an XML prolog, and the Content-Type is set to application/xml. If the body is not valid JSON the exchange is aborted with a 500 Problem Details. See the tutorial tutorials/xml/10-JSON-to-XML.yaml. |
| jsonProtection | 0..1 | Enforces restrictions on JSON request bodies to protect against JSON-based attacks and resource exhaustion. Validates against configurable limits to prevent attacks such as: |
| jsonRPCProtection | 0..1 | Protects JSON-RPC endpoints by validating request structure, controlling batch usage, applying ordered allow/deny rules to method names, and optionally validating request parameters and responses against JSON Schema documents. |
| jwtAuth | 0..1 | Validates a JWT on requests (signature via JWKS, required exp/sub) and exposes claims in exchange properties ("jwt"). |
| jwtSign | 0..1 | Signs the request or response body as a JWT, replacing the body with the compact JWS serialization (or storing it in a property instead, when property is set). The body must be a JSON object; iat, exp and nbf claims are added automatically before signing. |
| kafkaProducer | 0..1 | Publishes the body of the request or the response as a message to an Apache Kafka topic. |
| kubernetesValidation | 0..1 | Kubernetes Integration is still experimental. |
| limit | 0..1 | Enforces a maximum body size, rejecting oversized messages with a Problem Details 400 response. |
| llmGateway | 0..1 | Gateway in front of an LLM provider's chat API (OpenAI, Anthropic/Claude, or Google Gemini). It can share a single provider API key among many clients, authenticate clients and enforce per-user token limits through a store, apply usage policies, and inject a system prompt; token usage is recorded when the response returns. Place it in the flow of an api whose target is the provider's API. Without a store the gateway is stateless and just forwards requests with the configured key and policies. See the tutorials under tutorials/llm-gateway. |
| log | 0..1 | Logs request and response messages to the console or a log file, depending on the logging configuration. By default it writes the start line, headers, and body of each message, with sensitive header values masked. Set message to log the result of an expression instead of the full dump: |
| logContext | 0..1 | Puts the current API proxy's name into the logging ThreadContext under the key api for the duration of the exchange, so it can be included in log output (e.g. via a pattern layout); the entry is removed once the exchange finishes or aborts. |
| login | 0..1 | The login interceptor can be used to restrict and secure end user access to an arbitrary web application. |
| mcpProtection | 0..1 | Protects an MCP endpoint by validating incoming JSON-RPC requests and restricting the MCP methods and tools that clients may use. |
| membraneMCPServer | 0..1 | MCP Server for Membrane. It allows querying Membrane's internal state and operation from an LLM Ask the LLM questions like: - What APIs are deployed? - Is the Membrane instance healthy? - Give me a summary about the requests |
| ntlm | 0..1 | Performs NTLM authentication when the upstream responds with WWW-Authenticate: NTLM by replaying the request with NTLM headers. |
| oauth2authserver | 0..1 | OAuth2/OIDC authorization server endpoints (auth/token/userinfo/revocation/.well-known) with session + consent/login UI. |
| oauth2Client | 0..1 | Obtains an OAuth2 access token using the client credentials flow and forwards the request with a Bearer token. |
| oauth2PermissionChecker | 0..1 | |
| oauth2Resource2 | 0..1 | Allows only authorized HTTP requests to pass through. Unauthorized requests get a redirect to the authorization server as response. This interceptor does Session Management and can thereby translate Session IDs to OAuth2/OIDC Access Tokens. Beyond regular OIDC-compliant authorization servers, this interceptor can also be used with Azure B2C. |
| openapiPublisher | 0..1 | Serves the OpenAPI documents declared on the enclosing api together with a Swagger UI, under the /api-docs path. /api-docs returns an overview of all documents: an HTML page when the client accepts HTML, otherwise a JSON list with each document's title, version, and links. /api-docs/{id} returns one document as YAML, rewritten so its server URLs point at the gateway, and /api-docs/ui/{id} opens the Swagger UI for that document. An unknown id returns 404; requests to other paths pass through unchanged. Can only be used inside an api. See the tutorial tutorials/getting-started/120-OpenAPI.yaml. |
| openapiValidator | 0..1 | Validates requests and responses against the OpenAPI documents declared on the enclosing api (its openapi elements). Those documents are normally validated automatically before the flow runs; add this element to the flow to run validation at a specific point instead, for example after an authentication plugin so its result is available to security validation. What is checked is controlled per document by the openapi element's validateRequests, validateResponses, and validateSecurity options (or the matching x-membrane-validation extension in the document). A request matching no document is answered with 404, a request that violates its schema with a 4xx Problem Details, and an invalid response with 500. Can only be used inside an api. See the tutorial tutorials/openapi/21-Validation-Advanced.apis.yaml. |
| openTelemetry | 0..1 | OpenTelemetry is an open observability standard for distributed tracing. It tracks a request as it travels across services by passing a traceparent header from hop to hop and collecting timing data (spans) in a central backend such as Jaeger or Zipkin. Membrane supports OpenTelemetry by creating one INTERNAL span per request: it extracts the incoming W3C trace context from request headers, opens the span, and injects the updated traceparent into the forwarded request so downstream services join the same trace. HTTP headers are recorded as http.header.* attributes, the response status as http.status_code, and for API proxies the OpenAPI title as openapi.title. The traceId and spanId are written into SLF4J MDC automatically so every log line carries them. Aborted exchanges are marked ERROR. Declare the plugin in global: to instrument all APIs at once. See tutorials/operation/40-OpenTelemetry.yaml for a runnable multi-hop example with Jaeger. |
| paddingHeader | 0..1 | Adds an X-Padding header with random characters to pad message size (request/response). |
| prometheus | 0..1 | Prometheus is an open-source monitoring system that collects metrics by scraping HTTP endpoints at regular intervals. Deploy this element on a dedicated endpoint to expose Membrane's internal metrics in the Prometheus text exposition format (v0.0.4). |
| rateLimiter | 0..1 | The rateLimiter plugin limits the number of requests of a client in a period of time. As a default the client requests are grouped by client-Ip address and then counted. There are lots of possibilities to group the requests using the keyExpression. The requests can even be counted from different clients together. |
| regExReplacer | 0..1 | Runs a regular-expression-replacement on either the message body (default) or all header values. |
| replace | 0..1 | Replaces a JSON value at the configured JSONPath with a static string. |
| requireAuth | 0..1 | Requires a valid access token for the request, accepted either as a Bearer JWT (validated directly against the configured oauth2 client's JWKS) or, when no bearer token is present, via that client's normal session/login flow. After a successful session flow the request still passes through JWT validation before continuing. |
| rest2Soap | 0..1 | Converts REST requests into SOAP messages. |
| return | 0..1 | Stops processing the request and sends a response back to the client without calling the backend. If the exchange already holds a response, that response is sent; otherwise a new response is built from the request's body and Content-Type. Often paired with template to return a generated body. |
| reverseProxying | 0..1 | Rewrites the scheme, hostname and port in the "Location" header in HTTP responses, as well as in the "Destination" header in HTTP requests. The rewriting reflects the different schemes, hostnames and ports used to access Membrane vs. the target HTTP server. |
| rewriter | 0..* | Rewrites or redirects the path of incoming requests based on a mapping. |
| ruleMatching | 0..1 | Selects and assigns the matching proxy rule for incoming requests; optionally adds/extends X-Forwarded-* headers. |
| sampleSoapService | 0..1 | A built-in SOAP web service returning city population data, for testing and demonstration. Serves its own WSDL, responds to getCity requests, and returns a SOAP fault for non-POST requests or unknown cities. |
| setBody | 0..1 | Sets the body of the current HTTP message to a static string or a computed expression. SpEL template expressions are supported by default; Groovy, JsonPath, and XPath are also available. For conditional output or loops, use the template interceptor instead. See tutorials/getting-started/100-SetBody.yaml. |
| setCookies | 0..* | Adds one or more Set-Cookie headers to the HTTP response for session handling, user preferences, or tracking purposes. Supports computing expiry, setting standard attributes like Domain and Path, and building a compliant cookie string. Useful for enriching responses with configurable cookies directly at gateway level without backend involvement. |
| setHeader | 0..1 | Sets an HTTP header field on the current message to a constant string or a computed value. SpEL template expressions are supported by default; Groovy, JsonPath, and XPath are also available. See tutorials/getting-started/90-SetHeader.yaml. |
| setProperty | 0..1 | Sets an exchange property to a constant string or a computed value. Unlike a header or the body, a property is not sent to the client; it is only readable by later interceptors in the same exchange, e.g. as ${property.name} in a template or another expression. The value is evaluated as a SpEL template, Groovy, JsonPath, or XPath expression, defaulting to SpEL. See tutorials/orchestration/30-Orchestration.yaml. |
| shadowing | 0..1 | Clones incoming requests and sends them asynchronously to one or more shadow targets (main exchange continues unchanged). |
| shutdown | 0..1 | Shutdown interceptor. |
| soap2Rest | 0..1 | Converts SOAP messages into REST requests. |
| soapBody | 0..1 | Renders a SOAP body for legacy integration. The Content-Type defaults to the type of the configured SOAP version (text/xml for 1.1, application/soap+xml for 1.2). Setting contentType explicitly overrides this, e.g. to add a charset. |
| soapOperationExtractor | 0..1 | Extracts a SOAP operation's element name and namespace from the request body and stores them in the exchange properties XSLT_SOAP_OPERATION and XSLT_SOAP_OPERATION_NS, for use by downstream interceptors, such as an XSLT stylesheet, that branch on the operation. Non-SOAP or empty request bodies pass through unchanged. |
| soapStackTraceFilter | 0..1 | The soapStackTraceFilter removes SOAP stack traces from message bodies. |
| sqlInjectionProtection | 0..1 | Detects SQL injection patterns in incoming requests and blocks them before they reach the backend. Inspects query parameters, the request path, form and JSON bodies (and optionally headers) against a set of detection rules transpiled from the OWASP Core Rule Set (CRS) REQUEST-942 SQL-injection rules. |
| sseDemoStream | 0..1 | Demo interceptor that streams a Server-Sent Events (SSE) response, emitting one JSON event per interval, for testing or demonstration purposes. |
| static | 0..1 | Sets the message body to static content. The body is either provided inline as text content or loaded from a file/URL. If pretty is enabled, the formatted result is cached and reused until the interceptor is (re)initialized. |
| statisticsCSV | 0..1 | Writes statistics (time, status code, hostname, URI, etc.) about exchanges passing through into a CSV file (one line per exchange), UTF-8 encoded. |
| statisticsJDBC | 0..1 | Writes statistics (time, status code, hostname, URI, etc.) about exchanges passing through into a database (one row per exchange). |
| statisticsProvider | 0..1 | Serves request statistics as JSON from a JDBC-backed store. Supports paging (offset/max) and sorting (sort/order) via query parameters. |
| stompClient | 0..1 | Forwards STOMP requests to a STOMP broker and then tunnels the connection between client and broker. A request without STOMP credentials (login and passcode, or host and accept-version headers) gets 400. If the broker cannot be reached or the connection fails, the response is a 502 gateway problem detail. |
| tcp | 0..1 | Allow HTTP protocol upgrades to the TCP protocol. After the upgrade, the connection's data packets are simply forwarded and not inspected. |
| template | 0..1 | Renders the body content of a message from a template. The template can produce plain text, Json or XML. Variables in the template are substituted with values from the body, header, query parameters, etc. If the extension of a referenced template file is .xml it will use XMLTemplateEngine otherwise StreamingTemplateEngine. |
| throttle | 0..1 | Throttles incoming traffic by delaying requests and/or capping how many are processed concurrently, to protect a backend from overload. With delay set, every request is held briefly before it continues. With maxThreads set, a request that arrives while the limit is already reached is rejected with 503 once no slot frees up. See the examples under examples/routing-traffic/throttle. |
| time | 0..1 | Measures the end-to-end processing time of the child interceptor flow and logs an aligned summary. If an OpenTelemetry parent Span is present on the {@link Exchange}, a child sub-span is created around the measured section so timing data is exported to OTel as well. |
| tokenValidator | 0..1 | Validates the Authorization header of each request by sending it on a GET to an external validation endpoint; the request continues only if that endpoint responds with HTTP 200, otherwise it is rejected with 400 Bad Request. |
| transform | 0..1 | Applies an XSLT stylesheet to the body of a request or response and replaces the body with the transformation result. Every string-valued Exchange property is passed to the stylesheet as an XSLT parameter of the same name; declare a matching xsl:param in the stylesheet to read it. Set such a property beforehand, e.g. with setProperty. See tutorials/xml/62-XSLT-Parameter.yaml. |
| userFeature | 0..1 | Handles features that are user-configured in proxies.xml . |
| validator | 0..1 | Validates request and response message bodies against a schema. The schema type is selected by the attribute you set: wsdl for SOAP messages, schema for XML against an XSD, jsonSchema for JSON or YAML, or schematron. Exactly one of them must be configured; inside a soapProxy the WSDL is taken from the proxy automatically. With a WSDL, SOAP header blocks can be validated as well. An empty body passes; an invalid body is rejected with an error response that lists what was wrong. Set validationDetails to false to reject with a bare error instead, and failureHandler to control where the failure is logged. See distribution/tutorials/xml/50-XSD-Schema-validation.yaml and distribution/tutorials/soap/40-WSDL-Message-Validation.yaml. |
| webServer | 0..1 | Serves static files from a directory, a classpath location, or a URL, based on the request's path. The interceptor chain does not continue past this interceptor: it always finalizes the exchange, either with the contents of a matching file or with an error response, 404 for a path that matches no file and 400 for one that tries to escape the document base. |
| webServiceExplorer | 0..1 | Serves an HTML “web service explorer”. |
| webSocket | 0..1 | Lets clients upgrade a connection to the WebSocket protocol (RFC 6455) and relays it between client and backend. Without this plugin, upgrade requests are rejected. The upgrade request passes the flow like any other request, so plugins before webSocket, e.g. for authentication, apply to it. |
| webSocketDemoStream | 0..1 | Acts as a WebSocket backend that pushes demo data, for trying out and testing WebSocket proxies. It accepts the WebSocket upgrade and sends one JSON text message per interval with a running number, a timestamp and a simulated measured value: |
| wsaEndpointRewriter | 0..1 | |
| wsdl2openapi | 0..1 | The wsdl2openapi interceptor exposes SOAP/WSDL services via HTTP/JSON/OpenAPI. It automatically converts JSON requests to SOAP XML and SOAP XML responses back to JSON. |
| wsdlPublisher | 0..1 | The wsdlPublisher serves WSDL files (and attached XML Schema Documents), if your backend service does not already do so. |
| wsdlRewriter | 0..1 | Rewrites SOAP endpoint addresses and XML Schema locations (XSD import and include) in WSDL and XSD documents returned by the backend, so they point at the gateway instead of the backend's own address. By default the gateway's protocol, host, and port from the incoming request are used; set the attributes below to force a specific address. Typically used inside a soapProxy, where the service path is taken from the proxy. See the tutorial tutorials/soap/30-WSDL-Rewriter.yaml. |
| wsSecurity | 0..1 | Owns the WS-Security (wsse:Security) header of a SOAP message: the validate list consumes the security the peer sent, the secure list applies fresh security for the next hop. Both lists are optional and run in the order they are written; the whole validate list runs first, and the inbound header is removed at that boundary before secure creates a new one. With no validate list the header is emptied of the tokens the peer sent instead of being forwarded unchecked; what survives is only what asserts nothing on its own — its wsu:Timestamp, since a secure signature may cover it, and its XML Encryption material (xenc:EncryptedKey and xenc:EncryptedData) for as long as encrypted content is still in the message, since dropping key material while forwarding the ciphertext would leave a message nobody downstream can read. Header blocks targeted at a different actor are left untouched. |
| xenAuthentication | 0..1 | |
| xml2Json | 0..1 | Converts an XML message body to JSON using a structural, heuristic mapping: elements and attributes both become JSON properties, and a repeated element becomes a JSON array while the same element occurring once becomes an object. |
| xmlContentFilter | 0..1 | The xmlContentFilter removes certain XML elements from message bodies. The elements are described using an XPath expression. |
| xmlProtection | 0..1 | Prohibits XML documents to be passed through that look like XML attacks on older parsers. Too many attributes, too long element names are such indications. DTD definitions will simply be removed. |