Rate Limiting not Working when be Applied to Multiple Policies

Hey there,

We are using a Golang plugin to do the auth for tyk. However it causes problems when using multiple policies.

We’re using same keys for different APIs. However, for example, if we just use one API key to access one of our APIs (alpha-api), then send a request to another API (beta-api) endpoint (using the same key), a 403 “disallowed” error will pop up. After the cache is cleared (for us 5 minutes), then the key can be used to access the beta-api

We realized it’s because of our policies settings:

{
    "alpha-api": {
        "access_rights": {
            "apple-api": {
                "allowed_urls": [],
                "api_id": "alpha-api",
                "api_name": "alpha-api",
                "versions": [
                    "Default"
                ]
            }
        },
        "active": true,
        "name": "Default policy for alpha-api",
        "org_id": "1",
        "per": 60,
        "rate": 300,
        "state": "active"
    },
    "beta-api": {
        "access_rights": {
            "beta-api": {
                "allowed_urls": [],
                "api_id": "beta-api",
                "api_name": "beta-api",
                "versions": [
                    "Default"
                ]
            }
        },
        "active": true,
        "name": "Default policy for beta-api",
        "org_id": "1",
        "per": 60,
        "rate": 300,
        "state": "active"
    }
}

So our solution is to apply multiple policies when do the caching in Golang auth plugin:

object.Session = &coprocess.SessionState{
		LastUpdated:         time.Now().String(),
		IdExtractorDeadline: extractorDeadline,
		Metadata: map[string]string{
			"token":       authKey,
		},
		// the default policy id for an api is its api id
		//ApplyPolicies: []string{apiId},
		ApplyPolicies: []string{"alpha-api", "beta-api"},
	}

This solves the disallowed 403 error. however, the rate limits set in the polices file are messed up. As you can see in the policies file example above, the rate is set to 300. But in our test, in one minute, after I sent 100 requests to alpha-api then 200 requests to beta-api, the rate limits takes effect and I get 429 error.

I think it might be a bug for supporting multiple policies, or do you have any better ideas to solve this? Thank you!

Hi @byu,

I’m not able to reproduce this issue. What is your gateway version please? I just tested on v4.0.3

Hey @Ubong thank you for getting back to me!

I’m using v3.2.3. Just tried v4.0.3 but the results (both of the rate limiting issue and disallowed issue) are the same. To make sure we are doing the same:

  • The policies file is the same as the above
  • Both APIs (alpha and beta) are using Authorization header to deliver api key. And in the Golang auth plugin, before putting the session state into cache, both policies are applied to it
  • Global rate limits are set to 0, 0, aka no rate limits. So only the API rate limiting is taking effect here
  • For either of the APIs, rate limit is set to 300 reqs per 60 sec. But when using the same key, after sending 300 reqs to alpha-api, beta-api is rate limited as well

Could you check that the word apple-api inside the policies is not the culprit?

I haven’t tried with a golang plugin but I don’t have any issues using a regular key. From redis I can observe different bucket counters for the different APIs

Hi @byu,

We’ve reproduced this and we find it’s because of the missing “id” field in your policies setting. There should be an id field and this should be the same name/reference as the policy. i.e your policy file should be

{
    "alpha-api": {
        "access_rights": {
            "apple-api": {
                "allowed_urls": [],
                "api_id": "alpha-api",
                "api_name": "alpha-api",
                "versions": [
                    "Default"
                ]
            }
        },
        "active": true,
        "name": "Default policy for alpha-api",
        "id": "alpha-api",
        "org_id": "1",
        "per": 60,
        "rate": 300,
        "state": "active"
    },
    "beta-api": {
        "access_rights": {
            "beta-api": {
                "allowed_urls": [],
                "api_id": "beta-api",
                "api_name": "beta-api",
                "versions": [
                    "Default"
                ]
            }
        },
        "active": true,
        "name": "Default policy for beta-api",
        "id": "beta-api",
        "org_id": "1",
        "per": 60,
        "rate": 300,
        "state": "active"
    }
}

Still worth checking the apple-api in your access rights section.

Hope this helps.

Hi @Olu! Oh sorry it’s a misspelling :sweat_smile:. And thank you for mentioning redis is using different bucket counters for different APIs!

@Ubong Sorry for my late reply! Wooo thank you so much for pointing it out! It’s working now!

1 Like