ldeveloperl1985 / wg-otto

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Open Trust Taxonomy for Federation Operators

Table of Contents

Abstract

The Open Trust Taxonomy for Federation Operators (OTTO) is a set of API's and a linked data schema to enable the formation of multi-party federations--where a central authority creates the rules for membership, enabling the participants to more efficiently collaborate. The goal of OTTO is to support a range of trust models from very low to very high. By providing a framework for extension, in addition to a core set of functionality and schema, the OTTO standard provides a scalable technical infrastructure to solve organizational challenges in a number of different ecosystems.

Big picture

Definitions

Registration Authority have metadata describing their configuration. These Registration Authority Metadata values are used by OTTO:

  • issuer - REQUIRED. URL using the https scheme with no query or fragment component that the RA asserts as its Issuer Identifier. If Issuer discovery is supported, this value MUST be identical to the issuer value returned by WebFinger.
  • federations_endpoint - REQUIRED. federations endpoint
  • federation_entity_endpoint - REQUIRED. federation entity endpoint
  • organizations_endpoint - REQUIRED. organization endpoint
  • schema_endpoint - REQUIRED. schema endpoint

Registration Authority supporting Discovery MUST make a JSON document available at the path formed by concatenating the string /.well-known/otto-configuration to the Issuer. The syntax and semantics of .well-known are defined in RFC 5785 [RFC5785] and apply to the Issuer value when it contains no path component. otto-configuration MUST point to a JSON document compliant with this specification and MUST be returned using the application/json content type.

Non-normative example request

GET /.well-known/otto-configuration HTTP/1.1
Host: ra.com

The response is a set of Claims about the RA's configuration, including all necessary endpoints and public key location information. A successful response MUST use the 200 OK HTTP status code and return a JSON object using the application/json content type that contains a set of Claims as its members that are a subset of the RA's Metadata values. Other Claims MAY also be returned. Claims that return multiple values are represented as JSON arrays. Claims with zero elements MUST be omitted from the response. An error response uses the applicable HTTP status code value.

Non-normative example response

HTTP/1.1 200 OK
Content-Type: application/json

{
   "issuer":"https://ra.com",
   "federations_endpoint":"https://ra.com/otto/federations",
   "federation_entity_endpoint":"https://ra.com/otto/entity",
   "organizations_endpoint":"https://ra.com/otto/organizations",
   "schema_endpoint":"https://ra.com/otto/schema"
}

federations endpoint

Search Federations (GET)

Endpoint to return federation metadata or federation IDs that are hosted by given server.

Request:

  • federation_id - OPTIONAL - id of federation.
  • entity_type - OPTIONAL - filter to return federation entities only of specific type. For example OpenID Connect OP implementation in general is interested only in OpenID Connect RP entity because it's going to server only Connect RP requests. Such implementation is not interested in any UMA or SAML or OAuth2 entities. For this we provide filtering functionality. Possible values:
    • oauth2_rp
    • oauth2_op
    • connect_rp
    • connect_op
    • uma_rs
    • uma_rp
    • uma_as
  • filter - OPTIONAL - expression to narrow the result set based on specific criteria. Expression is represented in jspath format (https://github.com/dfilatov/jspath).
  • depth - OPTIONAL - represents depth of graph resolving. &depth=federations&depth=federations.entitites.organization.

Requests:

  • /federations - returns federation IDs available from this Registration Authority
  • /federations/federation id - returns metadata of federation
  • /federations/federation id&entity_type=type - returns metadata of federation filtered by type.
  • /federations/federation id&filter=filter - returns filtered metadata
  • /federations/federation id&depth=1 - how many interfederations deep to search

Federation list Request:

GET https://ra.org/federations HTTP/1.1

Federation list Response:

{
  "@context": "https://ra.org/schema/otto/federation_list",
  "federations": [
    "https://ra.org/federations/904ca9da-c5a6-11e5-9912-ba0be0483c18",
    "https://ra.org/federations/904cae1c-c5a6-11e5-9912-ba0be0483c18",
    "https://ra.org/federations/904cb092-c5a6-11e5-9912-ba0be0483c18"
  ]
}

Federation Request:

GET https://ra.org/federations/904cb092-c5a6-11e5-9912-ba0be0483c18 HTTP/1.1

Federation Response:

{
  "@context": "https://ra.org/schema/otto/federation.jsonld",                      <- context of federation
  "name": "OAuth 2 Federation",                                                    <- name of federation
  "entities":[
            {                                                                      <- reference to entity
                        "@context": "https://ra.org/schema/otto/entity/connect_rp.jsonld",
                        "uri": "https://ra.org/entity/664cb092-c5a6-11e5-9912-ba0be0483c18",
                        "name": "Gluu Server Ce-dev Client",
                        "id":"https://ce-dev.gluu.org/rp",          <- in RP context it is redirect_uri
                        "organization":"https://gluu.org/otto/organization"
            },
            {
                         "@context": "https://ra.org/schema/otto/entity/connect_op.jsonld",
                         "uri": "https://ra.org/entity/554cb092-c5a6-11e5-9912-ba0be0483c18",
                         "name": "Gluu Server Ce-dev",
                         "id":"https://ce-dev.gluu.org"           <- in OP context it is URI
                         "organization":"https://gluu.org/otto/organization"
            },
            {
                         "@context": "https://ra.org/schema/otto/entity/uma_rs.jsonld",
                         "uri": "https://ra.org/entity/904cb092-c5a6-11e5-9912-ba0be0483c18",
                         "name": "Gluu Resource Server",
                         "id":"https://ce-dev.gluu.org/rs",          <- in RS context it is URI
                         "organization":"https://gluu.org/otto/organization"
            }
  ]
  "federations":[                                                                  <- reference to federation
                         "https://ra.org/federations/904cb092-c5a6-11e5-9912-ba0be0483c18"
           ],
  "organization": {
                    "@context": "https://ra.org/schema/otto/organization.jsonld",   <- organization
                     "name":"MyOrganization",
                     <other properties here>
                  }
}

Create (POST)

Request:

POST /federations
{
   "name":"MyFederation",
   <other properties here>
}

Response:

HTTP/1.1 201 Created
Content-Type: application/json

{
   "id":"https://ra.org/federations/904cb092-c5a6-11e5-9912-ba0be0483c18"
}

Update (PUT)

Request:

PUT /federations/904cb092-c5a6-11e5-9912-ba0be0483c18 HTTP/1.1
{
   "name":"MyFederation",
   <other properties here>
}

Response:

HTTP/1.1 200 OK

Delete (DELETE)

Request:

DELETE /federations/904cb092-c5a6-11e5-9912-ba0be0483c18 HTTP/1.1

Response:

HTTP/1.1 200 OK

Join federation (POST)

It may create entity and join the federation or otherwise join already existed entity.

Request

POST /federations/<federation_id> HTTP/1.1
{
   "name":"MyEntity",
   <other properties here>
}

Response

HTTP/1.1 200 OK

Leave federation (DELETE)

Leave federation.

Request

DELETE /federations/<federation_id>/<entity id> HTTP/1.1

Response

HTTP/1.1 200 OK

federation_entity endpoint

Fetch (GET)

Entity Request:

GET https://ra.org/federation_entity/194d8ab2-c5a7-11e5-9912-ba0be0483c18 HTTP/1.1

OpenID Connect OP Entity Response:

{
  "@context": "https://ra.org/schema/otto/entity/connect_op.jsonld",
  "name": "Gluu Server Ce-dev",
  "id":"https://ce-dev.gluu.org"           <- in OP context it is URI
  "organization":"https://gluu.org/otto/organization"
}

OpenID Connect RP Entity Response:

{
  "@context": "https://ra.org/schema/otto/entity/connect_rp.jsonld",
  "name": "Gluu Server Ce-dev Client",
  "id":"https://ce-dev.gluu.org/rp",          <- in RP context it is redirect_uri
  "organization":"https://gluu.org/otto/organization"
}

UMA Resource Server Entity Response:

{
  "@context": "https://ra.org/schema/otto/entity/uma_rs.jsonld",
  "name": "Gluu Resource Server",
  "id":"https://ce-dev.gluu.org/rs",          <- in RS context it is URI
  "organization":"https://gluu.org/otto/organization"
}

Create (POST)

Request:

POST /federation_entity
{
   "name":"MyFederationEntity",
   <other properties here>
}

Response:

HTTP/1.1 201 Created
Content-Type: application/json

{
   "id":"https://ra.org/federation_entity/904cb092-c5a6-11e5-9912-ba0be0483c19"
}

Update (PUT)

Request:

PUT /federation_entity/<entity id> HTTP/1.1
{
   "name":"MyEntity",
   <other properties here>
}

Response:

HTTP/1.1 200 OK

Delete (DELETE)

Request:

DELETE /federation_entity/<entity id> HTTP/1.1

Response:

HTTP/1.1 200 OK

schema endpoint

Schema list Request:

GET https://ra.org/schema/v1.1 HTTP/1.1

(Schema sticks to particular version which is shown directly in URL. E.g. GET https://ra.org/schema/v2.1)

Schema list Response:

{
  "schemas": [
    "https://ra.org/schema/v1.1/hash",
    "https://ra.org/schema/v1.1/organization",
    "https://ra.org/schema/v1.1/federations",
    "https://ra.org/schema/v1.1/openid_provider",
    "https://ra.org/schema/v1.1/openid_relying_party",
    "https://ra.org/schema/v1.1/uma_rs",
    "https://ra.org/schema/v1.1/uma_as",
    "https://ra.org/schema/v1.1/uma_ro"
  ]
}

Schema Request:

GET https://ra.org/schema/v1.1/hash HTTP/1.1

Schema hash v1.1 Response:

    {
       "@context": {
         "otto": "http://kantarainitiative.org/otto/schema/",
         "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
         "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
         "schema": "http://schema.org/",
         "xsd": "http://www.w3.org/2001/XMLSchema#"
       },
       "@graph": [
         {
           "@id": "otto:hashValue",
           "@type": "rdf:Property",
           "rdfs:range": {
             "@id": "xsd:string"
           }
         },
         {
           "@id": "otto:Hash",
           "@type": "rdfs:Class"
         },
         {
           "@id": "otto:hashAlgorithm",
           "@type": "rdf:Property",
           "rdfs:range": {
             "@id": "xsd:string"
           }
         }
       ]
    }

Create (POST)

Request:

POST /schema
{
   "name":"myentity",
   "major_version":"1",
   "minor_version":"2"
   <other properties here>
}

Response:

HTTP/1.1 201 Created
Content-Type: application/json

{
   "id":"https://ra.org/schema/1.2/myentity"
}

Update (PUT)

Request:

PUT /schema HTTP/1.1
{
   "name":"myentity",
   "major_version":"1",
   "minor_version":"2"
   <other properties here>
}

Response:

HTTP/1.1 200 OK

Delete (DELETE)

Request:

DELETE /schema/v1.2/myentity HTTP/1.1

Response:

HTTP/1.1 200 OK

organization endpoint

Organizations list Request:

GET https://ra.org/organization HTTP/1.1

Organizations list Response:

{
  "@context": "https://ra.org/schema/otto/organization",
  "organizations": [
    "https://ra.org/organization/904ca9da-c5a6-11e5-9912-ba0be0483c18",
    "https://ra.org/organization/904cae1c-c5a6-11e5-9912-ba0be0483c18",
    "https://ra.org/organization/904cb092-c5a6-11e5-9912-ba0be0483c18"
  ]
}

Organization Request:

GET https://ra.org/organization/904cb092-c5a6-11e5-9912-ba0be0483c18 HTTP/1.1

Organization Response:

{
  "@context": "https://ra.org/schema/otto/organization.jsonld",                      <- context of organization
   "name":"MyOrganization",
   <other properties here>
}

Create (POST)

Request:

POST /organization
{
   "name":"MyOrganization",
   <other properties here>
}

Response:

HTTP/1.1 201 Created
Content-Type: application/json

{
   "id":"https://ra.org/organization/904cb092-c5a6-11e5-9912-ba0be0483c18"
}

Update (PUT)

Request:

PUT /organization/904cb092-c5a6-11e5-9912-ba0be0483c18 HTTP/1.1
{
   "name":"MyOrganization",
   <other properties here>
}

Response:

HTTP/1.1 200 OK

Delete (DELETE)

Request:

DELETE /organization/904cb092-c5a6-11e5-9912-ba0be0483c18 HTTP/1.1

Response:

HTTP/1.1 200 OK

Linked Data Schema

Properties

Properties :

schema/otto/hash.jsonld

    @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
    @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
    @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
    @prefix schema: <http://schema.org/> .
    @prefix otto: <http://kantarainitiative.org/otto/schema/> .

    # Ontology

    otto:Hash a rdfs:Class .

    otto:hashValue a rdf:Property ;
     rdfs:range xsd:string;
     .

    otto:hashAlgorithm a rdf:Property ;
     rdfs:range xsd:string;
     .

hash.jsonld

   {
     "@context": {
       "otto": "http://kantarainitiative.org/otto/schema/",
       "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
       "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
       "schema": "http://schema.org/",
       "xsd": "http://www.w3.org/2001/XMLSchema#"
     },
     "@graph": [
       {
         "@id": "otto:hashValue",
         "@type": "rdf:Property",
         "rdfs:range": {
           "@id": "xsd:string"
         }
       },
       {
         "@id": "otto:Hash",
         "@type": "rdfs:Class"
       },
       {
         "@id": "otto:hashAlgorithm",
         "@type": "rdf:Property",
         "rdfs:range": {
           "@id": "xsd:string"
         }
       }
     ]
   }

schema/otto/openid_provider.jsonld

External extensions JSON-LD basic concept

    @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
    @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
    @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
    @prefix schema: <http://schema.org/> .
    @prefix otto: <http://kantarainitiative.org/otto/schema/> .

    # Ontology

    otto:OpenID_Provider a rdfs:Class .

    otto:discoveryURL a rdf:Property ;
     rdfs:range xsd:anyURI;
     .

    otto:discoveryJSONHash a rdf:Property ;
     rdfs:range otto:Hash;
     .

    otto:providedBy a rdf:Property ;
     rdfs:range schema:Organization;
     .

    otto:jwksJSONHash a rdf:Property ;
     rdfs:range otto:Hash ;
     .

    # Instance data  TODO -> need to set instance data correctly

    <https://ra.org/federations/904cb092/c5a6-11e5-9912-ba0be0483c18>
     a schema:Thing, otto:OpenID_Provider;
     otto:discoveryURL "https://idp.example.com/.well-known/openid-configuration" ;
     otto:discoveryJSONHash "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12";
     otto:jwksJSONHash "de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3";
     otto:providedBy <https://fc.com/otto/organization/904cb092/230948-DFJLK>;

openid_provider.jsonld

   {
        "@context": {
          "otto": "http://kantarainitiative.org/otto/schema/",
          "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
          "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
          "schema": "http://schema.org/",
          "xsd": "http://www.w3.org/2001/XMLSchema#"
        },
        "@graph": [
          {
            "@id": "otto:jwksJSONHash",
            "@type": "ott:Hash"
          },
          {
            "@id": "otto:OpenID_Provider",
            "@type": "rdfs:Class"
          },
          {
            "@id": "otto:discoveryURL",
            "@type": "rdf:Property",
            "rdfs:range": {
              "@id": "xsd:anyURI"
            }
          },
          {
            "@id": "otto:providedBy",
            "@type": "rdf:Property",
            "rdfs:range": {
              "@id": "schema:Organization"
            }
          },
          {
             "@id": "otto:discoveryJSONHash",
             "@type": "otto:Hash"
          },
          {
            "@id": "https://ra.org/federations/904cb092/c5a6-11e5-9912-ba0be0483c18",
            "@type": [
              "otto:OpenID_Provider",
              "schema:Thing"
            ],
            "otto:discoveryJSONHash": "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12",
            "otto:discoveryURL": "https://idp.example.com/.well-known/openid-configuration",
            "otto:jwksJSONHash": "de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3",
            "otto:providedBy": {
              "@id": "https://fc.com/otto/organization/904cb092/230948-DFJLK"
            }
          },
        ]
      }

schema/otto/openid_relying_party.jsonld

    @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
    @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
    @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
    @prefix schema: <http://schema.org/> .
    @prefix otto: <http://kantarainitiative.org/otto/schema/> .

    # Ontology

    otto:OpenID_Relying_Party a rdfs:Class .

    otto:redirect_uris a rdf:Property ;
     rdfs:range xsd:anyURI;
     .

    otto:jwks_uri a rdf:Property ;
     rdfs:range xsd:anyURI;
     .

    otto:sector_identifier_uri a rdf:Property ;
     rdfs:range xsd:anyURI;
     .

    otto:initiate_login_uri a rdf:Property ;
     rdfs:range xsd:anyURI;
     .

    otto:logout_uri a rdf:Property ;
     rdfs:range xsd:anyURI;
     .

    otto:entity_category a rdf:Property ;
     rdfs:range xsd:anyURI;
     .

schema/otto/uma_rs.jsonld


    @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
    @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
    @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
    @prefix schema: <http://schema.org/> .
    @prefix otto: <http://kantarainitiative.org/otto/schema/> .

    # Ontology

    otto:UMA_Resource_Server a rdfs:Class .

    otto:resource_server_uri a rdf:Property ;
     rdfs:range xsd:anyURI;
     .

    otto:resource_set_uris a rdf:Property ;
     rdfs:range xsd:anyURI;
     .

schema/otto/uma_as.jsonld


    @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
    @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
    @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
    @prefix schema: <http://schema.org/> .
    @prefix otto: <http://kantarainitiative.org/otto/schema/> .

    # Ontology

    otto:UMA_Authorization_Server a rdfs:Class .

    otto:discoveryURL a rdf:Property ;
     rdfs:range xsd:anyURI;
     .

    otto:discoveryJSONHash a rdf:Property ;
     rdfs:range otto:Hash;
     .

schema/otto/uma_relying_party.jsonld

    @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
    @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
    @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
    @prefix schema: <http://schema.org/> .
    @prefix otto: <http://kantarainitiative.org/otto/schema/> .

    # Ontology

    otto:UMA_Relying_Party a rdfs:Class .

    otto:redirect_uris a rdf:Property ;
     rdfs:range xsd:anyURI;
     .

    otto:jwks_uri a rdf:Property ;
     rdfs:range xsd:anyURI;
     .

    otto:sector_identifier_uri a rdf:Property ;
     rdfs:range xsd:anyURI;
     .

    otto:initiate_login_uri a rdf:Property ;
     rdfs:range xsd:anyURI;
     .

    otto:logout_uri a rdf:Property ;
     rdfs:range xsd:anyURI;
     .

    otto:entity_category a rdf:Property ;
     rdfs:range xsd:anyURI;
     .

Appendix A

Search federations endpoint : /federations/<federation id>?depth=federations

All entities are resolved and federations link too with depth=federations

Federation Request:

GET https://ra.org/federations/904cb092-c5a6-11e5-9912-ba0be0483c18&depth=federations HTTP/1.1

Federation Response:

{
  "@context": "https://ra.org/schema/otto/federation.jsonld",                      <- context of federation
  "name": "OAuth 2 Federation",                                                    <- name of federation
  "entities": [                                                                    <- reference to entity
           {
             "@context": "https://ra.org/schema/otto/entity/connect_rp.jsonld",
             "uri": "https://ra.org/entity/664cb092-c5a6-11e5-9912-ba0be0483c18",
             "name": "Gluu Server Ce-dev Client",
             "id":"https://ce-dev.gluu.org/rp",          <- in RP context it is redirect_uri
             "organization":"https://gluu.org/otto/organization"
           },
           {
             "@context": "https://ra.org/schema/otto/entity/uma_rs.jsonld",
             "uri": "https://ra.org/entity/114cb092-c5a6-11e5-9912-ba0be0483c18",
             "name": "Gluu Resource Server",
             "id":"https://ce-dev.gluu.org/rs",          <- in RS context it is URI
             "organization":"https://gluu.org/otto/organization"
           }
  ],
  "federations":[
         {
                 "@context": "https://ra.org/schema/otto/federation.jsonld",                      <- context of sub federation
                 "name": "OAuth 2 Federation of Gluu",                                          <- name of sub federation
                 "entities":[
                          {                                                                    <- reference to entity
                            "@context": "https://ra.org/schema/otto/entity/connect_rp.jsonld",
                            "uri": "https://ra.org/entity/134cb092-c5a6-11e5-9912-ba0be0483c18",
                            "name": "Gluu Server Ce-dev2 Client",
                            "id":"https://ce-dev2.gluu.org/rp",          <- in RP context it is redirect_uri
                            "organization":"https://gluu.org/otto/organization"
                          },
                          {
                            "@context": "https://ra.org/schema/otto/entity/uma_rs.jsonld",
                            "uri": "https://ra.org/entity/344cb092-c5a6-11e5-9912-ba0be0483c18",
                            "name": "Gluu Resource Server 2",
                            "id":"https://ce-dev2.gluu.org/rs",          <- in RS context it is URI
                            "organization":"https://gluu.org/otto/organization"
                          }
                 ]
                 "federation": [                                                                 <- reference to federation
                          "https://ra.org/federations/222cb092-c5a6-11e5-9912-ba0be0483c18"
                 ]
                 "organization": "https://gluu.org/otto/organization"
        }
  ],
  "organization": {
                    "@context": "https://ra.org/schema/otto/organization.jsonld",   <- organization
                     "name":"MyOrganization",
                     <other properties here>
                  }
}

Search federations endpoint : /federations/<federation id>?depth=federations&filter=<filter>

Returns only .entity.name attributes.

Federation Request:

GET https://ra.org/federations/904cb092-c5a6-11e5-9912-ba0be0483c18&filter=.entity.name HTTP/1.1

Federation Response:

{
  "@context": "https://ra.org/schema/otto/federation.jsonld",                      <- context of federation
  "name": "OAuth 2 Federation",                                                    <- name of federation
  "entities": [
           {                                                                       <- reference to entity
             "name": "Gluu Server Ce-dev Client"
           },
           {
             "name": "Gluu Resource Server"
           },
           {
             "name": "Gluu Resource Server 2",
           }
   ],
  "federations":[                                                                  <- reference to federation
           "https://ra.org/federations/222cb092-c5a6-11e5-9912-ba0be0483c18"
  ],
  "organization": {
                    "@context": "https://ra.org/schema/otto/organization.jsonld",   <- organization
                     "name":"MyOrganization",
                     <other properties here>
                  }
}

(in case of multiple attributes specify multiple filter parameters as mentioned on wiki https://en.wikipedia.org/wiki/Query_string) &filter=.entity.name&filter=.entity.id

Questions

  • How are we going version federation metadata?
  • How are we going version entities ? E.g. UMA RP 1.0 vs UMA RP 1.0.1 implementation.
  • Do we want to support custom entities?

About

License:MIT License