Skip to main content

CKAN Passwordless API

Extension to allow paswordless login to the CKAN API.

Documentation: https://envidat.gitlab-pages.wsl.ch/ckanext-passwordless_api/

Source Code: https://gitlabext.wsl.ch/EnviDat/ckanext-passwordless_api


This plugin is primarily intended for custom frontends built on the CKAN API.

By using API tokens from CKAN core (>2.9), this plugin provides an authentication flow where:

  1. Users receive a login token via email (via reset key in core).
  2. API token is returned on valid login token (reset key) submission.
  3. The API token should then be included in Authorization headers from the frontend --> CKAN calls.

Based on work by @espona (Lucia Espona Pernas) for ckanext-passwordless (https://github.com/EnviDat/ckanext-passwordless).

A second login flow is also supported, using Azure AD:

  1. User logs in with authorization code flow in frontend (@azure/msal-browser or similar).
  2. Azure token is passed to azure specific endpoint.
  3. Token is validated and API token for CKAN is returned.
  4. The API token should then be included in Authorization headers from the frontend --> CKAN calls.

Install

pip install ckanext-passwordless-api

Config

Optional variables can be set in your ckan.ini:

  • passwordless_api.guidelines_url
    • Description: A link to your website guidelines.
    • Default: None, not included.
  • passwordless_api.policies_url
    • Description: A link to your website policies.
    • Default: None, not included.
  • passwordless_api.welcome_template
    • Description: Path to welcome template to render as html email.
    • Default: uses default template.
  • passwordless_api.reset_key_template
    • Description: Path to reset key template to render as html email
    • Default: uses default template.
  • passwordless_api.cookie_name
    • Description: Set to place the API token in a cookie, with given name. The cookie will default to secure, httpOnly, samesite: Lax.
    • Default: None, no cookie used.
  • passwordless_api.cookie_domain
    • Description: The domain for samesite to respect, required if cookie set.
    • Default: None.
  • passwordless_api.cookie_samesite
    • Description: To change the cookie samesite value to Strict. Only enable this if you know what you are doing.
    • Default: None, samesite value is set to Lax.
  • passwordless_api.cookie_http_only
    • Description: Use a httpOnly cookie, recommended.
    • Default: true.
  • passwordless_api.cookie_path
    • Description: Set a specific path to use the cookie, e.g. /api.
    • Default: / (all paths).
  • passwordless_api.anonymous_usernames
    • Description: Set to true to anonymise usernames when generated.
    • Default: false.
  • passwordless_api.anonymous_domain_exceptions
    • Description: Email domain exceptions that should not be anonymised, if enabled.
    • Default: None.

Endpoints

POST

  • <CKAN_HOST>/api/3/action/passwordless_request_reset_key
    • Description: Request a login token for a given email.
      • Creates user if they do not exist & sends welcome email.
    • Param1: email (str).
  • <CKAN_HOST>/api/3/action/passwordless_request_api_token
    • Description: Request an API token, given the email and login token (reset_key).
    • Param1: email (str).
    • Param2: key (str).
  • <CKAN_HOST>/api/3/action/passwordless_request_api_token_azure_ad
    • Description: Request an API token, given the email and Azure AD token.
    • Param1: email (str).
    • Param2: token (str).
  • <CKAN_HOST>/api/3/action/passwordless_revoke_api_token
    • Description: Revoke an API token.
    • Param1: token (str).

GET

  • <CKAN_HOST>/api/3/action/passwordless_revoke_api_token
    • Description: If logged in, revoke the current API token.
  • <CKAN_HOST>/api/3/action/passwordless_get_user
    • Description: Get user details, given their API token.
      • Also resets and returns a new API token (i.e. renewal).
      • Fails silently if the user is not logged in.
      • Use the core user_show action if refresh is not required.
  • <CKAN_HOST>/api/3/action/passwordless_introspect
    • Description: Verify if the API token is valid for a user.
      • This does not renew the token in the same call.
      • Mostly useful for auth checking in microservice APIs.

If configured, the cookie containing an API token can't do much on it's own.

It is possible to extract the cookie value using frontend JS and pass to the CKAN backend, but this makes your site vulnerable to XSS attacks.

Instead the cookie should be stored in a secure way:

  • samesite=Lax with domain=YOUR_DOMAIN to help prevent CSRF.
    • samesite=Strict is even more secure, but significantly impacts UX for your site.
  • secure to help prevent man-in-the-middle.
  • httpOnly to help prevent XSS.
    • Setting this means the cookie can no longer be accessed from your JS code.

Then a middleware must be used to convert the cookie value into a header than CKAN can interpret:

NGINX server example (nginx is the default/recommended server to reverse proxy CKAN) (https://docs.ckan.org/en/latest/maintaining/installing/deployment.html)

# Add the cookie-based API token to the request Authorization header
# This is passed to the CKAN backend & read automatically by CKAN
proxy_set_header 'Authorization' $cookie_${AUTH_COOKIE_NAME};

# If using caching omit the cookie
proxy_cache_bypass $cookie_${AUTH_COOKIE_NAME};
proxy_no_cache $cookie_${AUTH_COOKIE_NAME};

Apache server example

SetEnvIf Cookie "(^|;\ *)${AUTH_COOKIE_NAME}=([^;\ ]+)" ckan_cookie_value=$2
RequestHeader set Authorization "%{ckan_cookie_value}e"

Notes

  • It is also recommended to disable access to the API via cookie, to help prevent CSRF: ckan.auth.disable_cookie_auth_in_api = true
  • The configuration for API tokens can be configured in core:
api_token.nbytes = 60
api_token.jwt.decode.secret = string:YOUR_SUPER_SECRET_STRING
api_token.jwt.algorithm = HS256

# expire_api_token plugin (unit = 1 day in seconds, lifetime = 3 days)
expire_api_token.default_lifetime = 3
expire_api_token.default_unit = 86400

Metadata

Release files for ckanext-passwordless_api 1.1.11

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ckanext-passwordless_api 1.1.11
File Size Uploaded Provenance Actions
ckanext-passwordless-api-1.1.11.tar.gz 16.0 kB Without provenance Details for ckanext-passwordless-api-1.1.11.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for ckanext-passwordless_api 1.1.11
File Interpreter ABI Platform Actions
ckanext_passwordless_api-1.1.11-py3-none-any.whl Python 3 none any Details for ckanext_passwordless_api-1.1.11-py3-none-any.whl

Total release size: 31.1 kB

Release files / ckanext-passwordless-api-1.1.11.tar.gz

Download URL ckanext-passwordless-api-1.1.11.tar.gz
Size 16.0 kB
Tags Source
SHA-256 checksum
How to use checksums
9a74f2fc5b99dc40278e2ce90c9a1dfbd23313a9757765e0890d9ec084ecae90
BLAKE2b-256 checksum
How to use checksums
fe7026699e7f99443959f3c6d80cac1cf5875591b345155817ffbb552db181df
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via pdm/2.25.9 CPython/3.9.23 Linux/5.4.0-216-generic

Release files / ckanext_passwordless_api-1.1.11-py3-none-any.whl

Download URL ckanext_passwordless_api-1.1.11-py3-none-any.whl
Size 15.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b84eb564844c0d9542623ce32274572e659f3627c6798f8c04c18ff624255fc0
BLAKE2b-256 checksum
How to use checksums
56e1f9890111de27f90e43df7f76ac21f0debffaf156212a33da3f6ed9b64dee
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via pdm/2.25.9 CPython/3.9.23 Linux/5.4.0-216-generic

Security for ckanext-passwordless_api 1.1.11

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page