News KrakenD Enterprise v2.6 released with OpenTelemetry, FIPS-140, gRPC server and more

Enterprise Documentation

Recent changes

You are viewing a previous version of KrakenD Enterprise Edition (v1.3) , go to the latest version

API Key authentication using RBAC

Document updated on Nov 10, 2020

The API key authentication enables a Role-Based Access Control (RBAC) mechanism by reading the Authorization header of incoming requests. For all your desired endpoints, KrakenD rejects requests from users that do not provide a valid key or are trying to access a resource with insufficient permissions for the user’s role.

The authentication is granular and works per-endpoint, meaning that you can combine public endpoints and private endpoints in the same configuration.

The API Key middleware requires you to declare at least two different blocks of configuration:

  1. The declaration of all known users and roles, placed at the root’s extra_config middleware section.
  2. The association of which endpoints are protected, placed at each endpoint.

Declaring API Key users and roles

The first block of configuration declares all API Keys with roles recognized by the system. The API keys middleware configuration requires a single keys attribute with a list of objects declaring each client’s key and roles. The configuration is as follows:

{
  "version": 2,
  "extra_config": {
    "github_com/devopsfaith/krakend-apikeys": {
      "keys": [
        {
          "key": "4d2c61e1-34c4-e96c-9456-15bd983c5019",
          "roles": ["role1", "role2"],
          "@description": "ACME Inc."
        },
        {
          "key": "58427514-be32-0b52-b7c6-d01fada30497",
          "roles": ["role1","role3"],
          "@description": "Administrators Inc."
        }
      ]
    }
  }
}
The configuration attributes are:

  • keys list: A list of objects containing the following attributes:
    • key string: The secret key used by the client to access the resources.
    • role list: All the roles this user has. See roles as all the identifying labels that belong to this client.

It is also shown in the example a @description attribute to help you identify who this key belongs to. This attribute is fake and unrecognized by the middleware. Stay with the idea that you could have any other name or value you need for better administration (as long as its name does not match the ones above).

Protecting endpoints by API Key

Now that you have all users and roles declared, it’s time to reference them in the endpoints. For all the endpoints needing API Key validation, you need to include the middleware’s namespace (github_com/devopsfaith/krakend-apikeys) in its extra_config. Any endpoints not having the namespace are not considered to be API Key protected. The endpoints could look like this:

{
  "endpoint": "/admin",
  "backend": [
    {
      "url_pattern": "/__debug/admin",
      "host": [
        "http://localhost:8080"
      ]
    }
  ],
  "extra_config": {
    "github_com/devopsfaith/krakend-apikeys": {
      "roles": [
        "admin"
      ]
    }
  }
}

As you can see, you only need to write which roles are allowed to access the endpoint. API Keys not having the right role or unauthenticated requests will receive a 401 Unauthorized .

  • roles: The list of all the roles that are allowed to access this resource. Values must match its declaration.

Here is a full example of two different API Keys that can access three different endpoints:

{
  "version": 2,
  "extra_config": {
    "github_com/devopsfaith/krakend-apikeys": {
      "keys": [
        {
          "@description": "ACME Inc.",
          "key": "4d2c61e1-34c4-e96c-9456-15bd983c5019",
          "roles": ["user", "whitelabel"]
        },
        {
          "@description": "Administrators Inc.",
          "key": "58427514-be32-0b52-b7c6-d01fada30497",
          "roles": ["admin", "user"]
        }
      ]
    }
  },
  "endpoints": [
    {
      "endpoint": "/public",
      "backend": [
        {
          "url_pattern": "/__debug/public",
          "host": [
            "http://localhost:8080"
          ]
        }
      ]
    },
    {
      "endpoint": "/admin",
      "backend": [
        {
          "url_pattern": "/__debug/admin",
          "host": [
            "http://localhost:8080"
          ]
        }
      ],
      "extra_config": {
        "github_com/devopsfaith/krakend-apikeys": {
          "roles": [
            "admin"
          ]
        }
      }
    },
    {
      "endpoint": "/user",
      "backend": [
        {
          "url_pattern": "/__debug/user",
          "host": [
            "http://localhost:8080"
          ]
        }
      ],
      "extra_config": {
        "github_com/devopsfaith/krakend-apikeys": {
          "roles": [
            "user"
          ]
        }
      }
    }
  ]
}

Authenticating requests using API Key

The final step is to make requests again KrakenD adding the Authorization: Bearer header, or using Basic authentication. The value inside the header represents the API key defined in the configuration.

Using Bearer

The format of the header is as follows:

Authorization: Bearer YOUR-KEY

For instance, having declared in the configuration a key 4d2c61e1-34c4-e96c-9456-15bd983c5019 that should be capable of seeing /foo, you should make a call like this:

Passing the key with Bearer 
$curl -H'Authorization: Bearer 4d2c61e1-34c4-e96c-9456-15bd983c5019' http://localhost:8080/foo
{"message":"pong"}

Using Basic authentication

Another way of authenticating is using Basic authentication. The key needs to be encoded in base64:

Authorization: Basic base64(YOUR-KEY:)

Notice that the encoding of the key contains an ending : (this prevents your client to be asked for a password).

Using the same key in the previous example:

Convert Key to base64 
$echo "4d2c61e1-34c4-e96c-9456-15bd983c5019:" | base64
NGQyYzYxZTEtMzRjNC1lOTZjLTk0NTYtMTViZDk4M2M1MDE5Cgo=
Basic authentication 
$curl -H"Authorization: Basic NGQyYzYxZTEtMzRjNC1lOTZjLTk0NTYtMTViZDk4M2M1MDE5Ogo=" http://localhost:8080/foo
{"message":"pong"}

Or just using your client regular basic auth which will encode automatically (again, notice the : at the end of the key):

Basic authentication 
$curl -i --user 4d2c61e1-34c4-e96c-9456-15bd983c5019: http://localhost:8080/foo
{"message":"pong"}

In case you forget the colon : you’ll be prompted for the password (when there isn’t):

Basic authentication 
$curl -i --user 4d2c61e1-34c4-e96c-9456-15bd983c5019 http://localhost:8080/user
Enter host password for user '4d2c61e1-34c4-e96c-9456-15bd983c5019':
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
X-Krakend: Version
X-Krakend-Completed: true
Date: Tue, 10 Nov 2020 17:37:09 GMT
Content-Length: 18

{"message":"pong"}

Complete API Key configuration example

The following configuration snippet is fully functional. Run KrakenD with the debug flag (krakend run -d) to test it locally, as it uses itself as a backend. Explanation below:

{
    "version": 2,
    "extra_config": {
        "github_com/devopsfaith/krakend-apikeys": {
            "keys": [
                {
                    "@description": "ACME Inc.",
                    "key": "4d2c61e1-34c4-e96c-9456-15bd983c5019",
                    "roles": [
                        "user",
                        "whitelabel"
                    ]
                },
                {
                    "@description": "Administrators Inc.",
                    "key": "58427514-be32-0b52-b7c6-d01fada30497",
                    "roles": [
                        "admin",
                        "user"
                    ]
                }
            ]
        }
    },
    "endpoints": [
        {
            "endpoint": "/public",
            "backend": [
                {
                    "url_pattern": "/__debug/public",
                    "host": [
                        "http://localhost:8080"
                    ]
                }
            ]
        },
        {
            "endpoint": "/admin",
            "backend": [
                {
                    "url_pattern": "/__debug/admin",
                    "host": [
                        "http://localhost:8080"
                    ]
                }
            ],
            "extra_config": {
                "github_com/devopsfaith/krakend-apikeys": {
                    "roles": [
                        "admin"
                    ]
                }
            }
        },
        {
            "endpoint": "/user",
            "backend": [
                {
                    "url_pattern": "/__debug/user",
                    "host": [
                        "http://localhost:8080"
                    ]
                }
            ],
            "extra_config": {
                "github_com/devopsfaith/krakend-apikeys": {
                    "roles": [
                        "user"
                    ]
                }
            }
        }
    ]
}

In this example we have enabled two different API users. One with key 4d2c61e1-34c4-e96c-9456-15bd983c5019 (let’s say a customer of ACME Inc.) and another one with the key 58427514-be32-0b52-b7c6-d01fada30497 (an administrator of my company).

Both users share the role users and they can access all the protected endpoints as this role is included. Nevertheless, the /admin endpoint is reachable by the administrator only, as the role “admin” is required.

The endpoint /public is always accessible, with or without the Authorization header as it does not include the API key middleware configuration.

And now some sample interactions:

Accessing the /user endpoint with a valid user (Bearer) 
$curl -H'Authorization: Bearer 4d2c61e1-34c4-e96c-9456-15bd983c5019' http://localhost:8080/user
{"message":"pong"}
Accessing the /user endpoint (Basic) 
$curl -i --user 4d2c61e1-34c4-e96c-9456-15bd983c5019: http://localhost:8080/user
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
X-Krakend: Version
X-Krakend-Completed: true
Date: Tue, 10 Nov 2020 17:07:46 GMT
Content-Length: 18

{"message":"pong"}
Accessing the /admin endpoint with a non-admin user 
$curl -iG -H'Authorization: Bearer 4d2c61e1-34c4-e96c-9456-15bd983c5019' http://localhost:8080/admin

HTTP/1.1 401 Unauthorized
Date: Tue, 10 Nov 2020 17:01:03 GMT
Content-Length: 0
Accessing the /user endpoint with an invalid key 
$curl -iG -H'Authorization: Bearer INVALID-API-KEY' http://localhost:8080/user

HTTP/1.1 401 Unauthorized
Date: Tue, 10 Nov 2020 16:59:35 GMT
Content-Length: 0
Accessing the /public endpoint 
$curl http://localhost:8080/public
{"message":"pong"}
Scarf

Unresolved issues?

The documentation is only a piece of the help you can get! Whether you are looking for Open Source or Enterprise support, see more support channels that can help you.