{"result":{"depiction_url":null,"edges":{"in_module":{"objects":[{"created":"2026-10-06T13:35:39Z","object_id":{"id":2766,"is_a":["text","documentation","reference","module"],"name":"doc_external_3_mod_sso_openidc","title":"mod_sso_openidc","uri":"https:\/\/zotonic.com\/id\/2766"},"seq":1}],"predicate":{"id":333,"is_a":["meta","predicate"],"name":"in_module","title":{"_type":"trans","tr":{"en":"In module"}},"uri":"https:\/\/zotonic.com\/id\/in_module"}},"subject":{"objects":[{"created":"2026-10-06T13:35:39Z","object_id":{"id":2555,"is_a":["categorization","keyword","keyword_information_type"],"name":"zotonic_topic_reference","title":"Reference","uri":"https:\/\/zotonic.com\/id\/2555"},"seq":1},{"created":"2026-10-06T13:35:39Z","object_id":{"id":2564,"is_a":["categorization","keyword","keyword_audience"],"name":"zotonic_topic_backend_developer","title":"Backend developer","uri":"https:\/\/zotonic.com\/id\/2564"},"seq":2},{"created":"2026-10-06T13:35:39Z","object_id":{"id":2589,"is_a":["categorization","keyword","keyword_domain"],"name":"zotonic_topic_identity_and_accounts","title":"Identity and accounts","uri":"https:\/\/zotonic.com\/id\/2589"},"seq":3},{"created":"2026-10-06T13:35:39Z","object_id":{"id":2590,"is_a":["categorization","keyword","keyword_domain"],"name":"zotonic_topic_authentication","title":"Authentication","uri":"https:\/\/zotonic.com\/id\/2590"},"seq":4},{"created":"2026-10-06T13:35:39Z","object_id":{"id":2592,"is_a":["categorization","keyword","keyword_domain"],"name":"zotonic_topic_authorization_and_access_control","title":"Authorization and access control","uri":"https:\/\/zotonic.com\/id\/2592"},"seq":5},{"created":"2026-10-06T13:35:39Z","object_id":{"id":2599,"is_a":["categorization","keyword","keyword_domain"],"name":"zotonic_topic_api_and_integration","title":"API and integration","uri":"https:\/\/zotonic.com\/id\/2599"},"seq":6},{"created":"2026-10-06T13:35:39Z","object_id":{"id":2625,"is_a":["categorization","keyword","keyword_architecture"],"name":"zotonic_topic_model","title":"Model","uri":"https:\/\/zotonic.com\/id\/2625"},"seq":7},{"created":"2026-10-06T13:35:39Z","object_id":{"id":2681,"is_a":["categorization","keyword","keyword_technology"],"name":"zotonic_topic_oauth_2_0","title":"OAuth 2.0","uri":"https:\/\/zotonic.com\/id\/2681"},"seq":8}],"predicate":{"id":308,"is_a":["meta","predicate"],"name":"subject","title":{"_type":"trans","tr":{"en":"Keyword"}},"uri":"http:\/\/purl.org\/dc\/elements\/1.1\/subject"}}},"id":2767,"is_a":["text","documentation","reference","model"],"links":[{"rel":"self","target":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/2767"},{"rel":"hub","target":"https:\/\/zotonic.com\/.zotonic\/websub"}],"medium":null,"medium_url":null,"name":"doc_external_3_m_sso_openidc","page_url":{"en":"https:\/\/zotonic.com\/docs\/2767\/m_sso_openidc","x-default":"https:\/\/zotonic.com\/docs\/2767\/m_sso_openidc"},"preview_url":null,"resource":{"version":19,"pivot_location_lat":null,"title":"m_sso_openidc","is_authoritative":true,"body":"<p>Expose OpenID Connect provider configuration and public provider choices to\ntemplates, and supply provider storage and logon lookup functions to Erlang.<\/p>\n<h2>Model reads<\/h2>\n<table class=\"table\"><thead><tr><th>Path<\/th><th>Result<\/th><th>Access<\/th><\/tr><\/thead><tbody><tr><td><code>providers.list.auth<\/code><\/td><td>Enabled authentication providers<\/td><td>Public<\/td><\/tr><tr><td><code>providers.list.import<\/code><\/td><td>Enabled import providers<\/td><td>Public<\/td><\/tr><tr><td><code>providers.list.all<\/code><\/td><td>Enabled authentication or import providers<\/td><td>Public<\/td><\/tr><tr><td><code>providers.list<\/code><\/td><td>Full stored provider records<\/td><td>Provider administration<\/td><\/tr><tr><td><code>providers.byid[id]<\/code><\/td><td>One full provider record<\/td><td>Provider administration<\/td><\/tr><tr><td><code>provider[name].is_config_loaded<\/code><\/td><td>Whether discovery configuration is available<\/td><td>Provider administration<\/td><\/tr><tr><td><code>provider[name].scopes_supported<\/code><\/td><td>Discovered scopes, or an empty list if unspecified<\/td><td>Provider administration<\/td><\/tr><tr><td><code>provider[name].acr_values_supported<\/code><\/td><td>Discovered ACR values, or an empty list if unspecified<\/td><td>Provider administration<\/td><\/tr><tr><td><code>is_user_external<\/code><\/td><td>Whether the current user is controlled by an SSO provider<\/td><td>Current user<\/td><\/tr><\/tbody><\/table>\n<p>Provider administration means administrator access or <code>use.mod_sso_openidc<\/code>.\nProtected reads return <code>{error, eacces}<\/code> when unauthorized. Full provider\nrecords include client credentials and must not be exposed in public output.\nThe public lists select display and routing fields only, omit credentials, and\nexclude Client Credentials providers. Results are ordered by priority,\ndescription, name, and ID.<\/p>\n<p>For example, render public authentication choices with:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-django\">{% for provider in m.sso_openidc.providers.list.auth %}\n    &lt;a href=&quot;{% url oauth2_oidc_authorize provider=provider.name %}&quot;&gt;\n        {{ provider.description|escape }}\n    &lt;\/a&gt;\n{% endfor %}\n<\/code><\/pre>\n<p>Custom templates can apply their own display choices; the module&#39;s standard\nextra logon buttons omit priority <code>99<\/code>. Escape provider text when rendering it.\nThe model provides GET paths; provider mutations use the admin&#39;s signed\npostbacks rather than model POST paths.<\/p>\n<h2>Erlang API<\/h2>\n<p><code>list\/1<\/code>, <code>fetch\/2<\/code>, and <code>find_by_name\/2<\/code> return full provider records.\n<code>list_providers_auth\/1<\/code>, <code>list_providers_import\/1<\/code>, and <code>list_providers_all\/1<\/code>\nreturn the public subsets. <code>list_providers_for_domain\/2<\/code> finds enabled\nauthentication providers assigned to an email domain.<\/p>\n<p><code>insert\/3<\/code> accepts a provider name, discovery domain, and context. It fetches\ndiscovery metadata, stores the issuer, and creates a disabled provider,\nreturning <code>{ok, Id}<\/code>. Duplicate names return <code>{error, duplicate_name}<\/code> and failed\ndiscovery returns <code>{error, oidc_config}<\/code>. <code>update\/3<\/code> stores provider properties\nand reloads its worker configuration; <code>delete\/2<\/code> removes the provider.<\/p>\n<p>These direct storage functions do not enforce the model-path authorization\nchecks. Callers must check <code>is_authorized\/1<\/code> before exposing full records or\nperforming administrative mutations. The module&#39;s admin event handlers do so.<\/p>\n<p><code>find_providers_by_logon_username\/2<\/code> returns <code>{ControllingProviders, OtherProviders}<\/code>\nfor a supplied email address or username. <code>find_providers_controlling_user_id\/2<\/code>\nfinds providers controlling a user&#39;s primary email domain. <code>is_user_external\/2<\/code>\nuses that control information to identify externally managed users.<\/p>","slug":"m_sso_openidc","doc_module_config":[],"is_protected":false,"visible_for":0,"tz":"UTC","language":["en"],"doc_source_hash":"8b77b874969c1d67e4a4c63a0b658d34ccf336f61d8baf28430304cfca283528","is_featured":false,"content_group_id":{"id":2551,"is_a":["meta","content_group"],"name":"content_group_imported_docs","title":"Imported documentation","uri":"https:\/\/zotonic.com\/id\/content_group_imported_docs"},"external_module_id":{"id":3,"is_a":[],"name":null,"title":null,"uri":"https:\/\/zotonic.com\/id\/3"},"git_url":"https:\/\/github.com\/driebit\/zotonic_mod_sso_openidc","category_id":{"id":322,"is_a":["meta","category"],"name":"model","title":"Models","uri":"https:\/\/test.zotonic.com\/id\/322"},"doc_source_path":".\/src\/models\/m_sso_openidc.erl","publication_start":"2026-10-06T13:35:39Z","github_url":"https:\/\/github.com\/driebit\/zotonic_mod_sso_openidc","pivot_location_lng":null,"doc_source_kind":"external","name":"doc_external_3_m_sso_openidc","is_unfindable":false,"is_published":true,"pivot_geocode":null,"external_module_title":"OpenIDC","created":"2026-10-06T13:35:39Z","uri":null,"doc_status":"current","is_dependent":false,"is_external_module":true,"publication_end":"9999-06-01T00:00:00Z","modifier_id":{"id":1,"is_a":["person"],"name":"administrator","title":"Site Administrator","uri":"https:\/\/zotonic.com\/id\/1"},"privacy":0,"doc_source_commit":"d47592abd3ac17d449e0ca6c82edc1d44a1c5607","creator_id":{"id":1,"is_a":["person"],"name":"administrator","title":"Site Administrator","uri":"https:\/\/zotonic.com\/id\/1"},"modified":"2026-10-06T13:35:39Z","title_slug":"m_sso_openidc"},"uri":"https:\/\/zotonic.com\/id\/2767","uri_template":"https:\/\/zotonic.com\/id\/:id","websub":{"hub":"https:\/\/zotonic.com\/.zotonic\/websub","topic":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/2767"}},"status":"ok"}