[{"data":1,"prerenderedAt":421},["ShallowReactive",2],{"{\"path\":[\"blog\",\"sso-patterns-we-trust\"],\"query\":null,\"headers\":{\"Accept\":\"application/json\"}}":3},{"page":4,"templates":284,"_listing_pages":283,"navigation":399,"breadcrumbs":415},{"@id":5,"@type":6,"UID":7,"allow_discussion":8,"blocks":9,"blocks_layout":200,"changeNote":64,"contributors":224,"created":225,"creators":226,"description":228,"effective":229,"exclude_from_nav":8,"expires":230,"id":231,"is_folderish":232,"items":233,"items_total":263,"language":264,"layout":267,"lock":268,"modified":269,"nav_title":230,"next_item":270,"parent":271,"preview_caption_link":230,"preview_image_link":230,"previous_item":278,"relatedItems":279,"review_state":275,"rights":64,"subjects":280,"table_of_contents":230,"title":281,"type_title":277,"version":282,"versioning_enabled":232,"working_copy":230,"working_copy_of":230,"_listing_pages":283},"https://pretagovsite-api.fly.dev/blog/sso-patterns-we-trust","Document","9d59dfddd81848c284e183aad5958ff7",false,{"00b270f1-7f12-4a24-ab01-0795e5773d2e":10,"08a2e95f-a035-4045-8e5c-e0582b0348c2":18,"173ccff7-ab2c-4418-8c33-d65b6d01c0e1":25,"3c570355-fde0-4155-83f7-4d5eb6b71ae0":31,"41bd3815-20db-43dc-9d4d-1db0224a0858":37,"49ff88ca-35ee-409f-8eba-9955f5d0facf":43,"58306dbc-ad58-48a5-a2c5-8c80f76329b4":49,"66e7dcbb-27af-47e4-a2ac-e747a6fc09f7":55,"78eef699-18cc-44d8-aa5d-55de832f1f38":61,"a18501b6-bd6d-47db-ae7c-e6af1bd5c10a":108,"a746a44e-4207-4510-9cb2-248252583cd5":114,"b396b634-4464-44f3-b702-11943b60dfe6":120,"b49b225e-d2e8-47cb-a987-355c2a4225f9":126,"bfde7c42-f537-4b60-9fad-8cb5eedc11e0":132,"c5d26096-0f7e-4da4-87ba-07364c31861f":138,"c612b05b-11b8-4dbb-8483-e2c749123410":140,"c637fe4f-b889-4290-af47-b42573c870b6":146,"d68fe203-8a30-439f-ade7-2f7209c94140":152,"e0dc1d76-54d2-4744-a145-05b2b2e1e725":176,"e134d1c1-a578-4939-ac17-c69e60ce8865":182,"fc8d5282-53e8-4a18-b803-67aa8bd8d6f0":188,"feea38e3-9e20-41fe-adcf-aed3aa753ad3":194},{"@type":11,"plaintext":12,"value":13},"slate","Multi-tenant patterns",[14],{"children":15,"type":17},[16],{"text":12},"h2",{"@type":11,"plaintext":19,"value":20},"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.",[21],{"children":22,"type":24},[23],{"text":19},"p",{"@type":11,"plaintext":26,"value":27},"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.",[28],{"children":29,"type":24},[30],{"text":26},{"@type":11,"plaintext":32,"value":33},"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.",[34],{"children":35,"type":24},[36],{"text":32},{"@type":11,"plaintext":38,"value":39},"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.",[40],{"children":41,"type":24},[42],{"text":38},{"@type":11,"plaintext":44,"value":45},"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.",[46],{"children":47,"type":24},[48],{"text":44},{"@type":11,"plaintext":50,"value":51},"OIDC for most things",[52],{"children":53,"type":17},[54],{"text":50},{"@type":11,"plaintext":56,"value":57},"What's changed lately",[58],{"children":59,"type":17},[60],{"text":56},{"@type":62,"align":63,"alt":64,"image_scales":65,"url":107},"image","right","",{"image":66},[67],{"content-type":68,"download":69,"filename":70,"height":71,"scales":72,"size":105,"width":106},"image/png","@@images/image-1146-8ba0f90ce0acc2f849dfd8cdae6958bf.png","Screenshot 2023-08-21 at 2.21.13 pm.png",608,{"icon":73,"large":77,"larger":81,"mini":85,"preview":89,"teaser":93,"thumb":97,"tile":101},{"download":74,"height":75,"width":76},"@@images/image-32-080b057c7c34526e8ccc7c32ceb44c4b.png",16,32,{"download":78,"height":79,"width":80},"@@images/image-800-4bb610f7b58416776a4dacd1d0644cd3.png",424,800,{"download":82,"height":83,"width":84},"@@images/image-1000-421c3c4ca5068d8454eeb169e82ac3d6.png",530,1000,{"download":86,"height":87,"width":88},"@@images/image-200-7aa10766e1653616b5012dab346fda18.png",106,200,{"download":90,"height":91,"width":92},"@@images/image-400-fee9332a8aa65018b1533e6781c559d9.png",212,400,{"download":94,"height":95,"width":96},"@@images/image-600-4b3c8ae5340ec18fdf140a4015ecfd82.png",318,600,{"download":98,"height":99,"width":100},"@@images/image-128-6c58a1e126a15ce235b097567a9b900b.png",67,128,{"download":102,"height":103,"width":104},"@@images/image-64-ef3dd3121b8293072c3efc3fed5586ba.png",33,64,138810,1146,"https://pretagovsite-api.fly.dev/blog/sso-patterns-we-trust/screenshot-2023-08-21-at-2-21-13-pm-2.png",{"@type":11,"plaintext":109,"value":110},"Cleared-partner access",[111],{"children":112,"type":17},[113],{"text":109},{"@type":11,"plaintext":115,"value":116},"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.",[117],{"children":118,"type":24},[119],{"text":115},{"@type":11,"plaintext":121,"value":122},"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.",[123],{"children":124,"type":24},[125],{"text":121},{"@type":11,"plaintext":127,"value":128},"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.",[129],{"children":130,"type":24},[131],{"text":127},{"@type":11,"plaintext":133,"value":134},"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.",[135],{"children":136,"type":24},[137],{"text":133},{"@type":139},"title",{"@type":11,"plaintext":141,"value":142},"Service-to-service tokens",[143],{"children":144,"type":17},[145],{"text":141},{"@type":11,"plaintext":147,"value":148},"\"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.",[149],{"children":150,"type":24},[151],{"text":147},{"@type":62,"align":63,"alt":64,"image_scales":153,"size":174,"url":175},{"image":154},[155],{"content-type":68,"download":156,"filename":70,"height":71,"scales":157,"size":105,"width":106},"@@images/image-1146-3ae8ba2e9f7eb358eaa238f9089a9e26.png",{"icon":158,"large":160,"larger":162,"mini":164,"preview":166,"teaser":168,"thumb":170,"tile":172},{"download":159,"height":75,"width":76},"@@images/image-32-996cbc87f38bda4ca173da70d59ca828.png",{"download":161,"height":79,"width":80},"@@images/image-800-9874ad5c321854702466f95ee23d4af2.png",{"download":163,"height":83,"width":84},"@@images/image-1000-028e29c979e62ad15bbcc17af60f723f.png",{"download":165,"height":87,"width":88},"@@images/image-200-d5578964c0f4e99ea83d106f7a65aa0e.png",{"download":167,"height":91,"width":92},"@@images/image-400-226c242d33fa121ecaab7cc1871e3200.png",{"download":169,"height":95,"width":96},"@@images/image-600-cda12ad70f3ae4d863118a47b8c5381d.png",{"download":171,"height":99,"width":100},"@@images/image-128-30aab567a179eae85477ab802ed67a35.png",{"download":173,"height":103,"width":104},"@@images/image-64-bc6e86d54667756c1d241ff457f22ba9.png","m","https://pretagovsite-api.fly.dev/blog/sso-patterns-we-trust/screenshot-2023-08-21-at-2-21-13-pm-1.png",{"@type":11,"plaintext":177,"value":178},"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.",[179],{"children":180,"type":24},[181],{"text":177},{"@type":11,"plaintext":183,"value":184},"Use OIDC unless one of the constraints below forces SAML.",[185],{"children":186,"type":24},[187],{"text":183},{"@type":11,"plaintext":189,"value":190},"The pattern we don't do",[191],{"children":192,"type":17},[193],{"text":189},{"@type":11,"plaintext":195,"value":196},"SAML for legacy enterprise",[197],{"children":198,"type":17},[199],{"text":195},{"items":201},[202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223],"c5d26096-0f7e-4da4-87ba-07364c31861f","78eef699-18cc-44d8-aa5d-55de832f1f38","3c570355-fde0-4155-83f7-4d5eb6b71ae0","58306dbc-ad58-48a5-a2c5-8c80f76329b4","bfde7c42-f537-4b60-9fad-8cb5eedc11e0","e134d1c1-a578-4939-ac17-c69e60ce8865","feea38e3-9e20-41fe-adcf-aed3aa753ad3","d68fe203-8a30-439f-ade7-2f7209c94140","e0dc1d76-54d2-4744-a145-05b2b2e1e725","08a2e95f-a035-4045-8e5c-e0582b0348c2","00b270f1-7f12-4a24-ab01-0795e5773d2e","b49b225e-d2e8-47cb-a987-355c2a4225f9","a746a44e-4207-4510-9cb2-248252583cd5","a18501b6-bd6d-47db-ae7c-e6af1bd5c10a","49ff88ca-35ee-409f-8eba-9955f5d0facf","b396b634-4464-44f3-b702-11943b60dfe6","c612b05b-11b8-4dbb-8483-e2c749123410","173ccff7-ab2c-4418-8c33-d65b6d01c0e1","66e7dcbb-27af-47e4-a2ac-e747a6fc09f7","41bd3815-20db-43dc-9d4d-1db0224a0858","fc8d5282-53e8-4a18-b803-67aa8bd8d6f0","c637fe4f-b889-4290-af47-b42573c870b6",[],"2026-06-02T09:39:59",[227],"admin","Single sign-on patterns we've shipped, what works for which case, and the failure modes we've stopped repeating.","2026-05-21T10:00:00+00:00",null,"sso-patterns-we-trust",true,[234,250],{"@id":175,"@type":235,"description":64,"effective":236,"end":230,"getObjSize":237,"head_title":230,"image_field":62,"image_scales":238,"mime_type":68,"nav_title":230,"review_state":230,"start":230,"title":70,"type_title":235},"Image","1969-12-31T00:00:00+00:00","135.6 KB",{"image":239},[240],{"content-type":68,"download":156,"filename":70,"height":71,"scales":241,"size":105,"width":106},{"icon":242,"large":243,"larger":244,"mini":245,"preview":246,"teaser":247,"thumb":248,"tile":249},{"download":159,"height":75,"width":76},{"download":161,"height":79,"width":80},{"download":163,"height":83,"width":84},{"download":165,"height":87,"width":88},{"download":167,"height":91,"width":92},{"download":169,"height":95,"width":96},{"download":171,"height":99,"width":100},{"download":173,"height":103,"width":104},{"@id":107,"@type":235,"description":64,"effective":236,"end":230,"getObjSize":237,"head_title":230,"image_field":62,"image_scales":251,"mime_type":68,"nav_title":230,"review_state":230,"start":230,"title":70,"type_title":235},{"image":252},[253],{"content-type":68,"download":69,"filename":70,"height":71,"scales":254,"size":105,"width":106},{"icon":255,"large":256,"larger":257,"mini":258,"preview":259,"teaser":260,"thumb":261,"tile":262},{"download":74,"height":75,"width":76},{"download":78,"height":79,"width":80},{"download":82,"height":83,"width":84},{"download":86,"height":87,"width":88},{"download":90,"height":91,"width":92},{"download":94,"height":95,"width":96},{"download":98,"height":99,"width":100},{"download":102,"height":103,"width":104},2,{"title":265,"token":266},"English","en","document_view",{"locked":8,"stealable":232},"2026-06-02T09:40:01",{},{"@id":272,"@type":6,"description":64,"effective":273,"end":230,"getObjSize":230,"head_title":230,"image_field":230,"image_scales":274,"mime_type":230,"nav_title":230,"review_state":275,"start":230,"title":276,"type_title":277},"https://pretagovsite-api.fly.dev/blog","2023-08-04T22:10:00+00:00",{},"published","Insights","Page",{},[],[],"SSO patterns we trust","current",{},{"/templates/contact-cta-info":285,"/templates/contact-cta":351},{"@components":286,"@id":303,"@type":6,"UID":304,"allow_discussion":8,"blocks":305,"blocks_layout":327,"changeNote":64,"contributors":330,"created":331,"creators":332,"description":333,"effective":230,"exclude_from_nav":232,"expires":230,"id":334,"is_folderish":232,"items":335,"items_total":336,"language":337,"layout":267,"lock":338,"modified":339,"nav_title":230,"next_item":340,"parent":341,"preview_caption_link":230,"preview_image_link":230,"previous_item":347,"relatedItems":348,"review_state":275,"rights":64,"subjects":349,"table_of_contents":230,"title":350,"type_title":277,"version":282,"versioning_enabled":232,"working_copy":230,"working_copy_of":230},{"actions":287,"aliases":289,"breadcrumbs":291,"contextnavigation":293,"navigation":295,"navroot":297,"types":299,"workflow":301},{"@id":288},"https://pretagovsite-api.fly.dev/templates/contact-cta-info/@actions",{"@id":290},"https://pretagovsite-api.fly.dev/templates/contact-cta-info/@aliases",{"@id":292},"https://pretagovsite-api.fly.dev/templates/contact-cta-info/@breadcrumbs",{"@id":294},"https://pretagovsite-api.fly.dev/templates/contact-cta-info/@contextnavigation",{"@id":296},"https://pretagovsite-api.fly.dev/templates/contact-cta-info/@navigation",{"@id":298},"https://pretagovsite-api.fly.dev/templates/contact-cta-info/@navroot",{"@id":300},"https://pretagovsite-api.fly.dev/templates/contact-cta-info/@types",{"@id":302},"https://pretagovsite-api.fly.dev/templates/contact-cta-info/@workflow","https://pretagovsite-api.fly.dev/templates/contact-cta-info","contactctainfo000000000000000000",{"cta-section":306},{"@type":307,"blocks":308,"blocks_layout":317,"fixed":232,"readOnly":232,"slotId":320,"styles":321,"templateId":325,"templateInstanceId":326},"section",{"cta-btn":309},{"@type":310,"buttonColor":311,"buttonSize":312,"href":313,"title":316},"button","white","btn-lg",[314],{"@id":315},"https://pretagovsite-api.fly.dev/contact-info","Contact us for more information",{"items":318},[319],"cta-btn","cta",{"backgroundColor":322,"padding":323,"textAlign":324},"gradient-8","large","center","/templates/contact-cta-info","tpl-contact-cta-info-def",{"items":328},[329],"cta-section",[],"2026-06-19T18:39:44+00:00",[227],"Reusable contact call-to-action. Edit here to update every page that uses it.","contact-cta-info",[],0,{"title":265,"token":266},{"locked":8,"stealable":232},"2026-06-22T05:55:00+00:00",{},{"@id":342,"@type":343,"description":344,"effective":236,"end":230,"getObjSize":230,"head_title":230,"image_field":230,"image_scales":345,"mime_type":230,"nav_title":230,"review_state":275,"start":230,"title":346,"type_title":343},"https://pretagovsite-api.fly.dev/templates","Folder","Reusable content templates (edited centrally, applied across pages).",{},"Templates",{},[],[],"Contact CTA — More information",{"@components":352,"@id":369,"@type":6,"UID":370,"allow_discussion":8,"blocks":371,"blocks_layout":383,"changeNote":64,"contributors":385,"created":386,"creators":387,"description":333,"effective":230,"exclude_from_nav":232,"expires":230,"id":388,"is_folderish":232,"items":389,"items_total":336,"language":390,"layout":267,"lock":391,"modified":339,"nav_title":230,"next_item":392,"parent":393,"preview_caption_link":230,"preview_image_link":230,"previous_item":395,"relatedItems":396,"review_state":275,"rights":64,"subjects":397,"table_of_contents":230,"title":398,"type_title":277,"version":282,"versioning_enabled":232,"working_copy":230,"working_copy_of":230},{"actions":353,"aliases":355,"breadcrumbs":357,"contextnavigation":359,"navigation":361,"navroot":363,"types":365,"workflow":367},{"@id":354},"https://pretagovsite-api.fly.dev/templates/contact-cta/@actions",{"@id":356},"https://pretagovsite-api.fly.dev/templates/contact-cta/@aliases",{"@id":358},"https://pretagovsite-api.fly.dev/templates/contact-cta/@breadcrumbs",{"@id":360},"https://pretagovsite-api.fly.dev/templates/contact-cta/@contextnavigation",{"@id":362},"https://pretagovsite-api.fly.dev/templates/contact-cta/@navigation",{"@id":364},"https://pretagovsite-api.fly.dev/templates/contact-cta/@navroot",{"@id":366},"https://pretagovsite-api.fly.dev/templates/contact-cta/@types",{"@id":368},"https://pretagovsite-api.fly.dev/templates/contact-cta/@workflow","https://pretagovsite-api.fly.dev/templates/contact-cta","contactcta0000000000000000000000",{"cta-section":372},{"@type":307,"blocks":373,"blocks_layout":378,"fixed":232,"readOnly":232,"slotId":320,"styles":380,"templateId":381,"templateInstanceId":382},{"cta-btn":374},{"@type":310,"buttonColor":311,"buttonSize":312,"href":375,"title":377},[376],{"@id":315},"Contact us for a free review of your project",{"items":379},[319],{"backgroundColor":322,"padding":323,"textAlign":324},"/templates/contact-cta","tpl-contact-cta-def",{"items":384},[329],[],"2026-06-19T18:39:45+00:00",[227],"contact-cta",[],{"title":265,"token":266},{"locked":8,"stealable":232},{},{"@id":342,"@type":343,"description":344,"effective":236,"end":230,"getObjSize":230,"head_title":230,"image_field":230,"image_scales":394,"mime_type":230,"nav_title":230,"review_state":275,"start":230,"title":346,"type_title":343},{},{},[],[],"Contact CTA — Free review",[400,404,407,411],{"label":401,"route":402,"items":403,"cols":263,"width":263},"About","/about",[],{"label":276,"route":405,"items":406,"cols":263,"width":263},"/blog",[],{"label":408,"route":409,"items":410,"cols":263,"width":263},"Work","/case-studies",[],{"label":412,"route":413,"items":414,"cols":263,"width":263},"Services","/services",[],{"@id":416,"items":417,"root":420},"https://pretagovsite-api.fly.dev/blog/sso-patterns-we-trust/@breadcrumbs",[418,419],{"@id":272,"title":276},{"@id":5,"title":281},"https://pretagovsite-api.fly.dev",1782108106269]