Skip to main content

How To Create A Security Policy For Path Access Control With Tyk API Gateway

· 6 min read
Simon Pears
Python developer and technical writer

How to create a security policy to enable fine grained path access control for an API managed by Tyk.

Overview

An organisation can protect and serve many APIs to different consumers using access keys. An access key contains restrictions relating to rate limits, fine grained path access control etc.

If an organisation has many clients then replicating the access control limitations can become cumbersome. Subsequently, it is possible to assign one or more policies to a key. The access limitations defined in the policy are inherited by the key.

This guide explains how to perform the following:

  • Define a policy with fine grained access controls for a path.
  • Assign the policy to a key.
  • Use the key to access the API to verify that a forbidden response is returned for an API request that is not granted access by the policy.

Getting Started

Before a policy is created, an API and key must exist for an organisation.

Create The API For The Acme Organisation

Firstly, we will create an API for the Acme Organisation. This API will forward requests upstream to http.bin.

Issue the following POST request to tyk/apis:

curl \
--header 'Content-Type: application/json' \
--header 'x-tyk-authorization:foo' \
--data \
'{
"name": "acme-api",
"slug": "acme-api",
"api_id": "acme-api",
"org_id": "acme",
"use_keyless": false,
"auth": {
"auth_header_name": "Authorization"
},
"definition": {
"location": "header",
"key": "x-api-version"
},
"version_data": {
"not_versioned": true,
"versions": {
"Default": {
"name": "Default",
"use_extended_paths": true
}
}
},
"proxy": {
"listen_path": "/acme/",
"target_url": "http://echo.tyk-demo.com:8080/",
"strip_listen_path": true
},
"active": true
}' \
'http://localhost:8080/tyk/apis'

Before continuing, issue a reload request to the Tyk application gateway, to load the API.

Remember to include the X-Tyk-Authorization header with the corresponding configured tyk api key value. For example:

curl --location 'http://localhost:8080//tyk/reload/' \
--header 'Accept: application/json' \
--header 'X-Tyk-Authorization:foo'

Create A Policy To Control Which URLs Are Allowed

A policy can be created to specify the allowed URLs or paths for an API. Lets create a policy that only allows GET and POST request methods to paths beginning with acme/

Issue the following POST request to tyk/policies:

curl \
--header 'Content-Type: application/json' \
--header 'x-tyk-authorization:foo' \
--data \
'{
"id": "acme-api-policy",
"name": "Acme path access policy [get, post]",
"org_id": "acme",
"access_rights": {
"acme-api": {
"allowed_urls": [
{
"url": "/acme/(.*)",
"methods": ["GET", "POST"]
}
],
"api_id": "acme-api",
"api_name": "acme-api",
"versions": ["Default"]
}
},
"active": true,
"rate": 100,
"per": 1,
"quota_max": 10000,
"quota_renewal_rate": 3600,
"tags": ["acme policy"]
}' \
'http://localhost:8080/tyk/policies'

Please note that the id and org_id fields are required. Furthermore, the org_id should match the org_id of the API that is the target of the policy.

The policy above will only allow GET and POST requests for the acme API paths beginning with /acme.

Before continuing, issue a reload request to the Tyk application gateway.

Remember to include the X-Tyk-Authorization header with the corresponding configured tyk api key value. For example:

curl --location 'http://localhost:8080//tyk/reload/' \
--header 'Accept: application/json' \
--header 'X-Tyk-Authorization:foo'

Create An Access Key That Applies The Policy

Finally, the policy can be applied to an access key for the API.

Issue the following request to create a key for the acme API. The key will apply the new policy.

curl \
--header 'Content-Type: application/json' \
--header 'x-tyk-authorization:foo' \
--data '{
"allowance": 1000,
"rate": 1000,
"per": 60,
"expires": -1,
"quota_max": -1,
"quota_renews": 1406121006,
"quota_remaining": 0,
"quota_renewal_rate": 60,
"access_rights": {
"acme-api": {
"api_name": "acme-api",
"api_id": "acme-api"
}
},
"org_id": "acme",
"basic_auth_data": {
"password": "",
"hash_type": ""
},
"hmac_enabled": false,
"hmac_string": "",
"is_inactive": false,
"apply_policies": [
"acme-api-policy"
],
"monitor": {
"trigger_limits": []
}
}' \
'http://localhost:8080/tyk/keys'

A key should be given in the response payload:

{
"key": "acme32e8b18e3ffe4b6b9494f2e84716ea2e",
"status": "ok",
"action": "added",
"key_hash": "1d111058"
}

When this access key is used in the Authorization header for requests to the API then the policy(s) associated with the key will be enforced. In the example above we have applied the acme-api-policy to the key.

In the subsequent section, we will test that the policy is enforced.

Before doing so, issue a reload request to the Tyk application gateway.

Remember to include the X-Tyk-Authorization header with the corresponding configured tyk api key value. For example:

curl --location 'http://localhost:8080//tyk/reload/' \
--header 'Accept: application/json' \
--header 'X-Tyk-Authorization:foo'

Test It Out

So far, a policy has been created to restrict access to the acme API. Only GET and POST requests can be made to the /acme endpoint.

An access key has been created for the acme API. This key inherits the access control behaviour specified by the security policy.

Now, let us make some request to the acme API using the new access key. In the following examples, ensure that an Authorization header contains the new access key.

First, try and issue a DELETE request to the acme API. For example:

curl --location --request DELETE 'http://localhost:8080/acme/delete' \
--header 'Authorization:acme32e8b18e3ffe4b6b9494f2e84716ea2e'

A 403 forbidden response code should be returned, since a DELETE method is not included in the policy for paths beginning with /acme.

{
"error": "Access to this resource has been disallowed"
}

Now, try and issue a GET request to the acme API:

curl --location 'http://localhost:8080/acme/get' \
--header 'Accept: application/json' \
--header 'Authorization:acme32e8b18e3ffe4b6b9494f2e84716ea2e'

A 200 status response code should be returned.

{
"args": {},
"headers": {
"Accept": "application/json",
"Accept-Encoding": "gzip",
"Authorization": "acme32e8b18e3ffe4b6b9494f2e84716ea2e",
"Host": "httpbin.org",
"User-Agent": "curl/7.79.1",
"X-Amzn-Trace-Id": "Root=1-64230c87-28c89178507ef4c2713b5a13"
},
"origin": "172.19.0.1, <your ip address>, 18.205.37.198",
"url": "http://httpbin.org/get"
}

The security policy that we have created allows GET and POST request methods for paths beginning with /acme. A test has been performed to check that a GET request was forwarded upstream and a successful response was returned. Similarly, a test has been issued to check that a DELETE request has been forbidden by the policy.

Summary

This guide has explained how to create a security policy for an api to enforce fine grained access control to endpoint paths. Furthermore, it has described how to assign a policy to an access key upon creation.

Security policies enable an organisation to control access to APIs managed by the Tyk Gateway. They are useful when there are many access control keys for different API consumers. Subsequently, API access is easier to manage. When the policy is updated it is automatically enforced for all related access keys.