Add key authentication (also sometimes referred to as an API key) to a Service or a Route. Consumers then add their API key either in a query string parameter, a header, or a request body to authenticate their requests.
This plugin can be used for authentication in conjunction with the Application Registration plugin.
Tip: The Kong Gateway Key Authentication Encrypted plugin provides the ability to encrypt keys. Keys are encrypted at rest in the API gateway datastore.
Configuration Reference
This plugin is partially compatible with DB-less mode.
In DB-less mode, you configure Kong Gateway declaratively. Therefore, the Admin API is mostly read-only. The only tasks it can perform are all related to handling the declarative config, including:
- Setting a target's health status in the load balancer
- Validating configurations against schemas
- Uploading the declarative configuration using the
/config
endpoint
Consumers and Credentials can be created with declarative configuration.
Admin API endpoints that do POST, PUT, PATCH, or DELETE on Credentials are not available on DB-less mode.
Enable the plugin on a service
Enable the plugin on a route
Enable the plugin globally
A plugin which is not associated to any service, route, or consumer is considered global, and will be run on every request. Read the Plugin Reference and the Plugin Precedence sections for more information.
Parameters
Here's a list of all the parameters which can be used in this plugin's configuration:
Form Parameter | Description |
---|---|
name
required Type: string |
The name of the plugin, in this case key-auth . |
service.id
Type: string |
The ID of the Service the plugin targets. |
route.id
Type: string |
The ID of the Route the plugin targets. |
enabled
required Type: boolean Default value: true |
Whether this plugin will be applied. |
config.key_names
required Type: array of strings Default value: [apikey]
|
Describes an array of parameter names where the plugin will look for a key. The client must send the
authentication key in one of those key names, and the plugin will try to read the credential from a
header, request body, or query string parameter with the same name.
|
config.key_in_body
required Type: boolean Default value: false
|
If enabled, the plugin reads the request body (if said request has one and its MIME type is supported) and tries to find the key in it. Supported MIME types: |
config.key_in_header
required Type: boolean Default value: true
|
If enabled (default), the plugin reads the request header and tries to find the key in it. |
config.key_in_query
required Type: boolean Default value: true
|
If enabled (default), the plugin reads the query parameter in the request and tries to find the key in it. |
config.hide_credentials
required Type: boolean Default value: false
|
An optional boolean value telling the plugin to show or hide the credential from the upstream service. If |
config.anonymous
optional Type: string |
An optional string (Consumer UUID) value to use as an anonymous Consumer if authentication fails.
If empty (default), the request will fail with an authentication failure |
config.run_on_preflight
required Type: boolean Default value: true
|
A boolean value that indicates whether the plugin should run (and try to authenticate) on |
Case sensitivity
Note that, according to their respective specifications, HTTP header names are treated as
case insensitive, while HTTP query string parameter names are treated as case sensitive.
Kong follows these specifications as designed, meaning that the key_names
configuration values are treated differently when searching the request header fields versus
searching the query string. As a best practice, administrators are advised against defining
case-sensitive key_names
values when expecting the authorization keys to be sent in the request headers.
Once applied, any user with a valid credential can access the Service. To restrict usage to certain authenticated users, also add the ACL plugin (not covered here) and create allowed or denied groups of users.
Usage
Create a Consumer
You need to associate a credential to an existing Consumer object. A Consumer can have many credentials.
In both cases, the parameters are as described below:
parameter | description |
---|---|
username semi-optional |
The username of the Consumer. Either this field or custom_id must be specified. |
custom_id semi-optional |
A custom identifier used to map the Consumer to another database. Either this field or username must be specified. |
If you are also using the ACL plugin and allow lists with this service, you must add the new Consumer to the allowed group. See ACL: Associating Consumers for details.
Create a Key
In both cases, the fields/parameters work as follows:
field/parameter | description |
---|---|
{consumer} |
The id or username property of the Consumer entity to associate the credentials to. |
ttl optional |
The number of seconds the key is going to be valid. If missing, the ttl is unlimited. |
key optional |
You can optionally set your own unique key to authenticate the client. If missing, the plugin will generate one. |
Make a Request with the Key
Make a request with the key as a query string parameter:
$ curl http://kong:8000/{proxy path}?apikey=<some_key>
Note: The key_in_query
parameter must be set to true
(default).
Make a request with the key in the body:
$ curl http://kong:8000/{proxy path} \
--data 'apikey: <some_key>'
Note: The key_in_body
parameter must be set to true
(default is false
).
Make a request with the key in a header:
$ curl http://kong:8000/{proxy path} \
-H 'apikey: <some_key>'
Note: The key_in_header
parameter must be set to true
(default).
gRPC clients are supported too:
$ grpcurl -H 'apikey: <some_key>' ...
About API Key Locations in a Request
Use cases for key locations:
- Recommended: Use
key_in_header
(enabled by default) as the most common and secure way to do service-to-service calls. - If you need to share links to browser clients, use
key_in_query
(enabled by default). Note that query parameter requests can appear within application logs and URL browser bars, which expose the API key. - If you are sending a form with a browser, such as a login form, use
key_in_body
. This option is set tofalse
by default because it’s a less common use case, and is a more expensive and less performant HTTP request.
For better security, only enable the key locations that you need to use.
Disable a Key Location
This example disables using a key in a query parameter:
curl -X POST http://<admin-hostname>:8001/routes/<route>/plugins \
--data "name=key-auth" \
--data "config.key_names=apikey" \
--data "config.key_in_query=false"
Delete a Key
Delete an API Key by making the following request:
$ curl -X DELETE http://kong:8001/consumers/{consumer}/key-auth/{id}
Response:
HTTP/1.1 204 No Content
consumer
: Theid
orusername
property of the Consumer entity to associate the credentials to.id
: Theid
attribute of the key credential object.
Upstream Headers
When a client has been authenticated, the plugin appends some headers to the request before proxying it to the upstream service so that you can identify the Consumer in your code:
X-Consumer-ID
, the ID of the Consumer on KongX-Consumer-Custom-ID
, thecustom_id
of the Consumer (if set)X-Consumer-Username
, theusername
of the Consumer (if set)X-Credential-Identifier
, the identifier of the Credential (only if the consumer is not the ‘anonymous’ consumer)X-Anonymous-Consumer
, will be set totrue
when authentication failed, and the ‘anonymous’ consumer was set instead.
You can use this information on your side to implement additional logic. You can use the X-Consumer-ID
value to query the Kong Admin API and retrieve more information about the Consumer.
Paginate through keys
Paginate through the API keys for all Consumers by making the following request:
$ curl -X GET http://kong:8001/key-auths
Response:
...
{
"data":[
{
"id":"17ab4e95-9598-424f-a99a-ffa9f413a821",
"created_at":1507941267000,
"key":"Qslaip2ruiwcusuSUdhXPv4SORZrfj4L",
"consumer": { "id": "c0d92ba9-8306-482a-b60d-0cfdd2f0e880" }
},
{
"id":"6cb76501-c970-4e12-97c6-3afbbba3b454",
"created_at":1507936652000,
"key":"nCztu5Jrz18YAWmkwOGJkQe9T8lB99l4",
"consumer": { "id": "c0d92ba9-8306-482a-b60d-0cfdd2f0e880" }
},
{
"id":"b1d87b08-7eb6-4320-8069-efd85a4a8d89",
"created_at":1507941307000,
"key":"26WUW1VEsmwT1ORBFsJmLHZLDNAxh09l",
"consumer": { "id": "3c2c8fc1-7245-4fbb-b48b-e5947e1ce941" }
}
]
"next":null,
}
Filter the list by Consumer by using a different endpoint:
$ curl -X GET http://kong:8001/consumers/{username or id}/key-auth
username or id
: The username or id of the Consumer whose credentials need to be listed.
Response:
...
{
"data": [
{
"id":"6cb76501-c970-4e12-97c6-3afbbba3b454",
"created_at":1507936652000,
"key":"nCztu5Jrz18YAWmkwOGJkQe9T8lB99l4",
"consumer": { "id": "c0d92ba9-8306-482a-b60d-0cfdd2f0e880" }
}
]
"next":null,
}
Retrieve the Consumer associated with a key
Retrieve a Consumer associated with an API key by making the following request:
curl -X GET http://kong:8001/key-auths/{key or id}/consumer
key or id
: The id
or key
property of the API key for which to get the
associated Consumer.
Response:
{
"created_at":1507936639000,
"username":"foo",
"id":"c0d92ba9-8306-482a-b60d-0cfdd2f0e880"
}