Flask SDK for Axioms and OAuth2 / OpenID Connect based authentication and authorization providers.
Project description
axioms-flask-py 
Flask SDK for OAuth2 / OpenID Connect based authentication and authorization providers (Previously designed for Axioms). Secure your Flask APIs using OAuth2 / OpenID Connect based authentication and authorization checks.
Prerequisite
- Python 3.7+
- An OAuth2/OIDC client which can obtain access token after user's authentication and authorization and include obtained access token as bearer in
Authorizationheader of all API request sent to Python/Flask application server.
Install SDK
Install axioms-flask-py in you Flask API project,
pip install axioms-flask-py
Documentation
Prerequisite
- Python 3.7+
- An Axioms client which can obtain access token after user's authentication and authorization and include obtained access token as bearer in
Authorizationheader of all API request sent to Python/Flask application server.
Install SDK
Install axioms-flask-py in you Flask API project,
pip install axioms-flask-py
Add environment variables
Create a .env file and add following configs
Option 1: Using AXIOMS_DOMAIN (for Axioms or standard OAuth2/OIDC providers)
AXIOMS_DOMAIN=<your-axioms-slug>.axioms.io
AXIOMS_AUDIENCE=<your-axioms-resource-identifier-or-endpoint>
Option 2: Using AXIOMS_JWKS_URL (for custom JWKS endpoints)
AXIOMS_JWKS_URL=https://my-auth.domain.com/oauth2/.well-known/jwks.json
AXIOMS_AUDIENCE=<your-axioms-resource-identifier-or-endpoint>
Configuration Options:
AXIOMS_AUDIENCE(required): Your resource identifier or API audienceAXIOMS_JWKS_URL(optional): Full URL to your JWKS endpointAXIOMS_DOMAIN(optional): Your auth domain (e.g.,my-auth.domain.com)
Note: You must provide either AXIOMS_JWKS_URL or AXIOMS_DOMAIN.
Claims Handling:
- Roles are checked from
rolesclaim, orhttps://{AXIOMS_DOMAIN}/claims/rolesif using namespaced claims - Permissions are checked from
permissionsclaim, orhttps://{AXIOMS_DOMAIN}/claims/permissionsif using namespaced claims - Scopes are checked from the standard
scopeclaim
Load environment variables
In your Flask app file (where flask app is declared) add following.
from flask_dotenv import DotEnv
env = DotEnv(app)
Register Error
In your Flask app file (where flask app is declared) add following.
from flask import jsonify
from axioms_flask.error import AxiomsError
@app.errorhandler(AxiomsError)
def handle_auth_error(ex):
response = jsonify(ex.error)
response.status_code = ex.status_code
if ex.status_code == 401:
response.headers[
"WWW-Authenticate"
] = "Bearer realm='{}', error='{}', error_description='{}'".format(
app.config["AXIOMS_DOMAIN"], ex.error["error"], ex.error["error_description"]
)
return response
Guard Your Flask API Views
Use following decorators to guard you API views.
| Decorators | Description | Parameter |
|---|---|---|
axioms_flask.decorators.has_valid_access_token |
Checks if API request includes a valid bearer access token as authorization header. Check performed includes: token signature validation, expiry datetime validation, and token audience validation. Should be always the first decorator on the protected or private view. |
|
axioms_flask.decorators.has_required_scopes |
Check any of the given scopes included in scope claim of the access token. Should be after has_valid_access_token. |
An array of strings as conditional OR representing any of the allowed scope or scopes for the view as parameter. For instance, to check openid or profile pass ['profile', 'openid'] as parameter. |
axioms_flask.decorators.has_required_roles |
Check any of the given roles included in roles claim of the access token. Should be after has_valid_access_token. |
An array of strings as conditional OR representing any of the allowed role or roles for the view as parameter. For instance, to check sample:role1 or sample:role2 roles you will pass ['sample:role1', 'sample:role2'] as parameter. |
axioms_flask.decorators.has_required_permissions |
Check any of the given permissions included in permissions claim of the access token. Should be after has_valid_access_token. |
An array of strings as conditional OR representing any of the allowed permission or permissions for the view as parameter. For instance, to check sample:create or sample:update permissions you will pass ['sample:create', 'sample:update'] as parameter. |
Examples
- Check
openidorprofilescope present in the token
from axioms_flask.decorators import has_valid_access_token, has_required_scopes
private_api = Blueprint("private_api", __name__)
@private_api.route('/private', methods=["GET"])
@has_valid_access_token
@has_required_scopes(['openid', 'profile'])
def api_private():
return jsonify({'message': 'All good. You are authenticated!'})
- Check
sample:rolerole present in the token
from axioms_flask.decorators import has_valid_access_token, has_required_roles
role_api = Blueprint("role_api", __name__)
@role_api.route("/role", methods=["GET", "POST", "PATCH", "DELETE"])
@has_valid_access_token
@has_required_roles(["sample:role"])
def sample_role():
if request.method == 'POST':
return jsonify({"message": "Sample created."})
if request.method == 'PATCH':
return jsonify({"message": "Sample updated."})
if request.method == 'GET':
return jsonify({"message": "Sample read."})
if request.method == 'DELETE':
return jsonify({"message": "Sample deleted."})
- Check permission present in the token at API method level
from axioms_flask.decorators import has_valid_access_token, has_required_permissions
permission_api = Blueprint("permission_api", __name__)
@permission_api.route("/permission", methods=["POST"])
@has_valid_access_token
@has_required_permissions(["sample:create"])
def sample_create():
return jsonify({"message": "Sample created."})
@permission_api.route("/permission", methods=["PATCH"])
@has_valid_access_token
@has_required_permissions(["sample:update"])
def sample_update():
return jsonify({"message": "Sample updated."})
@permission_api.route("/permission", methods=["GET"])
@has_valid_access_token
@has_required_permissions(["sample:read"])
def sample_read():
return jsonify({"message": "Sample read."})
@permission_api.route("/permission", methods=["DELETE"])
@has_valid_access_token
@has_required_permissions(["sample:delete"])
def sample_delete():
return jsonify({"message": "Sample deleted."})
Flask Sample
To see a complete working example download Flask sample from our Github repository or simply deploy to heroku by clicking following button. You will need to provide Axioms domain and Axioms audience to complete deployment.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file axioms_flask_py-0.0.9rc21762481121.tar.gz.
File metadata
- Download URL: axioms_flask_py-0.0.9rc21762481121.tar.gz
- Upload date:
- Size: 17.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
84b835ce2e4234b93326ec111ca84d916aaeaf059cccf0f7878ba1f35db117ac
|
|
| MD5 |
673752a26a809e105fd3be9184fbb595
|
|
| BLAKE2b-256 |
8f93d38d55430152ed1d90804eb32ef386d341a00f099434c34fe1451303081a
|
Provenance
The following attestation bundles were made for axioms_flask_py-0.0.9rc21762481121.tar.gz:
Publisher:
release.yml on abhishektiwari/axioms-flask-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
axioms_flask_py-0.0.9rc21762481121.tar.gz -
Subject digest:
84b835ce2e4234b93326ec111ca84d916aaeaf059cccf0f7878ba1f35db117ac - Sigstore transparency entry: 678608114
- Sigstore integration time:
-
Permalink:
abhishektiwari/axioms-flask-py@c6d08527b97fd2aca5e37c73f6f4f73dbd18f94b -
Branch / Tag:
refs/pull/2/merge - Owner: https://github.com/abhishektiwari
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c6d08527b97fd2aca5e37c73f6f4f73dbd18f94b -
Trigger Event:
pull_request
-
Statement type:
File details
Details for the file axioms_flask_py-0.0.9rc21762481121-py3-none-any.whl.
File metadata
- Download URL: axioms_flask_py-0.0.9rc21762481121-py3-none-any.whl
- Upload date:
- Size: 11.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
06e353f533710f15d0db1dbb31b293d83e755ce4e7995363c9da2648f038c0e5
|
|
| MD5 |
304e75cb18933cf42793dce0d25b1035
|
|
| BLAKE2b-256 |
7903ed670c082e4a2baa8f380d0c2fc235ca74b29c7e8a619979065845ab04f5
|
Provenance
The following attestation bundles were made for axioms_flask_py-0.0.9rc21762481121-py3-none-any.whl:
Publisher:
release.yml on abhishektiwari/axioms-flask-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
axioms_flask_py-0.0.9rc21762481121-py3-none-any.whl -
Subject digest:
06e353f533710f15d0db1dbb31b293d83e755ce4e7995363c9da2648f038c0e5 - Sigstore transparency entry: 678608132
- Sigstore integration time:
-
Permalink:
abhishektiwari/axioms-flask-py@c6d08527b97fd2aca5e37c73f6f4f73dbd18f94b -
Branch / Tag:
refs/pull/2/merge - Owner: https://github.com/abhishektiwari
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c6d08527b97fd2aca5e37c73f6f4f73dbd18f94b -
Trigger Event:
pull_request
-
Statement type: