Skip to main content
PretaGovPretaGov

PretaGov

  • About
  • Insights
  • Work
  • Services
info@email.com
00 (123) 456 78 90
Contact

SSO patterns we trust

SSO (single sign-on) is one of those problems that looks straightforward in the spec and ugly in practice. We've shipped SSO integrations into Plone, custom Python services, Volto, and AI tooling for AU and UK government clients. Here's what we've settled on.

OIDC for most things

OpenID Connect is the modern default. It's an authentication layer on top of OAuth 2.0, well-supported across identity providers (Azure AD, Google Workspace, Okta, Keycloak, AWS Cognito), and the developer ergonomics are better than SAML by a long way.

Use OIDC unless one of the constraints below forces SAML.

SAML for legacy enterprise

SAML 2.0 is the older standard. Many enterprise identity providers still default to it, and a lot of government-grade IdPs (Shibboleth in higher ed; some health-sector implementations) are SAML-only. The protocol is verbose, the XML signature handling is error-prone, but the pattern is well-known.

Where you must do SAML: use a mature library (python-saml, pysaml2). Do not roll your own signature verification. Test the metadata round-trip carefully — most SAML failures we debug are misaligned metadata between IdP and SP.

Multi-tenant patterns

For platforms serving multiple organisations each with their own identity provider, the pattern is: route by hostname or email domain to the right IdP. We've shipped this for both Plone-based intranets and custom Python services. The pivot point is the OIDC discovery URL — wire it dynamically per tenant rather than statically per app.

The common failure mode here is shared session cookies across tenants. Don't. Tenant A's session must not be valid for tenant B even if the same user has accounts on both. Easy to get right at design time, painful to fix retroactively.

Cleared-partner access

For regulator and government work, we sometimes need to grant external cleared partners access to internal systems. The pattern: federated IdP, time-bounded credentials, fine-grained role mapping, audit log of every grant and use. We've built this on Keycloak federations and on direct OIDC connection to the partner's own IdP.

Audit is the part most teams under-invest in. Logging "who got access to what, when, and what they did" is the entire reason regulator clients trust the system enough to grant access in the first place.

Service-to-service tokens

Inside the stack, services authenticate to each other with short-lived OAuth 2.0 tokens, not API keys. Tokens are scoped per caller and per action. Rotation happens automatically. We don't put long-lived secrets in source code or in CI environment variables; those are the leak vectors we've seen most often.

What's changed lately

Two patterns we've shifted to recently: passkeys (WebAuthn) for end-user authentication where the IdP supports them — phishing-resistant, smoother UX than TOTP. And Pushed Authorization Requests (PAR) for OIDC where the IdP supports it — closes a class of phishing attack by ensuring the authorization parameters can't be tampered with via the browser. Both are quiet improvements that don't change the day-to-day pattern but raise the security ceiling.

The pattern we don't do

"Just store passwords in our own database with bcrypt." Don't. Identity is hard; offload it to a provider that does identity professionally. Even small clients should be on Auth0 or Cognito rather than a homegrown user table. We've inherited too many homegrown auth systems to recommend anyone build one again.

PretaGov

© 2026 PretaGov.
All rights reserved.

PretaGov UK

Suite 2A, Blackthorn House
St Pauls Square
Birmingham, B3 1RL
+44 (0) 208 819 3887
contact@pretagov.co.uk

PretaGov Australia

Suite 97, Level 3
515 Kent Street
Sydney NSW 2000
+61 (2) 9955 2830
contact@pretagov.com.au

Legal

  • Blog
  • Privacy Statement
  • Anti-slavery Statement
  • Accessibility Statement