openrs-dcb

Turning Library Patron Authentication Into OIDC

  • openrs
  • dcb
  • discovery
  • patron-auth
  • federated-identity
  • zitadel
  • ncip
  • ors-appliance

Earlier this month I wrote that federated identity in libraries is already happening. The point was not just that libraries need better login buttons. It was that library services need bounded, trusted assertions about patrons, institutions, and entitlements.

This is a small but important local checkpoint in that work: Rincewind can now log in to OpenRS Discovery as a patron of The Unseen University.

The more important point is what the Discovery app does not know.

It does not know how to authenticate against Sierra, Polaris, Alma, Koha, Evergreen, a local database, ORS-Appliance Fallback Host, or any other library system. It consumes OIDC. The DCB side uses its existing authentication abstractions and host-system integrations to reach proprietary or local patron authentication systems, then presents the result through a standards-based identity path that other applications can consume.

That is the real move: turn patron authentication trapped behind library-system interfaces into OIDC.

The architecture point

Library technology talks a lot about microservices. The original point of microservices was not convenience for hosting providers. It was independent deployability in service of more modular applications.

For libraries, that should mean being able to assemble new workflows by coordinating services with clear, standard interfaces. A discovery app, a document delivery app, a controlled digital lending app, a universal library card app, and a lifelong library card app should not each have to learn the proprietary patron authentication model of every library system in the network.

As long as patron identity remains hidden behind local or proprietary interfaces, it creates friction. That friction protects vendor and hosting boundaries more than it serves libraries.

The work here is a small example of the alternative. DCB already knows how to talk to library systems through its authentication abstractions. The Discovery login path wraps that capability in an OIDC-facing identity service. OpenRS Discovery is eating its own dog food: it is just another client of the identity interface we want future library applications to consume.

The design also has to support mixed identity estates. One institution may route patrons to SAML. Another may use OIDC. Another may have no standards-facing IdP at all, but may still have a patron database behind a proprietary LMS API. In this model, that long tail can still appear to consuming applications as OIDC, because DCB and the broker absorb the local-system-specific work.

The visible flow

The first screen is deliberately ordinary. Discovery is still a catalogue. Login is present, but it is not allowed to become the whole product.

OpenRS Discovery home page with shared catalogue search and a Login button.

OpenRS Discovery starts as an anonymous shared catalogue, with patron login available from the header.

Once a search has results, the large prompt collapses into a compact search/refine/results mode. This is closer to the interaction users expect from a working catalogue: after the first query, the vertical space belongs to results.

OpenRS Discovery search results for Brain with a compact search bar and refine rail.

Result mode is intentionally denser: compact search at the top, facets on the left, records in the main column.

After the patron starts login, the first domain question is not “which ZITADEL Organization are you in?” It is: where are you from?

That is Home Institution Discovery. It is a library-domain discovery step, equivalent to a WAYF service. The user selects a home library, university, council, or other institution. The result is an auth route.

OpenRS Discovery institution picker showing The Unseen University as a library credential route.

The patron chooses The Unseen University. This is institution discovery, not a ZITADEL Organization picker.

For The Unseen University, the route is local library credentials. That does not mean the React app is trusted to authenticate the patron. The SPA owns the journey, not the assertion.

OpenRS Discovery local credential form for The Unseen University with Rincewind entered as username.

Rincewind enters local credentials. The browser collects the input; the backend owns verification.

The completed login returns the patron to the result page they were using. The Login button is replaced by a patron menu. That is a better user contract than stopping on a developer-facing “login complete” screen.

OpenRS Discovery search results showing Rincewind signed in in the header.

Rincewind is returned to the search result page after login. The final Discovery session comes from ZITADEL.

The user menu is the first entry point for patron-specific services.

OpenRS Discovery user menu open for Rincewind with My account and Sign out actions.

The patron menu is intentionally small: account first, sign out second.

The account page is only a first UI slice. It shows the identity details currently available to the SPA and sketches the request-status surface that will matter next.

OpenRS Discovery patron account page for Rincewind with current request placeholders.

The account page gives us a home for patron details and request status. The current requests table is a placeholder until patron request APIs are connected.

The trust boundary

The useful rule is simple:

  • React owns the patron journey.
  • Micronaut owns the authentication transaction.
  • ZITADEL owns the final identity, session, and token issued to Discovery.
  • DCB consumes normalized patron claims later for resource-sharing requests.

Discovery does not consume a DCB patron-auth API directly as its application login contract. It consumes the final OIDC result. That distinction matters because it means the identity service can be reused by applications that are not Discovery.

In ZITADEL terms, the local stack now separates the identity boundaries:

  • ZITADEL Instance: the local issuer/domain boundary.
  • ZITADEL Organization: the local administrative/customer boundary.
  • ZITADEL Project: the patron-facing security context, separate from admin/staff auth.
  • ZITADEL Application: the Discovery SPA OIDC client.
  • Custom Login UI / Login App: the Discovery-owned patron journey surface.

The institution registry is not a ZITADEL Organization list. It is platform domain configuration. It maps a selected institution to an auth route: institutional SAML, institutional OIDC, social IdP, local credential broker, or unsupported.

What actually verifies Rincewind?

The local QA route now uses the real integration path:

OpenRS Discovery SPA
  -> ZITADEL hosted login
  -> ORS Discovery credential broker
  -> DCB /v2/patron/auth
  -> DCB ORS-Appliance Host LMS adapter
  -> NCIP 2.02 LookupUser
  -> ORS-Appliance embedded patron registry

The key point is that Rincewind no longer lives in a discovery-service static verifier. The demo patron lives in installed ORS-Appliance Fallback Host data for the Unseen University tenant. Discovery asks DCB to authenticate the patron; DCB asks the host system through its adapter; the adapter uses NCIP; ORS-Appliance verifies the local patron.

That matters because this is the shape we need for the long tail. Some institutions will use SAML. Some will use OIDC. Some may allow a social IdP. Some will need a local credential broker because their library system still owns the patron record. The relying application should not care which brokered path was used. It should receive one consistent ZITADEL-issued patron identity.

In this context, OIDC does two jobs. It is one of the standards-native routes an institution may already provide, and it is also the standards-facing wrapper we can put in front of proprietary patron databases through DCB.

Bonus: where Rincewind lives

The admin side now has the first thin management surface for the embedded patron registry. This is deliberately host-system scoped. It is not “Discovery users”; it is the institution’s local patron record that DCB can reach through the host-system integration path. Fallback Host is one consumer of this capability; Embedded ILS should be able to expose the same capability.

ORS-Appliance embedded patron registry list showing Rincewind.

ORS-Appliance exposes the embedded patron registry as an admin CRUD surface. Discovery still consumes only OIDC.

ORS-Appliance patron record view for Rincewind with local ID, barcode, username, home location, and status.

The patron record keeps local identifiers and a write-only credential reset path. The stored credential material is not exposed back to the browser.

Why this is identity engineering, not just login

Libraries often have patrons who do not fit cleanly into a campus IAM model: public library users, alumni, walk-in users, reciprocal borrowers, consortium users, and users from unsupported host systems. Treating all of that as “just add login” hides the important work.

The important work is federation:

  • who can identify the patron;
  • who can assert the patron is eligible;
  • what claims are needed by the relying service;
  • which system owns credential verification;
  • what the browser is allowed to know;
  • what DCB can later rely on for request placement.

This slice is small, but it attacks the right boundary. Discovery gets a patron session. ZITADEL remains the issuer. DCB still sees a DCB-shaped patron principal. ORS-Appliance can stand in for an institution whose local host system is not otherwise directly compatible with the network.

Most importantly, the OIDC surface is not Discovery-specific. Discovery is simply the first consuming application. The same identity path should be available to other workflows: document delivery, controlled digital lending, universal library cards, lifelong library cards, or services we have not designed yet.

That is the service-based architecture libraries have been promised for years. Not microservices as deployment packaging. Microservices as independently useful capabilities that can be coordinated into new library workflows.

That is the direction of travel: help libraries expose their patrons as properly federated identities in a wide-area resource-sharing system, without pretending every library starts with the same identity infrastructure.