Tyk Gateway (Open Source) + Keycloak (OIDC) Issue

Hello everyone,
I am trying to set up Tyk gateway with Keycloak as OIDC provider. I have been following the documentation to create the realm and client in my keycloak.

I am hosting the tyk gateway at localhost:8080 and keycloak server at localhost:9000.
For keycloak, I am using “tyk-test” realm and “keycloak-jwt” as ID for the client.

These are my configurations for the tyk gateway:

./app/oidc-protected.json

{
  "name": "OIDC",
  "api_id": "3",
  "org_id": "tyk-test",
  "version_data": {
    "not_versioned": true,
    "versions": {
      "Default": {
        "name": "Default",
        "use_extended_paths": true
      }
    }
  },
  "use_openid": true,
  "openid_options": {
    "providers": [
      {
        "issuer": "http://localhost:9000/auth/realms/tyk-test",
        "client_ids": {
          "a2V5Y2xvYWstand0": "admin"
        }
      }
    ],
    "segregate_by_client": false
  },
  "proxy": {
    "listen_path": "/get",
    "target_url": "http://httpbin.org/",
    "strip_listen_path": true
  },
  "active": true
}

The admin policy is as follows:
.policies/policies.json

{
  "admin": {
    "rate": 1000,
    "per": 1,
    "quota_max": 100,
    "quota_renewal_rate": 60,
    "access_rights": {
      "3": {
        "api_name": "OIDC",
        "api_id": "3",
        "versions": ["Default"]
      }
    },
    "org_id": "tyk-test",
    "hmac_enabled": false
  }
}

I was able to genearate the jwt tokens similar to the documentation.

However, when I try to access the route /get (with the bearer token), I keep getting the error:

{
  "error": "Key not authorised"
}

Here are the error-logs from my docker:

tyk-gateway  | time="Jul 10 14:57:10" level=warning msg="JWT Invalid" api_id=3 api_name=OIDC error="Validation error. Validation error. No provider was registered with issuer: http://localhost:9000/realms/tyk-test" mw=OpenIDMW org_id=tyk-test origin=192.168.128.1 path=/get
tyk-gateway  | time="Jul 10 14:57:10" level=warning msg="Attempted access with invalid key." api_id=3 api_name=OIDC key="****JWT]" mw=OpenIDMW org_id=tyk-test origin=192.168.128.1 path=/get

I tried searching around the forums for similar issues, but I haven’t found much help.

Could it be that my json configurations are not correct or missing something?
I have been stuck at this issuse for two days so any help is welcome.

hi bump for this. Still having the same error

You seem to be using policy file name instead of policy path. Can you share your gateway version for us to replicate?

Hi, i am using tyk-gateway:v5.1.0. Here is the reference github tyk-gateway

Well this indicates that there isn’t a client app on the IDP or the client requested isn’t present. You may want to check your IDP

That aside, I would suggest you implement JWT auth instead of OIDC auth as indicated in our doc.

Considering you are already following the JWT and Key Cloak with Tyk doc, the next steps would be to ensure your policies are loaded on the gateway

You can check the gateway logs on startup or reload or use the REST API /tyk/policies to confirm if it’s loaded.

time="Jul 16 20:01:07" level=info msg="Policies found (1 total):" prefix=main
time="Jul 16 20:01:07" level=debug msg=" - admin" prefix=main

If you can’t see the policy loaded, you may want to check your config setup since you are using the classic policy file

  "policies": {
    "policy_source": "file",
    "policy_record_name": "/opt/tyk-gateway/policies/policies.json"
  }, 

Policy Snippet (Ensure these properties are present

"admin": {
    "id": "admin",
    "auth_type": "jwt"
  }

API Definition snippet

"use_keyless": false,
  "enable_jwt": true,
  "auth_configs": {
    "jwt": {
      "disable_header": false,
      "auth_header_name": "Authorization",
      "cookie_name": "",
      "name": "",
      "validate_signature": false,
      "use_param": false,
      "signature": {
        "algorithm": "",
        "header": "",
        "use_param": false,
        "param_name": "",
        "secret": "",
        "allowed_clock_skew": 0,
        "error_code": 0,
        "error_message": ""
      },
      "use_cookie": false,
      "param_name": "",
      "use_certificate": false
    }
  },
  "jwt_skip_kid": false,
  "jwt_signing_method": "rsa",
  "jwt_source": "<base-64-endcoding-of-your-JWKS-url>",
  "jwt_identity_base_field": "sub",
  "jwt_policy_field_name": "pol",
  "jwt_default_policies": [
    "admin"
  ]

Let us know how it goes

Thanks for the suggestion. I have appended the snippets to my definitions and tyk conf. I can now see my policy from /tyk/policies route.

However, I am still getting the key not authorized error (although this time, the error messages are different. (I assume they are originating from JWKS url)

For the JWKS url, i used the base64 encoded url from my keycloak: “http://localhost:9000/realms/tyk-test/protocol/openid-connect/certs” (obtained from my .well-known/openid-configuration path from keycloak)

Here is the api definition

{
  "name": "OIDC",

  "use_keyless": false,
  "enable_jwt": true,
  "auth_configs": {
    "jwt": {
      "disable_header": false,
      "auth_header_name": "Authorization",
      "cookie_name": "",
      "name": "",
      "validate_signature": false,
      "use_param": false,
      "signature": {
        "algorithm": "",
        "header": "",
        "use_param": false,
        "param_name": "",
        "secret": "",
        "allowed_clock_skew": 0,
        "error_code": 0,
        "error_message": ""
      },
      "use_cookie": false,
      "param_name": "",
      "use_certificate": false
    }
  },
  "jwt_skip_kid": false,
  "jwt_signing_method": "rsa",
  "jwt_source": "aHR0cDovLzAuMC4wLjA6OTAwMC9yZWFsbXMvdHlrLXRlc3QvcHJvdG9jb2wvb3BlbmlkLWNvbm5lY3QvY2VydHM=",
  "jwt_identity_base_field": "sub",
  "jwt_policy_field_name": "pol",
  "jwt_default_policies": ["admin"],

  "auth": {
    "use_openid": true,
    "openid_options": {
      "providers": [
        {
          "issuer": "http://0.0.0.0:9000/realms/tyk-test",
          "client_ids": {
            "dHlrLWNsaWVudA==": "admin"
          }
        }
      ],
      "segregate_by_client": false
    }
  },
  "proxy": {
    "listen_path": "/get",
    "target_url": "http://httpbin.org/",
    "strip_listen_path": true
  },
  "version_data": {
    "not_versioned": true,
    "versions": {
      "Default": {
        "name": "Default"
      }
    }
  }
}

I am gettting this connection refused error in the logs:

tyk-gateway  | time="Jul 17 03:33:23" level=error msg="Failed to get resource URL" error="Get \"http://0.0.0.0:9000/realms/tyk-test/protocol/openid-connect/certs\": dial tcp 0.0.0.0:9000: connect: connection refused"
tyk-gateway  | time="Jul 17 03:33:23" level=info msg="Failed to decode JWKs body. Trying x5c PEM fallback." api_id= api_name=OIDC error="Get \"http://0.0.0.0:9000/realms/tyk-test/protocol/openid-connect/certs\": dial tcp 0.0.0.0:9000: connect: connection refused" mw=JWTMiddleware org_id= origin=192.168.208.1 path=/get
tyk-gateway  | time="Jul 17 03:33:23" level=error msg="Failed to get resource URL" api_id= api_name=OIDC error="Get \"http://0.0.0.0:9000/realms/tyk-test/protocol/openid-connect/certs\": dial tcp 0.0.0.0:9000: connect: connection refused" mw=JWTMiddleware org_id= origin=192.168.208.1 path=/get
tyk-gateway  | time="Jul 17 03:33:23" level=error msg="Couldn't get token" api_id= api_name=OIDC error="Get \"http://0.0.0.0:9000/realms/tyk-test/protocol/openid-connect/certs\": dial tcp 0.0.0.0:9000: connect: connection refused" mw=JWTMiddleware org_id= origin=192.168.208.1 path=/get
tyk-gateway  | time="Jul 17 03:33:23" level=info msg="Attempted JWT access with non-existent key." api_id= api_name=OIDC mw=JWTMiddleware org_id= origin=192.168.208.1 path=/get
tyk-gateway  | time="Jul 17 03:33:23" level=error msg="JWT validation error" api_id= api_name=OIDC error="Get \"http://0.0.0.0:9000/realms/tyk-test/protocol/openid-connect/certs\": dial tcp 0.0.0.0:9000: connect: connection refused" mw=JWTMiddleware org_id= origin=192.168.208.1 path=/get

Thanks for the help

This means Tyk couldn’t reach your Key Cloak instance. The error is typically caused by the target not being available to receive the request or a network issue.

As we’ve seen on this community before, the connect: connection refused error could be related to docker. So you might want to try replacing 0.0.0.0 with host.docker.internal or the private IP of your machine.

Hi, so instead of using the localhost, I replaced it the docker address: 172.17.0.1
I replaced all url and encodings for them to this new ip address.
Now I am having a slightly different problem. When I tried to access the protected route /get with the jwt token, I just keep seeing the loading screen.
This is the error log:

> tyk-gateway  | time="Jul 19 13:03:08" level=error msg="Failed to get resource URL" error="Get \"http://172.17.0.1:9000/realms/tyk-test/protocol/openid-connect/certs\": dial tcp 172.17.0.1:9000: connect: connection timed out"
> tyk-gateway  | time="Jul 19 13:03:08" level=info msg="Failed to decode JWKs body. Trying x5c PEM fallback." api_id=2 api_name=OIDC error="Get \"http://172.17.0.1:9000/realms/tyk-test/protocol/openid-connect/certs\": dial tcp 172.17.0.1:9000: connect: connection timed out" mw=JWTMiddleware org_id= origin=172.18.0.1 path=/get

A timeout error means that a connection could not be established within an allotted time (typically between 30 to 60 seconds)

You want to check that the destination is active and listening. You can use netstat and telnet command for this.

Since you are using docker, you want to ensure there are no network issues based on your setup.