Membrane API Gateway returns 403 Forbidden with a link to this page when the cors plugin rejects a CORS preflight request, because the policy combines credentials: true with the wildcard origin *, which CORS never allows. The browser then blocks the actual cross-origin request of the page.
The response contains the status 403 Forbidden, the detail The credentials '...' is not allowed by the CORS policy., where the quoted value is the origin of the page, the problem type https://membrane-api.io/problems/security/credentials-not-allowed and a link to this page. The type security with the subtype credentials-not-allowed means that the CORS policy of the gateway refused the request.
Before a web page sends a cross-origin request that is not a simple request, the browser sends a preflight: an OPTIONS request with the headers Origin, Access-Control-Request-Method and, if needed, Access-Control-Request-Headers. The cors plugin checks these values against its origins, methods, headers and credentials settings and answers the preflight itself. If one check fails, it rejects the preflight with this error. The CORS Guide for API Developers explains the background.
The cors plugin has credentials: true, but origins contains * or is not set, in which case it defaults to *. The CORS standard forbids answering a credentialed request for any origin, because any web site could then call the API with the user's cookies. With this configuration, every preflight that passes the other checks is rejected.
The API worked without credentials, and credentials: true was added later, for example to support cookies or HTTP authentication, without changing origins.
* in origins with the explicit list of origins that may send credentials.credentials: true instead.api:
port: 2000
flow:
- cors:
origins: https://example.com https://app.example.com
credentials: true
target:
url: https://api.predic8.de
api:
port: 2000
flow:
- cors:
origins: https://example.com https://app.example.com
credentials: true
target:
url: https://api.predic8.de
For development only, allowAll: true skips all CORS checks. Do not use it in production.
Unlike most errors, CORS rejections are sent with the detail and the link to this page even when Membrane runs in production mode. Setting production: true in the configuration document does not remove them.
Configuration reference:
Still stuck? See the troubleshooting guide or ask on GitHub Issues. For commercial support, contact info@predic8.de.