Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

Multi-provider external authentication for Plone

pas.plugins.identity

PyPI Python versions

Documentation CI

GitHub contributors GitHub Repo stars

The backend package for multi-provider external authentication in Plone, built on authlib and joserfc. See also the frontend package @plone-collective/volto-identity.

One canonical Plone user id maps to many external identities — GitHub, Google, another Plone site, any OpenID Connect provider, an emailed magic link — for the same human, without running a separate identity broker.

Features

  • Identity linking. One account, many providers. The identity key is (provider, subject), and an identity already linked to somebody is never silently re-attached: a collision is a hard error, not a merge.
  • Providers configured through the web. A control panel with a form generated from each driver's published schema, so a driver describes its own settings and the frontend composes rather than describes them. Client secrets are write-only through every API surface, GenericSetup export included.
  • Six shipped drivers. github, google, oidc-generic, plone-identity (another Plone site running this package's server layer), keycloak, and email for magic-link sign-in. Writing another means subclassing BaseDriver and registering a utility.
  • Magic-link sign-in. Single-use signed tokens, at most fifteen minutes, rate limited per address and per IP, answering identically for known and unknown addresses.
  • An audit log. Successes and refusals, per user or site-wide, bounded and purged on write. IP address and user agent are off by default, and the sink is a utility a deployment can replace.
  • A documented event contract, which is what the audit log, the profile machinery and your own integrations all consume. Nothing reaches into anything else.
  • Content-backed profiles and groups, with user properties, enumeration and group membership served entirely from a dedicated catalog. No content object is woken to answer them, and the test suite asserts that rather than claiming it.
  • Federated group membership. Each provider's grants are recorded separately, so signing in through one never revokes what another gave you, and local grants survive both.
  • Migrations from pas.plugins.authomatic and pas.plugins.oidc. Dry-run by default, idempotent, and they report what they would do before you let them do it.
  • Core installs alone. uv add pas.plugins.identity with no extras is a tested configuration, enforced in CI by an import-linter contract rather than by discipline.

Layers and extras

The package installs as a core, with one optional layer beside it. [server] is that layer, and it brings a GenericSetup profile of its own. [sql] is an extra rather than a layer: it adds one audit sink and installs no profile.

Profile What it adds
pas.plugins.identity:default Sign in with external providers, identity linking, the audit log, the control panel, and the content types users and groups are.
pas.plugins.identity.server:default An OAuth 2.1 and OpenID Connect authorization server, so the site can be a provider for others.
Extra Adds Profile
[server] The authorization server layer. pas.plugins.identity.server:default
[sql] An audit sink writing a row per event to a relational database. Needs IDENTITY_AUDIT_DSN. none — name sql in audit_sinks.

Core never imports from the server layer, and CI fails the build if it starts to. Read the layers page for why the boundary is more than tidiness.

Not in scope

  • Being an identity broker. Providers are configured on the site and mapped onto its own users; this package does not proxy one provider to another.
  • Merging two existing accounts. A colliding identity is refused rather than reconciled, because a merge that guesses is worse than a refusal that explains.
  • Storing credentials in a Dexterity field. Passwords stay in source_users, or in an annotation for a site that opts into ICredentialStorage. A field would be serialized, exported, indexed and versioned: four disclosure paths, each of which has to be remembered separately.
  • SAML. Nothing here precludes a driver for it; none ships.

Documentation

Full documentation is published at collective.github.io/pas-plugins-identity, and its source lives in docs/ at the repository root.

The pages closest to this package:

Installation

Requires Plone 6.2 and Python 3.12 or later.

Install pas.plugins.identity with uv.

uv add pas.plugins.identity

For the authorization server as well:

uv add "pas.plugins.identity[server]"

Create the Plone site.

make create-site

Then install pas.plugins.identity from the add-ons control panel, and configure a provider in Site Setup > Identity providers.

Contribute

Prerequisites ✅

Installation 🔧

  1. Clone this repository.

    git clone git@github.com:collective/pas-plugins-identity.git
    cd pas-plugins-identity/backend
    
  2. Install this code base.

    make install
    

Tests

make test

Part of the suite drives a real OpenID Connect provider in a container and is marked docker. To run everything else:

uv run pytest -m "not docker"

License

The project is licensed under GPLv2.

Credits and acknowledgements 🙏

Generated using Cookieplone (2.0.0b3) and cookieplone-templates (91c8455) on 2026-08-20 18:32:15.036687. A special thanks to all contributors and supporters!

Metadata

Release files for pas.plugins.identity 1.0.0a13

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

Source distribution (sdist)

Source distribution for pas.plugins.identity 1.0.0a13
File Size Uploaded Provenance
pas_plugins_identity-1.0.0a13.tar.gz 1.1 MB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for pas.plugins.identity 1.0.0a13
File Interpreter ABI Platform
pas_plugins_identity-1.0.0a13-py3-none-any.whl Python 3 none any Details

Total release size: 1.8 MB

Release files / pas_plugins_identity-1.0.0a13.tar.gz

Download URL pas_plugins_identity-1.0.0a13.tar.gz
Size 1.1 MB
Tags Source
SHA-256 checksum
How to use checksums
066a4e752dada947100522d35bea688e943f8feb5916938dc10f4a3cb390291d
BLAKE2b-256 checksum
How to use checksums
74dc500d4ffedd19299d1cbf59a90268706427db290ed4547874e4dc358a4fb9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.21 {"installer":{"name":"uv","version":"0.12.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / pas_plugins_identity-1.0.0a13-py3-none-any.whl

Download URL pas_plugins_identity-1.0.0a13-py3-none-any.whl
Size 731.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4fce3df52e9621898fc64b1a9fc1fd0f0eb37f41f2fade1fca6bef990a55e92b
BLAKE2b-256 checksum
How to use checksums
7a575a3d790c23a7ab0803f2053a2b650ddcd0b90ccd5fa8275e30eacf2b3931
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.21 {"installer":{"name":"uv","version":"0.12.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for pas.plugins.identity 1.0.0a13

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