Proposal of an improved Federation API

Issue #1382 resolved
Giuseppe De Marco created an issue

Instead of a single federation_api endpoint I would much rather 4 specialized fed api endpoints, named according to their specific operations. I wonder what might be a good semantics to name these endpoints, their purposes and their peculiar characteristics. On the track proposed by Roland I share a proposal below:

  • federation_statement (FETCH), performs the current federation_api fetch function, it’s required only for intermediaries and trust anchors and its result can be cached or served as a static content. My proposal would like to get even more than a single statement at this endpoint, with an appropriate pagination. Exactly as it is in SAML2 with MDQ, if the subject is specified the endpoint would return the single statement otherwise all the statements in a single metadata, in our case this response MUST be paginated. Here a proposal of a FETCH response:

request for a single member/subject

GET /federation_statement_fetch?sub=https%3A%2F%2Fspid.example.it HTTP/1.1
Host: openid.sunet.se

response

200 OK
Last-Modified: Mon, 17 Dec 2018 11:15:56 GMT
Content-Type: oidc-federation-statement-fetch+jwt

{
 "alg": "RS256",
 "kid": "WU52Y3MxX0VTYWs0b1pwbXAxcVkzd1Y5YnY3OWJHeUZXczgtRl9Lc3VDTQ",
 "typ": "oidc-federation-statement-fetch+jwt"
}
.
{
  "iss": "https://openid.sunet.se",
  "iat": 1620050972,
  "exp": 1620072515,
  "statements": [
    {
      "iss": "https://openid.sunet.se",
      "sub": "https://spid.example.it",
      "iat": 1516239022,
      "exp": 1516298022,
      "metadata": {
        "openid_relying_party": {
          "application_type": "web",
          "redirect_uris": [
            "https://spid.example.it/rp/callback"
          ],
          "organization_name": "example",
          "logo_uri": "https://www.example.it/images/32x32.png",
          "grant_types": [
            "authorization_code"
          ],
          "signed_jwks_uri": "https://spid.example.it/rp/jwks.json"
        }
      },
      "jwks": {
        "keys": [
          {
            "alg": "RS256",
            "e": "AQAB",
            "key_ops": [
              "verify"
            ],
            "kid": "key1",
            "kty": "RSA",
            "n": "pnXBOusEANuug6ewezb9J_...",
            "use": "sig"
          }
        ]
      },
      "authority_hints": [
        "https://spid.registry.agid.it"
      ]
    }
  ],
  "page": 1,
  "total_pages": 1,
  "total_entries": 1,
  "next_page_path": "",
  "prev_page_path": ""
}

request for ALL THE AVAILABLE subjects

GET /federation_statement_fetch HTTP/1.1
Host: openid.sunet.se

... as seen in the previous example, the pagination would do the job. The entity statements will be many inside the “statements” list.

  • federation_list, performs the current federation_api listing with several changes compared to the current implementation, it would return a JWT object with the “entities“ claim valued as follows. Only the iat claim for each entity is REQUIRED, other claims may be supported as optionals. Each page must have not more than 100 entries, this allows us to serve these page as static contents (with a smart httpd rewrite rule). The claim “iat”, in root of the JWT, determine if the resultset have been updated.
    The entities resultset must have a descendant ordering with higher iat on top, so as to explain which entities have been added or updated lately.

FeDERATION LIST RESPONSE

{
 "alg": "RS256",
 "kid": "WU52Y3MxX0VTYWs0b1pwbXAxcVkzd1Y5YnY3OWJHeUZXczgtRl9Lc3VDTQ",
 "typ": "oidc-federation-listing+jwt"
}
.
{
 "iss": "https://openid.sunet.se",
 "iat": 1620050972,
 "entities": [
   {
    "https://ntnu.andreas.labs.uninett.no/": {
       "iat": 1588455866,
   },
   {
    "https://blackboard.ntnu.no/openid/callback": {
       "iat": 1588455856,
   },
   {
    "https://serviceprovider.say.no/": {
       "iat": 1588355866,
   },
   ... # many other entries
 ],
"page": 1,
"total_pages": 2,
"total_entries": 189,
"next_page_path": "/federation_listing?page=2",
"prev_page_path": ""
}
  • federation_trustmark_introspection, allows a verifier to submit a trustmark in the form of a JWT and obtain an introspection of this. This endpoint allows you to verify in real time whether a trust mark has been disabled/revoked by its issuer. This endpoint is mandatory for all anchor trusts that issue trust marks. Below is a proposal for its possible use, Roland will create a PR for this. This endpoint is protected by private_key_jwt client authentication

FEDERATION TRUSTMARK INTROSPECTION REQUEST

POST /federation_trustmark_introspection HTTP/1.1
Host: openid.sunet.se
Content-Type: application/x-www-form-urlencoded

trustmark=2Yot [... many other bytes ofthe signed JWT ...] WpAA
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=PHNhbWxwOl[...omitted for brevity...]ZT

FEDERATION TRUSTMARK INTROSPECTION RESPONSE

HTTP/1.1 200 OK
Content-Type: application/federation-trustmark-introspection+jwt

{
 "typ": "federation-trustmark-introspection+jwt",
 "alg": "RS256",
 "kid": "wG6D"
}
.
{
 "iss":"https://openid.sunet.se",
 "iat":1514797892,
 "active":true,
 "sub":"https://that.trustmarked.memb.er"
}
  • federation_trust_negotiation, performs the current federation_api resolve_metadata operation.

The value for a paged result

The proposal to obtain a pagination of the results with an order of these that exposes on top the entities recently updated or added, wants to cover effectively the following use cases:

  • Federation resilience. Having a way to get in sync in a time T with the latest changes published by intermediaries and trusted anchors even though their endpoints federation_api are unreachable in a time T+1, makes the entire federation more resilient. This strategy avoids the concentration of many connections to the endpoints during the hot moments of the days (from 10am to 3pm). DDOS on an Internet backbone or any other service interruption may be wary of creating trust between an RP and an OP.
  • Delta of latest updates. Getting a delta of the latest changes (with a paginated result set with a descendant ordering based on iat) allow members of a federation to update/create their own chains of trust with a polling strategy. They would create or update only the trust chains that requires to be created or updated. If nothing have changed in the relation established between a leaf and a trust anchor the trust chains of that leaf can be used as they are. This strategy, not mandatory but entirely optional, would significantly reduce the cost of exchanges between members within a federation.
  • SIOP, cross device use case with offline interactions.

SIOP story

we are in an underground discoteque/market with poor bandwidth. If the wallet keeps updating the federation statements it will work completely offline even for cross device communications.

I need to establish a trust with the requester and this latter needs to establish a trust with the sender, nowaday for offline validations of covid green certificates, the mobile apps need to download the certificates and the revocation list. With oidc fed they just have to keep the trust chains updated.

Even more on mobile devices, using sqlite3, it would be trivial the storage of millions of entries, the updating process just need a way to get the delta of the members to get in sync with their trust chains (here paged result with descending iat makes the job).

Comments (8)

  1. Michael Jones
    • changed status to open

    This was discussed on the 10-Jan-22 call. As noted by Roland in issue #1387, being able to use discovery for separate endpoints would be cleaner.

  2. Giuseppe De Marco reporter

    I feel I can change my mind about the FETCH operation, this must not be paginated because it must release nothing but a single statement. An endpoint, an output.

    Perhaps, but this will be the decision of the federation authorities that participate in the work, in our implementation will also be added an endpoint to fetch multiple statements (statements listing). My proposal was to normalize the output so that a statement or more than one, within a response, would not change the structure, leading the implementers to be able to generalize the code.

    I am sure that in the implementation on which I am working we will have, also, an endpoint of paginated listing (entities listing), as in the previous example, with descending ordering on the last updated/added entities.

    With PR 108 Roland made the most important change, so that we can close this issue. If we could add or change other aspects related to what I have described in this issue, we can reserve the pleasure to propose it later, on a consolidated draft

  3. Log in to comment