Basic policy question

Hi

I have a very basic question about Tyk policies.

I currently issue a client-id / secret pair by setting the API authentication to auth token. My plan is to have multiple auth tokens to the same API. So for example:

  1. I have customer A sign up for my services. I will issue them with client-id AAA to access API yyy
  2. I have customer B sign up for my services. I will issue them with client-id BBB to access API yyy

I would like to control access to API YYY in the following manner:

  1. client-id AAA can access API YYY but with rate limit of 1000 calls / 24 hours
  2. client-id BBB can access API YYY but with rate limit of 2000 calls / 24 hours

Is this possible in Tyk? Any guidelines on how this can be achieved?

Obviously I would have multiple APIs in the future (API YYY, API ZZZ, API KKK etc) all following the pattern above.

Thanks.

Hi @Jesum_Yip - this is certainly possible.

I’d recommend using our access control policies.

You can use policies with the open source gateway, or you can use the GUI in the dashboard or cloud to manage policies if you prefer.

For the example above, setup policy 1, perhaps called “silver policy”, specify in the policy that it provides access to API YYY, limited to a quota of 1,000 calls per 24 hours.
Now create a second policy, “gold policy”, with the same access rights, but with a quota of 2,000 calls per 24 hours.
Now provide access to those policies to whichever clients you wish.

You can add other dimensions of control via a policy also, and it makes it simple to change rights to every client you have, just by changing the policy, instead of reissuing keys for every client.

If you haven’t already, I strongly recommend following our simple, 7 stage ‘getting started with Tyk API Management’ guide. Stage 4 - security policies covers access control policies and introduces the concept in a quick and simple manner. You can do it all in the time it takes to drink a coffee.

Hope that helps

James

Thanks James, I will take a look.

However, that only solves part of the problem for me. I have a super complicated scenario that I am trying to build and it’s got problems at every step. It involves Auth0 → Tyk → custom built API layer → Snowflake. We would like to secure everything using JWT tokens.

One of the problems we are facing now is that Snowflake can only accept a SINGLE value in the scope / scp claim of a JWT token. If you put more than one value in it (either space separated or an array), Snowflake will reject the token.

Does anyone here have experience with Auth0 + Tyk combination?

We have a worked example of Tyk and Auth0 in our docs, have you followed that through?

We started supporting Auth0 in 2016, so it’s well used by the community and there are many posts on the topic, perhaps one of them will help with your scenario? This one covers machine to machine JWT bearers from AuthO

Well the main issue is we can’t figure out how to overcome some limitations in snowflake and the auth0 sdk that we are using in our web app.

Snowflake only accepts a single value in the scope claim. Auth0’s sdk only accepts a hard coded value for audience and scope. If you leave scope blank when making the request to auth0, you end up with a jwt that has all the scopes defined for that specific audience. This means I need to create multiple versions of my web app each with a different hard coded value so that each web app instance is specific to one customer.

And snowflake would need multiple oauth integrations to be done - one for each customer - to auth0, which is also really silly.

I am just wondering if there is a way to get tyk to be the one to issue jwt tokens and do the manipulations at tyk. This way we can integrate snowflake to tyk as the oauth provider. And when the web portal passes the auth0 token to tyk, tyk knows based on the api being called to drop all non-relevant scopes.

Interesting problem! I don’t know how to help with that, but perhaps someone else on the community will have some suggestions. Please do keep the thread updated if you figure it out, it could help other users with similar plans.

Jesum,

you could certainly mint JWT tokens in Tyk, transparently to the user, after it authenticates the user with their auth0 token.

You would simply write a custom plugin that would generate a new JWT token and sign it with a shared key or private key that Snowflake will look for.

But this means that Auth0 is essentially just authentication layer. Not sure why Snowflake has the 1 scope limitation, but you can consider this approach.

1 Like

Hi, I haven’t tried it myself and only googled their docs - where can I read about this requirement?

We made some progress but we’re still hitting issues.

So our flow now is :

  1. User logs in to web application.
  2. As part of the log in flow, web application redirects to Auth0 to complete the authentication process.
  3. Auth0 returns a JWT token to web application.

That’s pretty standard so far.

  1. User triggers a function in Web application that requires data from Snowflake
  2. Web application has to make another call to Auth0 to generate another JWT token with a single scope value.
  3. Web application then calls Tyk passing the JWT token as payload.
  4. Tyk applies the necessary Tyk policy based on the JWT token contents (easy enough to do in Tyk).
  5. Tyk calls a data access layer we built and passes along the JWT token as payload.
  6. Data access layer calls Snowflake using that same JWT token inserted into the Snowflake connection object as a member.

The issue is in step #5. There are 2 general methods to call Auth0 a second time for the same user context to generate another JWT token:

  1. Use a refresh token. This works, tested, but there are rate limits applied by Auth0 for the refresh token endpoint (50 calls per minute with bursts of max 500; see Rate Limit Policy). I can see how we can easily hit this limit if our web application is popular (heck, today, it’s the web application, tomorrow it can be the web application and 3 other mobile apps). So this is just going to hit a scalability wall in the future.
  2. Use silent authentication in Auth0 (Configure Silent Authentication). But, because we also use MFA to protect our Auth0 identities, it will trigger a mfa_required error when we use this. We also don’t want the user to be prompted by MFA requirements multiple times while using the web application. Hence, we have to configure an Auth0 rule to require MFA ONLY ONCE per user session ( Sessions). This seems like the better approach.

As an ancillary, we also noticed the Snowflake library we use for authentication takes a “role” parameter. The “role” parameter is directly correlated to the values in the scope claim of the JWT token. We now face another issue. If we have a JWT token with 3 scope values, e.g.:

scope:read:app1 write:app2 snowflakerole

And in our connection to Snowflake, we put “snowflakerole” into the “role” parameter, Snowflake still throws an error saying the role does not exist in the token. We suspect the problem is due to the way the “scope” claim is formatted. We do know that if we specify role = “snowflakerole” , and the token has “scope:snowflakerole” ONLY, the connection succeeds.

Auth0 formats the scope claim as a space-separated list. Snowflake, we suspect, can only accept an array (this is a suspicion at this point, so can’t blame Snowflake yet lol).

Furthermore, RFC6749 para 3.3, RFC 8693 para 4.2, and RFC7662 para 2.2 all state that it should be space-separated. However, we have seen in the wild some systems using an array for multiple scope values.

We have opened a support ticket with Snowflake to clarify this question. I will see if there is a way we can test this theory (still thinking because it requires Auth0 to forcibly generate multiple scope claims as an array).

While we have a working solution, it would be nice if we can get Snowflake to do this because it means our web application no longer needs to deal with multiple Auth0 calls:

  1. I pass a role parameter to Snowflake to specify what role I require when I am connecting.
  2. I pass a JWT token with multiple values in the scope claim. One of the values corresponds to #1.
  3. Snowflake parses the scope claim and correctly finds the role being requested and allows the connection.

By the way, these multiple calls to Auth0 must be done with custom code - it’s not something supported by the Auth0 libraries in the wild as far as we can tell. The libraries do support automatically refreshing expired tokens but this happens in the background and its not publicly exposed as a method we can call while specifying a different scope claim. The automatic refresh gets you the same JWT token every time. So it’s more work we are trying to avoid if we can - prefer to re-use libraries than to write custom code.

One other possible solution is for us use Tyk as an OAuth provider. This means all backend systems that are OAuth compliant will be integrated with Tyk for the OAuth flow. However, we will still keep Auth0 as our IdP (so some functions like SCIM integration, SSO, etc will still be kept in Auth0), but only outsource the OAuth negotiation specifically to Tyk. I don’t know if Tyk can do this? I do know that some well known OAuth endpoints don’t exist in the Tyk gateway (I tested and I only see “NOT FOUND” appearing in my browser - so i think Tyk is treating these endpoints as published API endpoints that Tyk is proxying).

We also thought of whether it’s possible for Tyk to strip away values from the JWT scope claim and only keep the relevant one for Snowflake but this is going to fundamentally break the whole reason why the JWT token is signed in the first place - so that it is not modified. I suppose the suggestion from sedky would be the way to go - a custom plugin. A shared key implies HMAC signing algorithm - I don’t believe Snowflake supports this. That means I need to maintain a separate set of private/public keys - which comes with its own operational overhead (e.g. key rotation!).

You could create a feature request if you can help us create a generic user flow. I would love for Tyk to validate jwt and sign a new one OOTB.

Hmmm yeah, the only catch is it means you have to allow all applications that recognize the JWT to be able to perform token validation against Tyk (i.e. to ensure the token was really issued by Tyk). This means two possibilities:

  1. Tyk becomes full-fledge OAuth provider exposing all the well-known OAuth endpoints, it needs key management, certificates, etc.; or
  2. Tyk can only support the HMAC protocol for token verification, which limits its utility.

FYI Snowflake support has come back to say they apparently support a scope claim with multiple space-separated values. This is going to get interesting because according to Configure Custom Authorization Servers for External OAuth | Snowflake Documentation,

:slight_smile:

I have another question: when you are performing policy to claim mapping, can you use regular expressions to evaluate the claim?

and what happens if for example “mycustomscopeclaim” contains this:

mycustomscopeclaim: abc123 def567 xyz999

will Tyk correctly find def567 if it is listed under “Scope to policy mapping” ? Can I use regular expressions or wildcards to define the claim? For example “def*” will match def567?

Turns out wildcards don’t work. Tyk needs a perfect match.

We do have a workaround in mind that is a compromise in our authorization model (security is weaker) that we will have to implement.

Hi,
About the scope list - yeh, that’s the doc I sent you in the beginning. :slight_smile:

About regexp for matching scopes - again, really great idea - would you mind creating an issue with your use case? and maybe even PR for this line :upside_down_face:? shouldn’t be too complicated (here we do regex pattern matching for url rewrite)

I don’t know how to code in Go :frowning:

I will put in a request by contacting some internal folks. Thanks!

1 Like