Openid connect and the id token


Is it possible to decode the openid connect id token and retrieve the identity claims before it gets passed on to the target url? There are some systems that won’t be able to do the decoding so I’d like to do it at the gateway and add the attributes to the header.



They are available as context variables in the v2.2.0.3+ releases.

The new variables aren’t documented yet, but the JWT Claims are in the context variable map as $tyk_context.jwt_claims_{claimname}

So you can embed them in headers or into the URL or into the body in a transform template.

1 Like

Hi Martin:

I tried this but it doesn’t seem to be retrieving any of the claims. Actually, it doesn’t seem to be retrieving any context variable at all. Is there something I need to enable first before I can retrieve context variables?

I’m using the RPM installation…

Ok, forgot to enable Context Variable in advanced options. So i can retrieve other context variables but the jwt claims are still empty. Log says:

“Context Data not found for key in map: jwt_claims_name”

Ah, my bad, custom JWT’s support the context claim, OIDC does not (yet - I just pushed a change to develop that incorporates this for OIDC, it’ll be in the next release)

Ahhh ok that makes sense now. No prob, will look out for it in the next release.


custom JWT’s support the context claim, OIDC does not

@Martin May I know does the OIDC support the context variable now? ver 2.3.7

Plus 1 to the question.

@marians Verified and it supports.

Yes it does support context now :slight_smile:

I’m trying to make use of this in tyk 2.3.7, but can’t.

For test purposes, I’m proxying against .

I’m using global_headers as explained here: Request Headers

Test request and response
http get localhost:8080/openidconnect/ 'Authorization:Bearer '$IDTOKEN
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Connection: close
Content-Length: 956
Content-Type: application/json
Date: Thu, 27 Jul 2017 10:16:06 GMT
Server: meinheld/0.6.1
Via: 1.1 vegur
X-Powered-By: Flask
X-Processed-Time: 0.00076699256897
X-Ratelimit-Limit: 10000
X-Ratelimit-Remaining: 9997
X-Ratelimit-Reset: 1501153684

    "headers": {
        "Accept": "*/*",
        "Accept-Encoding": "gzip, deflate",
        "Authorization": "Bearer eyJhbGciO... (truncated)",
        "Connection": "close",
        "Host": "",
        "User-Agent": "HTTPie/0.9.8"
API Definition
  "id": "5978bc3e914dc313dbe5bc1a",
  "name": "Open ID Connect Demo",
  "slug": "openidconnect",
  "api_id": "openidconnect",
  "org_id": "default",
  "use_keyless": false,
  "use_oauth2": false,
  "oauth_meta": {
    "allowed_access_types": [],
    "allowed_authorize_types": [],
    "auth_login_redirect": ""
  "auth": {
    "use_param": false,
    "use_cookie": false,
    "auth_header_name": "Authorization"
  "use_basic_auth": false,
  "enable_jwt": false,
  "jwt_signing_method": "",
  "jwt_source": "",
  "jwt_identity_base_field": "",
  "jwt_client_base_field": "",
  "jwt_policy_field_name": "",
  "notifications": {
    "shared_secret": "",
    "oauth_on_keychange_url": ""
  "enable_signature_checking": false,
  "hmac_allowed_clock_skew": -1,
  "definition": {
    "location": "header",
    "key": "x-api-version"
  "version_data": {
    "not_versioned": true,
    "versions": {
      "Default": {
        "name": "Default",
        "expires": "",
        "paths": {
          "ignored": [],
          "white_list": [],
          "black_list": []
        "use_extended_paths": true,
        "extended_paths": {
          "ignored": [],
          "white_list": [],
          "black_list": [],
          "cache": [],
          "transform": [],
          "transform_response": [],
          "transform_headers": [],
          "transform_response_headers": [],
          "hard_timeouts": [],
          "circuit_breakers": [],
          "url_rewrites": [],
          "virtual": [],
          "size_limits": []
        "global_headers": {
          "X-Remote-Addr": "$tyk_context.remote_addr",
          "X-GiantSwarm-User-Subject": "$tyk_context.jwt_claims_sub",
          "X-GiantSwarm-User-Email": "$tyk_context.jwt_claims_email",
          "X-GiantSwarm-User-Organizations": "$tyk_context.jwt_claims_groups"
        "global_headers_remove": ["X-Generator", "X-Powered-By"],
        "global_size_limit": 0
  "uptime_tests": {
    "check_list": [],
    "config": {
      "expire_utime_after": 0,
      "service_discovery": {
        "use_discovery_service": false,
        "query_endpoint": "",
        "use_nested_query": false,
        "parent_data_path": "",
        "data_path": "",
        "port_data_path": "",
        "use_target_list": false,
        "cache_timeout": 0,
        "endpoint_returns_list": false
      "recheck_wait": 0
  "proxy": {
    "listen_path": "/openidconnect/",
    "target_url": "",
    "strip_listen_path": true,
    "enable_load_balancing": false,
    "target_list": [],
    "check_host_against_uptime_tests": false,
    "service_discovery": {
      "use_discovery_service": false,
      "query_endpoint": "",
      "use_nested_query": false,
      "parent_data_path": "",
      "data_path": "",
      "port_data_path": "",
      "use_target_list": false,
      "cache_timeout": 0,
      "endpoint_returns_list": false
  "custom_middleware": {
    "pre": [],
    "post": [],
    "response": []
  "cache_options": {
    "cache_timeout": 60,
    "enable_cache": true,
    "cache_all_safe_requests": false,
    "enable_upstream_cache_control": false
  "session_lifetime": 0,
  "active": true,
  "auth_provider": {
    "name": "",
    "storage_engine": "",
    "meta": {}
  "session_provider": {
    "name": "",
    "storage_engine": "",
    "meta": null
  "event_handlers": {
    "events": {}
  "enable_batch_request_support": false,
  "enable_ip_whitelisting": false,
  "allowed_ips": [],
  "dont_set_quota_on_create": false,
  "expire_analytics_after": 0,
  "response_processors": [],
  "CORS": {
    "enable": false,
    "allowed_origins": [],
    "allowed_methods": [],
    "allowed_headers": [],
    "exposed_headers": [],
    "allow_credentials": false,
    "max_age": 0,
    "options_passthrough": false,
    "debug": false
  "domain": "",
  "tags": [],
  "use_openid": true,
  "openid_options": {
    "providers": [
        "issuer": "https://dex/dex",
        "client_ids": {
          "ZXhhbXBsZS1hcHA=": "default"

@hustshawn Can you share some insights how you verified this?

Why is your token in quotation marks?

It’s basically the configuration on custom headers.
The api definition looks like this

                    "X-Static": "foo",
                    "X-Path": "$tyk_context.path",
                    "X-Remote-Addr": "$tyk_context.jwt_claims_oci"

You can refer to below.

To verify the result, I lunched a local web server as upstream, which the api endpoint target to, and logs the request headers. You will see the request header in that server.

Have you enabled context variables (enable_context_vars)?

Tyk won’t process them without being explicitly enabled

1 Like

Thanks! I didn’t have that.

For the later-comers: //

1 Like

Meanwhile I tested this and found that $tyk_context.jwt_claims_groups does not work, although the JWT contains a groups claim. Instead of the expected value, "$tyk_context.jwt_claims_groups" is returned.

Can you provide more detail please? Maybe an example of what yu are doing? The api definition? Any kind of information that could actually help us replicate it?

Otherwise we can’t help.