Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Repository files navigation

Multi-provider external authentication for Plone

PyPI npm

Built with Cookieplone Documentation Storybook

GitHub contributors GitHub Repo stars

CI

Multi-provider external authentication for Plone, built on authlib and joserfc.

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.

πŸ“– Read the documentation

What it does πŸ“‹

  • 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. Client secrets are write-only through every API surface, including GenericSetup export.
  • 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 and user agent are off by default.
  • 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.
  • An authorization server, optionally. The [server] extra makes the site an OAuth 2.1 and OpenID Connect provider in its own right, so one Plone site can be where the others sign in.
  • Core installs alone. uv add pas.plugins.identity with no extras is a tested configuration, enforced in CI by an import-linter contract.

Relationship to pas.plugins.oidc and pas.plugins.authomatic

pas.plugins.authomatic is the long-standing multi-provider option, built on the authomatic library, which is no longer maintained upstream. This package is a candidate successor for those sites.

pas.plugins.oidc does one OIDC provider, and does it well. If that is what you need, it is the smaller and more mature dependency; there is no reason to move.

The difference is linking. Neither of the above maps several external identities onto one canonical Plone user id, and that mapping is what this package is arranged around. Migrations from both have shipped: they are dry-run by default, idempotent, and report what they would do before you let them do it. See Migrating from pas.plugins.authomatic and Migrating from pas.plugins.oidc for what each can and cannot recover.

For how this compares with Products.membrane β€” a similar problem solved a different way β€” see About users as content.

Documentation πŸ“š

Full documentation lives in docs/ and is published at collective.github.io/pas-plugins-identity.

Install in your project πŸ”§

Both packages are installed separately. The backend one is enough on its own; the frontend one requires it.

Backend

Requires Plone 6.2 and Python 3.12 or later.

uv add pas.plugins.identity

For the authorization server as well:

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

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

Frontend

Requires Volto 19. The add-on is developed against 19.3.0.

Add @plone-collective/volto-identity to your package.json.

"addons": [
    "@plone-collective/volto-identity"
],
"dependencies": {
    "@plone-collective/volto-identity": "*"
}

Important

Adding the package to dependencies without listing it under addons installs the code but never registers it, so nothing is rendered.

Quick Start 🏁

Prerequisites βœ…

Installation πŸ”§

  1. Clone this repository, then change your working directory.

    git clone [email protected]:collective/pas-plugins-identity.git
    cd pas-plugins-identity
  2. Install this code base.

    make install

Fire Up the Servers πŸ”₯

  1. Create a new Plone site on your first run.

    make backend-create-site
  2. Start the backend at http://localhost:8080/.

    make backend-start
  3. In a new shell session, start the frontend at http://localhost:3000/.

    make frontend-start

Voila! Your Plone site should be live and kicking! πŸŽ‰

Local Stack Deployment πŸ“¦

Deploy a local Docker Compose environment that includes the following.

Run the following commands in a shell session.

make stack-create-site
make stack-start

And... you're all set! Your Plone site is up and running locally! πŸš€

The federation demo 🀝

A second stack runs two Plone sites and signs one into the other, which is the fastest way to see what this package is for.

It runs on a single PostgreSQL rather than a ZEO server, with a database each for the two sites' ZODBs and a third for authentication records. Only the identity provider writes its records there; the relying party keeps the bounded log inside its own plugin, so the two arrangements are visible side by side.

make demo-stack-start

Read the tutorial for what to click once it is up.

Project structure πŸ—οΈ

This monorepo consists of the following distinct sections:

  • backend: The Plone add-on pas.plugins.identity, installed with uv, plus its test suite and the demo stack's own package.
  • frontend: The Volto add-on @plone-collective/volto-identity, plus its Storybook stories.
  • docs: The Sphinx and MyST documentation published at collective.github.io/pas-plugins-identity.

Why this structure? πŸ€”

  • Both halves of the add-on live together, so a change to a REST API payload and the change to the component that reads it are one commit.
  • GitHub Workflows are triggered per section, so a documentation change does not rebuild the frontend (refer to .github/workflows).
  • The documentation is built from the same checkout as the code it describes, so a reference page and the source it documents cannot drift between repositories.

Code quality assurance 🧐

To check your code against quality standards, run the following shell command.

make check

Format the codebase

To format and rewrite the code base, ensuring it adheres to quality standards, run the following shell command.

make format
Section Tool Description Configuration
backend Ruff Python code formatting, imports sorting backend/pyproject.toml
backend zpretty XML and ZCML formatting --
frontend ESLint Fixes most common frontend issues frontend/.eslintrc.js
frontend prettier Format JS and Typescript code frontend/.prettierrc
frontend Stylelint Format Styles (css, less, sass) frontend/.stylelintrc

Formatters can also be run within the backend or frontend folders.

Linting the codebase

To check the code base without rewriting it, run the following shell command.

make lint
Section Tool Description Configuration
backend Ruff Checks code formatting, imports sorting backend/pyproject.toml
backend Pyroma Checks Python package metadata --
backend check-python-versions Checks Python version information --
backend zpretty Checks XML and ZCML formatting --
frontend ESLint Checks JS / Typescript lint frontend/.eslintrc.js
frontend prettier Check JS / Typescript formatting frontend/.prettierrc
frontend Stylelint Check Styles (css, less, sass) formatting frontend/.stylelintrc

Linters can be run individually within the backend or frontend folders.

The backend also enforces its own layering. make check-imports, from backend/, runs import-linter contracts asserting that core never imports the optional server layer, so the no-extras install stays a tested configuration rather than a claim.

Internationalization 🌐

Generate translation files for Plone and Volto with ease:

make i18n

Packages πŸ“¦

This repository holds two packages, released separately and each under its own license.

Package Location Registry License
pas.plugins.identity backend/ PyPI GPL-2.0-only
@plone-collective/volto-identity frontend/ npm MIT

The backend package is usable on its own: it needs no frontend to authenticate a user against an external provider, link an identity, or serve any of it over the REST API. The frontend package requires the backend, because everything it renders comes from what the backend serves.

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!

About

Multi-provider external authentication for Plone

Resources

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages