Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Version history


VersionDateNotes
0.12025-Q1First pilot draft
0.22026-02-05

Explicit target handling added
Introduced target_value to explicitly define the value sent via target_parameter. If either field is present, both are now required.

Support for relative target paths
target_value now supports absolute URIs as well as absolute-path references starting with /, optionally including query and fragment.

Improved validation of link map login URLs
In link_mapping, login URLs are now strictly required to be HTTPS, while IdP entityID keys may be any non-empty string (e.g. HTTPS URIs or URNs), due to legacy SAML entityID requirements.

Summary

The profile enables organizations to describe Service Providers (SPs) and their supported SSO mechanisms in a machine-readable format, using JSON. It supports two main SSO link types:

  • EntityID-based login: Relies on the identity provider’s entityID and parameters such as idp_parameter, target_parameter, and an SP-initiated login URL.

  • Link map-based login: Uses explicit mappings between known IdP entityIDs and proprietary login URLs.

Each metadata entry includes descriptive and branding information about the organization and its services, including display names, logos, and landing pages, facilitating consistent presentation in discovery services and login portals.

Metadata requirements

Organization Information (organization_info)

This section contains metadata about the organization offering the SSO services.

  • description REQUIRED (str)

    • A short description of the organization and its services.
    • Example: "An example description of the service provider organization".
  • display_name REQUIRED (str)

    • A user-friendly name for the organization.
    • Example: "Example Service Provider".
  • logotype REQUIRED (str, URL)

  • name REQUIRED (str)

    • The official legal name of the organization.
    • Example: "Example Service Provider AB".
  • url REQUIRED (str, URL)

List of SSO Links (sso_links)

This section contains a list of services that support SSO authentication.

...

description REQUIRED (str)

  • A short description of the service.
  • Example: "Example Digital Math Service is the number one digital math companion in Schengen".

...

disabled OPTIONAL (bool)

  • Indicates whether the SSO link is disabled. If omitted, the value is presumed to be false.
  • Possible values:
    • true → The service is disabled and not available to users.
    • false → The service is active and can be used.
  • Example: false (the service is active).

...

display_name REQUIRED (str)

  • The name of the service displayed to users.
  • Example: "Math Rocket".

entity_id REQUIRED (str, URL)

0.32026-03-01

IntroducedIdP Discovery Metadata feed. Refactored document structure for consistency and clarity.

0.3.12026-03-09

Updating JSON schemas to version 2020-12 and examples

Table of Contents
maxLevel3

Summary

This technical profile defines two independent JSON-based metadata feeds used within the SSO infrastructure:

  1. SP SSO Links Metadata Feed – Describes Service Providers (SPs) and how SSO can be initiated.

  2. IdP Discovery Metadata Feed – Provides a simplified Identity Provider (IdP) catalog in JSON format for UI presentation, discovery services, and portal implementations.

The feeds are independent and may be implemented separately.

Both feeds:

  • MUST use application/json

  • MUST use UTF-8 encoding

  • MUST validate against their respective JSON Schemas defined in this document

SP SSO Links Metadata

The SP SSO Links Metadata feed provides information about how SSO can be initiated for Service Providers within the federation.

It supports two SSO types:

  • EntityID-based login: Relies on the identity provider’s entityID and parameters such as idp_parameter, target_parameter, and an SP-initiated login URL.

  • Link map-based login: Uses explicit mappings between known IdP entityIDs and proprietary login URLs.

Each metadata entry includes descriptive and branding information about the organization and its services, including display names, logos, and landing pages, facilitating consistent presentation in discovery services and login portals.

SP SSO Links Data Model

The SP SSO Links Metadata feed MUST be a JSON array.


Each array element MUST be a JSON object containing organization_info and sso_links.

Organization Information (organization_info)

This section contains metadata about the organization offering the SSO services.

The organization_info object MUST contain the following properties:

FieldRequiredTypeDescription
descriptionYESstringA short description of the organization and its services
display_nameYESstringA user-friendly name of the organization
logotypeYESstring (URI)The URL of the organization's logo
nameYESstringThe official legal name of the organization
urlYESstring (URI)The official website of the organization

All properties are REQUIRED.
Additional properties MUST NOT be included.

Example

Code Block
languagejs
{
	"description": "An example description of the service provider organization",
	"display_name": "Example Service Provider",
	"logotype": 

...

"https://example.com/

...

logo REQUIRED (str, URL)

...

logo.svg",
	"name": "Example Service Provider AB",
	"url": "https://example.com

...

sso_type REQUIRED (str)

  • The type of SSO configuration used for the service.
  • Possible values:
    • "entity_id" → Standard SAML SSO using an entity ID.
    • "link_map" → Direct mapping between Identity Providers (IdPs) and specific login URLs.
  • Example: "entity_id" for traditional SAML SSO.

...

target_parameter OPTIONAL (str)

  • The parameter used to pass a target address after authentication.
  • Example: "Target".

...

target_value OPTIONAL (str)

  • The value used to pass a target address after authentication.
  • Example: "https://example.com/math/resource".

If either target_parameter or target_value is present, the other MUST also be present. target_value MAY be an absolute URI or an absolute-path reference starting with / optionally including query and fragment (relative to the service’s own origin).

If sso_type is "entity_id"

These fields are required for a standard SAML SSO setup using the entity ID as parameter for identifying the IdP.

...

idp_parameter REQUIRED (str)

  • The parameter used to pass the IdP’s entity ID in the SSO request.
  • Example: "entityID".
"
}

List of SSO Links (sso_links)

This section contains a list of services that support SSO authentication.

sso_links MUST be an array containing one object per service.

...

Each SSO link object MUST contain the following properties unless otherwise specified:

FieldRequiredTypeDescription
descriptionYESstringA short description of the service
display_nameYESstringThe name of the service displayed to users
entity_idYESstring (URI)The SAML entityID of the service
logoYESstring (URI)The URL of the service's logo
sso_typeYESstringThe type of SSO configuration
disabledNObooleanIndicates whether the SSO link is disabled
target_parameterNOstringThe parameter used to pass a target address
target_valueNOstringThe value used to pass a target address

...

Field Details

description (REQUIRED, string)

A short description of the service.

Example:
"Example Digital Math Service is the number one digital math companion in Schengen"

...

display_name (REQUIRED, string)

The name of the service displayed to users.

Example:
"Math Rocket"

...

entity_id (REQUIRED, string, URI)

The entity ID of the service in the SAML federation.

Example:
"https://example.com/math"

...

logo (REQUIRED, string, URI)

The URL of the service’s logo.

Example:

sp_init REQUIRED (str, URL)

...

"https://example.com/math/

...

logo.svg"

...

sso_type (REQUIRED, string)

Defines how SSO is initiated for the service.

Allowed values:

  • "entity_id" – Standard SAML SSO using an entity ID.

  • "link_map" – Direct mapping between Identity Providers (IdPs) and specific login URLs.

Example:

"sso_type": "entity_id"

...

disabled (OPTIONAL, boolean)

Indicates whether the SSO link is disabled.

If omitted, the value MUST be interpreted as false.

Allowed values:

  • true – The service is disabled and MUST NOT be presented to users.

  • false – The service is active.

Example:

"disabled": false

...

target_parameter (OPTIONAL, string)

The parameter used to pass a target address after authentication.

Example:

"target_parameter": "Target"

...

target_value (OPTIONAL, string)

The value used to pass a target address after authentication.

Example:

...

Fields used when the service uses direct mapping between IdPs and specific login URLs 

link_mapping REQUIRED (object)

...

languagejs

...

"target_value":

"https://example.com/math/resource"

If either target_parameter or target_value is present, the other MUST also be present.

target_value MAY be:

  • An absolute URI, or

  • An absolute-path reference beginning with /, optionally including query and fragment components, interpreted relative to the service’s own origin.

If sso_type is "entity_id"

These fields are required for a standard SAML SSO setup using the entity ID as parameter for identifying the IdP.

  • idp_parameter REQUIRED (str)

    • The parameter used to pass the IdP’s entity ID in the SSO request.
    • Example: "entityID".
  • sp_init REQUIRED (str, URL)

    • The URL for SP-initiated authentication.
    • Example: bjj/login?idp=example1-idp", "https://idp.example2.com": "https://example.com/bjj/login?idp=example2-idp", "https://idp.example3.com": "https://example.com/bjj/login?idp=example3-idp" },

Example metadata

...

languagejs

...

Fields used when the service uses direct mapping between IdPs and specific login URLs 

  • link_mapping REQUIRED (object)

    • A mapping where each IdP’s entity ID is used as a key, and the value is the specific login URL for that IdP.
    • Example:
      Code Block
      languagejs
      "link_mapping": {
      	"https://idp.example1.com": "https://example.com/bjj/login?idp=example1-idp",
      	"https://idp.example2.com": "https://example.com/

...

    • bjj/login?idp=example2-idp",
      

...

    • 	"https://idp.example3.com": "https://example.com/bjj/login?idp=example3-idp"
      

...

    • }, 

Example metadata

Code Block
languagejs
[
  {
    "ssoorganization_linksinfo": [
      {
        "description": "ExampleAn Digitalexample Mathdescription Service isof the numberservice one digital math companion in Schengenprovider organization",
        "disabled": false,
        "display_name": "MathExample Service RocketProvider",
        "entity_idlogotype": "https://example.com/mathlogo.svg",
        "idp_parametername": "entityIDExample Service Provider AB",
        "logourl": "https://example.com/math/logo.svg",
    },
    "spsso_initlinks": "https://example.com/math/Shibboleth.sso/Login?",[
        "sso_type": "entity_id",{
        "target_parameterdescription": "Target",
Example Digital Math Service is the number  "target_value": "https://example.com/math/resource"
      },
one digital math companion in Schengen",
         {"disabled": false,
        "descriptiondisplay_name": "Example Digital Brazilian Jiu-Jitsu Service is the number one digital BJJ teacher in SchengenMath Rocket",
        "entity_id": "https://example.com/math",
        "disabledidp_parameter": false"entityID",
        "display_namelogo": "Example Digital Brazilian Jiu-Jitsu Servicehttps://example.com/math/logo.svg",
        "entitysp_idinit": "https://example.com/bjjmath/Shibboleth.sso/Login?",
        "linksso_mappingtype": {
 "entity_id",
         "https://idp.example1.com"target_parameter": "https://example.com/bjj/login?idp=example1-idpTarget",
          "https://idp.example2.com"target_value": "https://example.com/bjj/login?idp=example2-idp"math/resource"
      },
      {
      "https://idp.example3.com  "description": "https://example.com/bjj/login?idp=example3-idp"
        }Example Digital Brazilian Jiu-Jitsu Service is the number one digital BJJ teacher in Schengen",
        "logodisabled": "https://example.com/bjj/logo.png"false,
        "ssodisplay_typename": "link_map"
Example Digital Brazilian    }Jiu-Jitsu Service",
    ]
  }
]

JSON schema

JSON schema for validating metadata:

Code Block
languagejs
{
  "$schemaentity_id": "httphttps://json-schemaexample.org/draft-07/schema#com/bjj",
        "typelink_mapping": "array",{
  "items": {
        "typehttps://idp.example1.com": "objecthttps://example.com/bjj/login?idp=example1-idp",
    "properties": {
      "organization_info": {
        "type": "objecthttps://idp.example2.com": "https://example.com/bjj/login?idp=example2-idp",
        "properties": {  "https://idp.example3.com": "https://example.com/bjj/login?idp=example3-idp"
          "description": { "type": "string" },
          "display_namelogo": { "type": "string" },
 https://example.com/bjj/logo.png",
         "logotype": { ""sso_type": "string", "format": "uri" },link_map"
      }
    ]
  }
]

JSON schema

The SSO links metadata MUST validate against the JSON schema found at https://fed.skolfederation.se/pilot/schemas/sso-links-metadata-schema-0_1.json.

Code Block
languagejs
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://fed.skolfederation.se/pilot/schemas/sso-links-metadata-schema-0_1.json",
  "title": "Skolfederation SSO Links Metadata",
  "type": "array",
  "minItems": 1,
  "items": {
    "type": "object",
    "properties": {"name": { "type": "string" },
          "url": { "type": "string", "format": "uri" }
        },
        "required": ["description", "display_name", "logotype", "name", "url"],
        "additionalProperties": false
      },
      "ssoorganization_linksinfo": {
        "type": "arrayobject",
        "itemsproperties": {
          "typedescription": "object",{
            "propertiestype": {"string",
            "descriptionminLength": { "type": "string"1
          },
            "disableddisplay_name": { "type": "boolean" },
            "display_name": { "type": "string" },
            "entity_idminLength": { "type": "string", "format": "uri"1
          },
            "idp_parameterlogotype": {
            "type": "string" },
            "logo": { "type": "string", "format": "uri" },
            "sp_initpattern": { "type": "string", "format": "uri"^https://"
          },
            "sso_typename": {
 "type": "string", "enum           "type": ["entity_idstring",
 "link_map"]           "minLength": 1
          },
            "target_parameterurl": {
            "type": "string" },
            "target_valueformat": { "$refuri",
            "pattern": "#^https:/definitions/uriOrRelativePath" },
            "link_mapping": {
              "type": "object",
              "minProperties": 1,
              "patternProperties": {
                ".*": { "type": "string", "format": "uri", "pattern": "^https://" }
              },
              "additionalProperties": false,
              "propertyNames": { "type": "string", "minLength": 1 }
            }
          },
          "required": ["description", "display_name", "entity_id", "logo", "sso_type"],
          "anyOf": [
            {
              "properties": { "sso_type": { "const": "entity_id" } },
              "required": ["idp_parameter", "sp_init"]
            },
            {
              "properties": { "sso_type": { "const": "link_map" } },
              "required": ["link_mapping"]
            }
          ]/"
          }
        },
        "required": [
          "description",
          "display_name",
          "logotype",
          "name",
          "url"
        ],
        "additionalProperties": false
      },
      "sso_links": {
        "type": "array",
        "minItems": 1,
        "items": {
          "type": "object",
          "properties": {
            "description": {
              "type": "string",
              "minLength": 1
            },
            "disabled": {
              "type": "boolean",
              "default": false
            },
            "display_name": {
              "type": "string",
              "minLength": 1
            },
            "entity_id": {
              "type": "string",
              "format": "uri"
            },
            "idp_parameter": {
              "type": "string",
              "minLength": 1
            },
            "logo": {
              "type": "string",
              "format": "uri",
              "pattern": "^https://"
            },
            "sp_init": {
              "type": "string",
              "format": "uri",
              "pattern": "^https://"
            },
            "sso_type": {
              "type": "string",
              "enum": [
                "entity_id",
                "link_map"
              ]
            },
            "target_parameter": {
              "type": "string",
              "minLength": 1
            },
            "target_value": {
              "$ref": "#/$defs/uriOrRelativePath"
            },
            "link_mapping": {
              "type": "object",
              "minProperties": 1,
              "patternProperties": {
                "^.+$": {
                  "type": "string",
                  "format": "uri",
                  "pattern": "^https://"
                }
              },
              "propertyNames": {
                "type": "string",
                "minLength": 1
              },
              "additionalProperties": false
            }
          },
          "required": [
            "description",
            "display_name",
            "entity_id",
            "logo",
            "sso_type"
          ],
          "dependentRequired": {
            "target_parameter": [
              "target_value"
            ],
            "target_value": [
              "target_parameter"
            ]
          },
          "oneOf": [
            {
              "properties": {
                "sso_type": {
                  "const": "entity_id"
                }
              },
              "required": [
                "idp_parameter",
                "sp_init"
              ],
              "not": {
                "required": [
                  "link_mapping"
                ]
              }
            },
            {
              "properties": {
                "sso_type": {
                  "const": "link_map"
                }
              },
              "required": [
                "link_mapping"
              ],
              "not": {
                "anyOf": [
                  {
                    "required": [
                      "idp_parameter"
                    ]
                  },
                  {
                    "required": [
                      "sp_init"
                    ]
                  }
                ]
              }
            }
          ],
          "additionalProperties": false
        }
      }
    },
    "required": [
      "organization_info",
      "sso_links"
    ],
    "additionalProperties": false
  },
  "$defs": {
    "uriOrRelativePath": {
      "anyOf": [
        {
          "type": "string",
          "format": "uri"
        },
        {
          "type": "string",
          "pattern": "^/(?!/)[^\\s]*$"
        }
      ]
    }
  }
}

IdP Discovery Metadata

The IdP Discovery Metadata feed provides a structured JSON representation of Identity Providers intended for consumption by:

  • Discovery services (WAYF / inverse discovery)

  • Login portals

  • Federation UI implementations

  • IdP selection interfaces

The purpose of this feed is to enable consistent and predictable presentation of Identity Providers across user-facing services.

This feed does not replace SAML metadata.
SAML metadata remains the authoritative source for federation trust and protocol configuration.

The IdP Discovery Metadata feed may be generated from one or more authoritative sources, including but not limited to federation SAML metadata.


...

IdP Discovery Metadata Data Model

The IdP Discovery Metadata feed MUST be a JSON array containing one object per Identity Provider.

Each IdP object MUST contain the following fields:

FieldRequiredTypeDescription
entity_idYESstring (URI)The SAML entityID of the IdP in the federation
descriptionYESstringA short description of the organization and its services
display_nameYESstringA user-friendly name for display purposes
logotypeYESstring (URI)URL to the organization's logo
nameYESstringThe official legal name of the organization
urlYESstring (URI)The official website of the organization

All properties are REQUIRED.

Additional properties MUST NOT be included.

...

Example metadata

Code Block
languagejs
[
  {
    "entity_id": "https://idp1.example.com/idp",
    "description": "Example Organization One Identity Provider for staff and student login.",
    "display_name": "Example Organization One",
    "logotype": "https://idp1.example.com/static/logo.svg",
    "name": "Example Organization One AB",
    "url": "https://www.example.com"
  },
  {
    "entity_id": "https://idp2.example.com/idp",
    "description": "Example Organization Two Identity Provider used for federated authentication.",
    "display_name": "Example Organization Two",
    "logotype": "https://idp2.example.com/static/logo.svg",
    "name": "Example Organization Two AB",
    "url": "https://org2.example.com"
  },
  {
    "entity_id": "https://idp3.example.com/idp",
    "description": "Example Organization Three Identity Provider supporting staff and student access.",
    "display_name": "Example Organization Three",
    "logotype": "https://idp3.example.com/static/logo.svg",
    "name": "Example Organization Three AB",
    "url": "https://org3.example.com"
  }
]


...

JSON schema

The IdP Discovery feed MUST validate against the JSON schema found at https://fed.skolfederation.se/pilot/schemas/idp-discovery-feed-schema-0_1.json

Code Block
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://fed.skolfederation.se/pilot/schemas/idp-discovery-feed-schema-0_1.json",
  "title": "Skolfederation IdP Discovery metadata feed",
  "type": "array",
  "minItems": 1,
  "items": {
    "type": "object",
    "properties": {
      "entity_id": {
        "type": "string",
          "allOfformat": ["uri"
      },
      "description": {
        "type": "string",
      "if": { "requiredminLength": ["target_parameter"] },1
           },
   "then": { "required": ["targetdisplay_valuename"]: }{
        "type": "string",
   },
     "minLength": 1
      {},
        "logotype": {
      "if": { "requiredtype": ["target_value"] }string",
        "format": "uri",
     "then":  { "requiredpattern": ["target_parameter"] }"^https://"
      },
      }"name": {
          ]"type": "string",
          "additionalPropertiesminLength": false1
        },
      "url": }{
      }  "type": "string",
        "requiredformat": ["organization_infouri", "sso_links"],

        "additionalPropertiespattern": false"^https://"
      },
   "definitions": { },
    "uriOrRelativePathrequired": {[
      "anyOf": [entity_id",
      "description",
  { "type": "string", "format": "uridisplay_name" },
      "logotype",
    { "type": "stringname", "pattern": "^/(?!/)[^\\s]*$" }
 
      "url"
     ],
    }"additionalProperties": false
  }
}


...

Validation and Encoding Requirements

For both metadata feeds:

  • Content-Type MUST be application/json

  • Encoding MUST be UTF-8

  • Feeds MUST validate against their respective JSON Schemas