Skip to main content

Validates OIDC/OAuth2 access tokens following RC9068

Project description

RFC9068 Access Token Validator

This library provides a means to validate access tokens following the rules laid out in RFC9068.

Rationale

Both OIDC and OAuth2 do not clearly specify how to validate access tokens as a resource server. This poses a risk as the implementation of choice might differ across applications and may be insecure.

In order to resolve this issue RFC7662 was published in 2015. This method involves the resource server sending the access token to the authorization server to verify it. This comes with a big performance penalty, as the resource server needs to make its own request to the authorization server everytime it needs to validate a token, which basically needs to happen for every authenticated request.

To overcome the performance penalty, systems started using access tokens in the form of JSON Web Tokens, which can be parsed and validated. However, considering there was no formal definition of what the contents of the token should look like, tokens issued by one provider were not necessarily compatible with tokens provided by another provider, leading to different implementations of token validation.

RFC9068 aims to overcome that obstacle by providing a specification on what the contents of the access tokens should look like and how to validate the access tokens.

Installation

Install using uv:

uv add rfc9068

or using pip:

pip install rfc9068

Usage

The validator itself is nothing more than a composition, its dependencies do the actual work. That means that we need to construct the validator and it's recommended to use dependency injection to do that, otherwise perhaps implement a factory.

Factory example

from rfc9068 import RFC9068AccessTokenValidator, RFC9068AccessTokenValidatorInterface
from rfc9068.parser import AccessTokenParser
from rfc9068.payload import (
  IssuerValidator,
  AudienceValidator,
  ExpirationValidator
)
from rfc9068.signature import PyJwtSignatureValidator, PyJwtJWKResolver
from jwt import PyJWKClient, PyJWS

class ValidatorFactory:
  def __call__(
    self,
    jwks_url: str,
    issuer: str,
    audience: str,
    algorithms: list[str] = ["RS256"],
  ): RFC9068AccessTokenValidatorInterface:
    return RFC9068AccessTokenValidator(
        AccessTokenParser(),
        PyJwtSignatureValidator(
            PyJwtJWKResolver(
                PyJWKClient(jwks_url),
            ),
            PyJWS(),
        ),
        IssuerValidator(),
        AudienceValidator(),
        ExpirationValidator(),
        algorithms,
        issuer,
        audience,
    )

factory = ValidatorFactory()
validate = factory(
  "http://keycloak:8002/realms/rfc9068/protocol/openid-connect/certs",
  "http://keycloak:8002/realms/rfc9068",
  "test-audience",
  ["RS256"],
)

Validator

Now that we have a validator we can use it to validate access tokens.

from rfc9068.core import InvalidTokenError

try:
  validate(access_token)
except InvalidTokenError as e:
  # Token is not valid
  print(e)
  raise e

# When no exceptions are raised the token is valid

Development

For development of this package we provide a container setup.

Building

docker compose build

Starting containers

docker compose run --rm validator sh

This will also open a shell where we can run our dev tools:

uv run ruff check
uv run mypy .
uv run pytest -v --cov --cov-fail-under=100

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

rfc9068-0.1.0.tar.gz (4.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rfc9068-0.1.0-py3-none-any.whl (6.2 kB view details)

Uploaded Python 3

File details

Details for the file rfc9068-0.1.0.tar.gz.

File metadata

  • Download URL: rfc9068-0.1.0.tar.gz
  • Upload date:
  • Size: 4.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for rfc9068-0.1.0.tar.gz
Algorithm Hash digest
SHA256 7f91f3d6797ec48b79009c2b76caa136ee5a87b5b7986949e126eb521b676a72
MD5 4d89c733c89f02d1de4e96c24bb493ec
BLAKE2b-256 cd3588f055cbd858beab2be227b95fda156a756e380a72fca6e5aee95bf998f3

See more details on using hashes here.

File details

Details for the file rfc9068-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: rfc9068-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 6.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for rfc9068-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 971882858ad47c8f6c0d7c90788f9e1ad232937a0fca4076e19266cb0394ddba
MD5 9bdc2671fc83c6163bdf25b358669316
BLAKE2b-256 15acb998009c565c4bff5dcfe9836f2f8f6860a5c03989c470b5fff7ec86af83

See more details on using hashes here.

Supported by

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