How To: Forward a Custom Claim from JWT into HTTP Header

Overview

This tutorial explains how to extract a claim from a JWT—such as org (organization) and forward it to a backend as a custom HTTP header (X-Org).

Use Case

Useful in systems where backend services need to know the organization context for the request, but JWT validation happens at the gateway.

Step 1: Generate a JSON Web Key (JWK)

./membrane.sh generate-jwk -o ./conf/jwk.json

Optional: use a specific key size:

./membrane.sh generate-jwk -b 2048 -o ./conf/jwk.json

Step 2: Configure Your Routes

Add the following to your proxies.xml file:

<!-- Token Server -->
<api port="2000" name="Token Server">
<request>
<template>
{
"sub": "user@example.com",
"aud": "order",
"scp": "read write",
"organization": "predic8"
}
</template>
<jwtSign>
<jwk location="jwk.json"/>
</jwtSign>
</request>
<return/>
</api>

<!-- Protected API that reads 'organization' from JWT -->
<api port="2001" name="Protected Resource">
<jwtAuth expectedAud="order">
<jwks>
<jwk location="jwk.json"/>
</jwks>
</jwtAuth>

<!-- Set header using claim from JWT -->
<setHeader name="X-Org" value="${properties.jwt['organization']}"/>

<target host="localhost" port="2002"/>
</api>

<!-- Backend that logs headers -->
<api port="2002" name="Backend Logger">
<log/>
<return statusCode="200"/>
</api>
<!-- Token Server -->
<api port="2000" name="Token Server">
  <request>
    <template>
      {
        "sub": "user@example.com",
        "aud": "order",
        "scp": "read write",
        "organization": "predic8"
      }
    </template>
    <jwtSign>
      <jwk location="jwk.json"/>
    </jwtSign>
  </request>
  <return/>
</api>

<!-- Protected API that reads 'organization' from JWT -->
<api port="2001" name="Protected Resource">
  <jwtAuth expectedAud="order">
    <jwks>
      <jwk location="jwk.json"/>
    </jwks>
  </jwtAuth>

  <!-- Set header using claim from JWT -->
  <setHeader name="X-Org" value="${properties.jwt['organization']}"/>

  <target host="localhost" port="2002"/>
</api>

<!-- Backend that logs headers -->
<api port="2002" name="Backend Logger">
  <log/>
  <return statusCode="200"/>
</api>

Step 3: Start Membrane

./membrane.sh

Membrane will now serve:

Step 4: Get a Token

curl http://localhost:2000

Returns a signed JWT like:

eyJhbGciOiJSUzI1NiIsInR5cCI...

Step 5: Use the Token

curl -H "Authorization: Bearer <your-token>" http://localhost:2001

The backend will log something like:

X-Org: predic8

Next Steps