Skip to main content

API key permissions for the Django REST Framework

Project description

djangorestframework-api-key

travis pypi python django drf license Say Thanks!

🔐 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.2.0.tar.gz (10.2 kB view details)

Uploaded Source

Built Distribution

File details

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

File metadata

  • Download URL: djangorestframework-api-key-1.2.0.tar.gz
  • Upload date:
  • Size: 10.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.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.2.0.tar.gz
Algorithm Hash digest
SHA256 b0c770ccb7d490520f0396bae446c851a95de0550c34e1421bdcb60a31de9d99
MD5 1da3f157af46b518cde8e23c8ec32764
BLAKE2b-256 1c676d9eb95b007d1a6f58f022f5bd33fcd14add3eb33d091f778a9604960242

See more details on using hashes here.

File details

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

File metadata

  • Download URL: djangorestframework_api_key-1.2.0-py3-none-any.whl
  • Upload date:
  • Size: 15.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.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.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fa1c492dcf1d0e58a74ae8806649087a3a41ea0f88fd127cec0798d229162314
MD5 5137682be87f4e2d2e5a2b8793e6c0d6
BLAKE2b-256 28127e3279c7d4279b43e15ee52e84a93fd321a10b9451a1b78c92e8407e4dea

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