From ef0742c8eeff0a11b1c636936c49a62d79a0f549 Mon Sep 17 00:00:00 2001 From: Thomas Bayer Date: Wed, 7 Jan 2026 17:48:39 +0100 Subject: [PATCH 1/4] refactor: migrate tutorials, examples, and documentation to YAML format, add XML protection example --- README.md | 156 +++++++++++------- .../tutorials/advanced/10-PathParameters.yaml | 1 - distribution/tutorials/data/hello-dtd.xml | 3 + .../tutorials/security/90-XML-Protection.yaml | 22 +++ docs/ROADMAP.md | 1 + 5 files changed, 121 insertions(+), 62 deletions(-) create mode 100644 distribution/tutorials/data/hello-dtd.xml create mode 100644 distribution/tutorials/security/90-XML-Protection.yaml diff --git a/README.md b/README.md index 538ca43454..b6ac0e3711 100644 --- a/README.md +++ b/README.md @@ -949,82 +949,116 @@ Try the tutorial [OAuth2 with external OpenID Providers](https://membrane-soa.or ### Membrane as Authorization Server -Operate your own identity provider: +Membrane includes a fully functional OAuth 2.0 Authorization Server and can also operate as an OpenID Connect Provider. -```xml +The following example shows a minimal configuration for running Membrane as an OAuth 2.0 authorization server with a static client definition and basic claim and scope setup. - - - - - - - - - - - - - - - +```yaml +api: + port: 8000 + flow: + - oauth2authserver: + issuer: http://localhost:8000 + location: logindialog + consentFile: consentFile.json + ldapUserDataProvider: + map: {} # Configure LDAP mapping here + staticClientList: + clients: + - client: + clientId: abc + clientSecret: def + callbackUrl: http://localhost:2000/oauth2callback + bearerToken: {} + claims: + value: aud email iss sub username + scopes: + - scope: + id: username + claims: username + - scope: + id: profile + claims: username email ``` -See the [OAuth2 Authorization Server](https://www.membrane-soa.org/service-proxy-doc/4.8/oauth2-code-flow-example.html) example. +If no LDAP server is available, you can use file-based, database-backed, or in-memory user data providers instead. + +For a complete walkthrough of the authorization code flow, see the OAuth2 Authorization Server example [OAuth2 Authorization Server](https://www.membrane-soa.org/service-proxy-doc/4.8/oauth2-code-flow-example.html). ## Basic Authentication -```xml - - - - - - - +Sometimes the old basic authentication is enough to provide basic security. + +```yaml +api: + port: 2000 + flow: + - basicAuthentication: + users: + - user: + username: alice + password: secret + - user: + username: bob + password: secret + target: + url: https://api.predic8.de ``` ## SSL/TLS -Route to SSL/TLS secured endpoints: +TLS is the base for secure API communication. -```xml - - - -``` +The first example shows TLS being used for connections from the API Gateway to the backend: -Secure endpoints with SSL/TLS: +```yaml +api: + port: 2000 + # Note the 's' in https! + target: + url: https://api.predic8.de +``` -```xml +The next example secures the public endpoint, enabling TLS for connections from clients to the API Gateway: - - - - - - - +```yaml +api: + port: 443 + ssl: + key: + private: + location: keystore.p12 + certificates: + - certificate: + location: truststore.p12 + target: + url: http://backend ``` +See more [TLS/SSL configuration examples](/distribution/examples/security/ssl-tls) + ### XML and JSON Protection Membrane offers protection mechanisms to secure your APIs from common risks associated with XML and JSON payloads. #### XML Protection -The `xmlProtection` plugin inspects incoming XML requests and mitigates risks such as: +`xmlProtection` inspects incoming XML and reduces common attack vectors, including: -- External entity references (XXE attacks). -- Excessively large element names. +- External entity references (XXE). +- Overly long element names. - High numbers of attributes or deeply nested structures. -**Example:** -```xml - - - - +```yaml +api: + port: 2000 + flow: + - xmlProtection: + maxAttributeCount: 3 + maxElementNameLength: 100 + removeDTD: true + - return: + status: 200 ``` See [XML Protection Reference](https://www.membrane-api.io/docs/current/xmlProtection.html). @@ -1041,11 +1075,12 @@ The `jsonProtection` plugin safeguards APIs from JSON-based vulnerabilities by s **Example:** -```xml - - - - +```yaml +global: + - jsonProtection: + maxDepth: 3 + maxObjectSize: 50 + maxArraySize: 1000 ``` See [JSON Protection](https://www.membrane-api.io/docs/current/jsonProtection.html). @@ -1056,12 +1091,11 @@ See [JSON Protection](https://www.membrane-api.io/docs/current/jsonProtection.ht Limit the number of incoming requests: -```xml - - - - - +```yaml +global: + - rateLimiter: + requestLimit: 1000 + requestLimitDuration: PT1H ``` ## Load balancing diff --git a/distribution/tutorials/advanced/10-PathParameters.yaml b/distribution/tutorials/advanced/10-PathParameters.yaml index daf8430ccd..44e4f2e72b 100644 --- a/distribution/tutorials/advanced/10-PathParameters.yaml +++ b/distribution/tutorials/advanced/10-PathParameters.yaml @@ -1,4 +1,3 @@ - # yaml-language-server: $schema=https://www.membrane-api.io/v7.0.5.json # # Membrane Tutorial: Path Parameters diff --git a/distribution/tutorials/data/hello-dtd.xml b/distribution/tutorials/data/hello-dtd.xml new file mode 100644 index 0000000000..85099751bf --- /dev/null +++ b/distribution/tutorials/data/hello-dtd.xml @@ -0,0 +1,3 @@ + +]> +Hello diff --git a/distribution/tutorials/security/90-XML-Protection.yaml b/distribution/tutorials/security/90-XML-Protection.yaml new file mode 100644 index 0000000000..3eb933ac90 --- /dev/null +++ b/distribution/tutorials/security/90-XML-Protection.yaml @@ -0,0 +1,22 @@ +# yaml-language-server: $schema=https://www.membrane-api.io/v7.0.5.json +# +# Membrane Tutorial: XML Protection +# +# Try it: +# +# 1.) Too many attributes +# curl -d '' -H "Content-Type: text/xml" localhost:2000 +# +# 2.) DTD Removal +# Look at data/hello-dtd.xml +# curl -d @data/hello-dtd.xml -H "Content-Type: text/xml" localhost:2000 + +api: + port: 2000 + flow: + - xmlProtection: + maxAttributeCount: 3 + maxElementNameLength: 100 + removeDTD: true + - return: + status: 200 \ No newline at end of file diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index e8c1bcf87f..5ce692f8bc 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -6,6 +6,7 @@ # 7.X +- Add Example tests for all tutorials - Question: Should we remove the old rest2soap interceptor(using XSLT) in favor of the new template based examples? - Do we need add(Rule,Source) and getRuleBySource(Manual|Spring)? - Rewrite ACL to use the YAML configuration instead of external XML files From c86dc7242786018497ea8f599620d6b20f0d56bb Mon Sep 17 00:00:00 2001 From: Thomas Bayer Date: Wed, 7 Jan 2026 17:49:44 +0100 Subject: [PATCH 2/4] fix(docs): correct link to Prometheus and Grafana example in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b6ac0e3711..78a041930c 100644 --- a/README.md +++ b/README.md @@ -1190,7 +1190,7 @@ This API will expose metrics for Prometheus at [http://localhost:2000/metrics](h ![Grafana Dashborad for Membrane API Gateway](/docs/images/membrane-grafana-dashboard.png) Grafana dashboard from Membrane metrics. -See [Prometheus and Grafana example](distribution/examples/monitoring-tracing/prometheus). +See [Prometheus and Grafana example](distribution/examples/monitoring-tracing/prometheus-grafana). ### OpenTelemetry Integration Membrane supports integration with **OpenTelemetry** traces using the `openTelemetry` plugin and the `W3C` propagation standard. This enables detailed tracing of requests across Membrane and backend services. From 8e1837d7041929caf5ccd2683d7bed2283254270 Mon Sep 17 00:00:00 2001 From: Thomas Bayer Date: Thu, 8 Jan 2026 13:58:06 +0100 Subject: [PATCH 3/4] refactor(docs): update SSL configuration example in README for consistency with keystore/truststore conventions --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 78a041930c..68aa78ff68 100644 --- a/README.md +++ b/README.md @@ -1025,12 +1025,12 @@ The next example secures the public endpoint, enabling TLS for connections from api: port: 443 ssl: - key: - private: - location: keystore.p12 - certificates: - - certificate: - location: truststore.p12 + keystore: + location: keystore.p12 + password: changeit + truststore: + location: keystore.p12 + password: changeit target: url: http://backend ``` From ac71e1d18838adfc031cce69b9c8e827871e1356 Mon Sep 17 00:00:00 2001 From: Thomas Bayer Date: Fri, 9 Jan 2026 12:03:09 +0100 Subject: [PATCH 4/4] docs: update OAuth2 example in README for improved clarity and static user configuration --- README.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 154aec2bfe..3ff2b4bfd8 100644 --- a/README.md +++ b/README.md @@ -950,7 +950,7 @@ Try the tutorial [OAuth2 with external OpenID Providers](https://membrane-soa.or ### Membrane as Authorization Server -Membrane includes a fully functional OAuth 2.0 Authorization Server and can also operate as an OpenID Connect Provider. +Membrane includes a fully functional OAuth 2.0 Authorization Server and can also act as an OpenID Connect Provider. The following example shows a minimal configuration for running Membrane as an OAuth 2.0 authorization server with a static client definition and basic claim and scope setup. @@ -962,8 +962,12 @@ api: issuer: http://localhost:8000 location: logindialog consentFile: consentFile.json - ldapUserDataProvider: - map: {} # Configure LDAP mapping here + staticUserDataProvider: + users: + - user: + username: john + password: secret + email: john@predic8.de staticClientList: clients: - client: @@ -982,9 +986,9 @@ api: claims: username email ``` -If no LDAP server is available, you can use file-based, database-backed, or in-memory user data providers instead. +User accounts can be stored directly in the configuration, loaded from a file, or backed by a database. -For a complete walkthrough of the authorization code flow, see the OAuth2 Authorization Server example [OAuth2 Authorization Server](https://www.membrane-soa.org/service-proxy-doc/4.8/oauth2-code-flow-example.html). +For a full walkthrough of the authorization code flow, see the OAuth2 Authorization Server example [OAuth2 Authorization Server](https://www.membrane-soa.org/service-proxy-doc/4.8/oauth2-code-flow-example.html). ## Basic Authentication