Skip to main content

API key permissions for the Django REST Framework

Project description

djangorestframework-api-key

travis pypi python django drf license

🔐 API key permissions for the Django REST Framework.

Migrating from 0.x? Read the release notes.

Features

djangorestframework-api-key allows server-side clients to safely use your API.

Server-side clients are third-party backends and services (i.e. machines) which do not have a user account but still need to interact with your API in a secure way.

Intended to be:

  • ✌️ Simple to use: create, view and revoke API keys via the admin site, or use built-in helpers to create API keys programmatically.
  • 🔒 As secure as possible: API keys are treated with the same level of care than user passwords. They are hashed using the default password hasher before being stored in the database, and only visible at creation.

Note: there are important security aspects you need to consider before switching to an API key access control scheme. See Security caveats.

Installation

  • Install from PyPI:
pip install djangorestframework-api-key
  • Add the app to your INSTALLED_APPS:
# settings.py

INSTALLED_APPS = [
  # ...
  'rest_framework',
  'rest_framework_api_key',
]
  • Run the included migrations:
python manage.py migrate

Usage

Setting permissions

This package provides an HasAPIKey permission class. It requires clients to provide a valid API key.

As any permission class, you can either set it globally:

# settings.py
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework_api_key.permissions.HasAPIKey',
    ]
}

or on a per-view basis:

# views.py
from rest_framework.views import APIView
from rest_framework_api_key.permissions import HasAPIKey

class UserListView(APIView):
    permission_classes = [HasAPIKey]
    # ...

Tip: you can use the bitwise operators | and & to compose HasAPIKey with other permission classes and achieve more complex authorization behaviour, e.g.:

  • Require clients to pass a valid API key AND their authentication credentials:
permission_classes = [HasAPIKey & IsAuthenticated]
  • Require clients to pass a valid API key OR their authentication credentials:
permission_classes = [HasAPIKey | IsAuthenticated]

See also Setting the permission policy for more information on using permission classes in the Django REST Framework.

Making authorized requests

Authorization header

By default, clients must pass their API key via the Authorization header. It must be formatted as follows:

Authorization: Api-Key ********

where ******** refers to the generated API key.

To know under which conditions access is granted, please see Grant scheme.

Custom header

You can set the API_KEY_CUSTOM_HEADER setting to a non-None value to require clients to pass their API key in a custom header instead of the Authorization header.

This is useful if you plan to use API keys AND an authentication scheme which already uses the Authorization header (e.g. token-based authentication).

For example, if you set:

# settings.py
API_KEY_CUSTOM_HEADER = "HTTP_X_API_KEY"

then clients must make authorized requests using:

X-Api-Key: ********

where ******** refers to the generated API key.

Please refer to HttpRequest.META for more information on headers in Django.

Creating and managing API keys

Admin site

When it is installed, djangorestframework-api-key adds an "API Key Permissions" section to the Django admin site where you can create, view and revoke API keys.

Programmatic usage (advanced)

API keys can be created, viewed and revoked programmatically by manipulating the APIKey model.

The examples below use the Django shell.

  • You can view and query APIKey like any other model. For example, to know the number of active (unrevoked) API keys:
>>> from rest_framework_api_key.models import APIKey
>>> APIKey.objects.filter(revoked=False).count()
42
  • If you wish to create an API key programmatically, you'll most likely want a one-time access to its generated key too. To do so, use the .create_key() method on the APIKey objects manager instead of .create():
>>> from rest_framework_api_key.models import APIKey
>>> api_key, generated_key = APIKey.objects.create_key(name="Backend API")
>>> # Proceed with `api_key` and `generated_key`...

Danger: to preserve confidentiality, give the generated key to the client only, and do not keep any trace of it on the server afterwards.

Security

Key generation scheme

An API key is composed of two items:

  • A prefix P, which is a generated string of 8 characters.
  • A secret key SK, which is a generated string of 32 characters.

The generated key that clients use to make authorized requests is GK = P.SK. It is treated with the same level of care than passwords:

  • Only a hashed version is stored in the database. The hash is computed using the default password hasher* (see also How Django stores passwords).
  • The generated key is shown only once to the client upon API key creation.

*All hashers provided by Django should be supported. djangorestframework-api-key is tested against the default list of PASSWORD_HASHERS.

Grant scheme

Access is granted if and only if all of the following is true:

  1. The API key header is present and correctly formatted (see Making authorized requests).
  2. An unrevoked API key with the prefix of the given key exists in the database.
  3. The hash of the given key matches that of the API key.

Caveats

API keys ≠ Security: depending on your situation, you should probably not rely on API keys only to authenticate/authorize your clients.

Using API keys shifts the responsability of Information Security on your clients. This induces risks, especially if detaining an API key gives access to confidential information or write operations. For example, an attacker could impersonate clients if they let their API keys leak.

As a best practice, you should apply the Principle of Least Privilege: allow only those who require resources to access those specific resources. In other words: if your client needs to access an endpoint, add API permissions on that endpoint only instead of the whole API.

Besides, it is highly recommended to serve the API over HTTPS to ensure the confidentiality of API keys passed in requests.

Act responsibly!

Example project

The example project shows usage in the context of a Django project.

Changelog

See CHANGELOG.md.

Contributing

See CONTRIBUTING.md.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

djangorestframework-api-key-1.1.0.tar.gz (9.3 kB view details)

Uploaded Source

Built Distribution

File details

Details for the file djangorestframework-api-key-1.1.0.tar.gz.

File metadata

  • Download URL: djangorestframework-api-key-1.1.0.tar.gz
  • Upload date:
  • Size: 9.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.32.1 CPython/3.7.1

File hashes

Hashes for djangorestframework-api-key-1.1.0.tar.gz
Algorithm Hash digest
SHA256 0136f90cfa91714eafaa551d69c839b517a8240c4b32f42c5ee4d9bd4e3623a2
MD5 44ca7de604c395a36d8f79a63653f227
BLAKE2b-256 3015d8742dfa549eda51a7d4a9eed4b0290b872ddf71a776198d81909dbdd83b

See more details on using hashes here.

File details

Details for the file djangorestframework_api_key-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: djangorestframework_api_key-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 13.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.32.1 CPython/3.7.1

File hashes

Hashes for djangorestframework_api_key-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6df84b5ac9b598a30be308d8a8f7cbf1b0ae9c391687574eb245766f26ded0a5
MD5 ce98031c8813b038e8ef93838eb8d5ba
BLAKE2b-256 bd5498296d7ec2f2b24bd71919458e6305655769ee85a5f8ba3f798af8d15c88

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page