Subject: [Txauth] Turning polymorphism up to 11 (P11)

From: Dick Hardt <[email-masked]>
Date: Fri, 10 Jul 2020 18:01:17 -0700

Taking Justin's model of strings being shortened versions of OAuth scopes,
adding in the "type" property from RAR, and defining a default type, we
*could* add a bunch of polymorphism. (I have not implemented the code
below, but it looks doable assuming I have not overloaded a type in the
same context)

/Dick

Let's start with a request for 2 authorizations using OAuth scopes, one for
writing and the other for reading:

(1)
{
    "authorizations": {
        "writer": [
            {
                "type": "oauth_scope",
                "scope": ["create","update","delete"]
            }
        ],
        "reader": [
            {
                "type": "oauth_scope",
                "scope": ["read","list"]
            }
        ]
    }
}

We can ask for just one token with all the same capabilities:
(2)
{
    "authorizations": [
        {
            "type": "oauth_scope",
            "scope": ["create","update","delete"]
        },
        {
            "type": "oauth_scope",
            "scope": ["read","list"]
        }
    ]
}

Of course (2) can be simplified as:
(3)
{
    "authorizations": [
        {
            "type": "oauth_scope",
            "scope": ["create","update","delete","read","list"]
        }
    ]
}

Now let's say that in "oauth_scope", the array of scopes can also be a
space separated string. So the following is equivalent:
(4)
{
    "authorizations": [
        {
            "type": "oauth_scope",
            "scope": "create update delete read list"
        }
    ]
}

Now let's say that the "oauth_scope" type is the default, so we can express
it as:
(5)
{
    "authorizations": ["create","update","delete","read","list"]
}

Or use a space separated string instead of an array:
(6)
{
    "authorizations": "create update delete read list"
}

In summary, (2) - (6) will give the exact same result.

Let's add another authorization type to the request, "customer_information":
(7)
{
    "authorizations": [
        "create update delete read list",
        {
            "type": "customer_information",
            "locations": [
                "https://example.com/customers",
            ],
            "actions": [
                "read"
            ],
            "datatypes": [
                "contacts",
                "photos"
            ]
        }
    ]
}

And the space separated strings can be turned into individual strings and
we have the equivalent request:
(8)
{
    "authorizations": [
        "create",
        "update",
        "delete",
        "read",
        "list",
        {
            "type": "customer_information",
            "locations": [
                "https://example.com/customers",
            ],
            "actions": [
                "read"
            ],
            "datatypes": [
                "contacts",
                "photos"
            ]
        }
    ]
}

Let's go back to our first example, and ask for 3 separate tokens:
(9)
{
    "authorizations": {
        "writer": "create update delete",
        "reader": "read list",
        "customer": [
            {
                "type": "customer_information",
                "locations": [
                    "https://example.com/customers",
                ],
                "actions": [
                    "read"
                ],
                "datatypes": [
                    "contacts",
                    "photos"
                ]
            }
        ]
    }
}

In a multi token request, if there is only one item in the array, we can
shorten (9) to the following:
(10)
{
    "authorizations": {
        "writer": "create update delete",
        "reader": "read list",
        "customer": {
            "type": "customer_information",
            "locations": [
                "https://example.com/customers",
            ],
            "actions": [
                "read"
            ],
            "datatypes": [
                "contacts",
                "photos"
            ]
        }
    }
}

---

From: Dick Hardt <[email-masked]>
Date: Sun, 12 Jul 2020 17:55:19 -0700

For those not familiar with "turning up to 11"
https://en.wikipedia.org/wiki/Up_to_eleven

A counter argument to all of this polymorphism is that the AS is sending
back the granted authorization. While pushing type detection to the AS to
provide a simpler interface for the Client, it seems counterproductive if
the Client has to do the same. A consistent response from the AS will be
simpler for the Client, but would then also be different then what the
Client originally requested from the GS.

On Fri, Jul 10, 2020 at 6:01 PM Dick Hardt <[email-masked]> wrote:

> Let's start with a request for 2 authorizations using OAuth scopes, one
> for writing and the other for reading:
>
> (1)
> {
>     "authorizations": {
>         "writer": [
>             {
>                 "type": "oauth_scope",
> Now let's say that the "oauth_scope" type is the default, so we can
> express it as:
> (5)
> {

---

From: Yaron Sheffer <[email-masked]>
Date: Mon, 13 Jul 2020 12:02:50 +0300

<no hats>

The issue of polymorphism is somewhat religious, similarly to strong vs. weak typing in programming languages, and I am of the non-polymorphic (unimorphic?) persuasion. Specifically when it comes to security protocols, where a recipient misunderstanding a value can easily result in a vulnerability.

With respect to a schema language, IMO the fact that it is difficult to express some polymorphic constructs in JSON Schema is a reason to avoid these constructs, rather than go looking for a different schema language.

Thanks,

                Yaron

From: Txauth <[email-masked]> on behalf of Dick Hardt <[email-masked]>
Date: Monday, July 13, 2020 at 03:56
To: <[email-masked]>
Subject: Re: [Txauth] Turning polymorphism up to 11 (P11)

For those not familiar with "turning up to 11" https://en.wikipedia.org/wiki/Up_to_eleven

A counter argument to all of this polymorphism is that the AS is sending back the granted authorization. While pushing type detection to the AS to provide a simpler interface for the Client, it seems counterproductive if the Client has to do the same. A consistent response from the AS will be simpler for the Client, but would then also be different then what the Client originally requested from the GS.

Taking Justin's model of strings being shortened versions of OAuth scopes, adding in the "type" property from RAR, and defining a default type, we *could* add a bunch of polymorphism. (I have not implemented the code below, but it looks doable assuming I have not overloaded a type in the same context)

/Dick

Let's start with a request for 2 authorizations using OAuth scopes, one for writing and the other for reading:

(1)

{

    "authorizations": {

        "writer": [

            { 

                "type": "oauth_scope",

            }

        ],

        "reader": [

            { 

                "type": "oauth_scope",

                "scope": ["read","list"]

            }

        ]

    }

}

(2)

{

    "authorizations": [

        { 

            "type": "oauth_scope",

        },

        { 

            "type": "oauth_scope",

            "scope": ["read","list"]

        }

    ]

}

(3)

{

    "authorizations": [

        { 

            "type": "oauth_scope",

        }

    ]

}

Now let's say that in "oauth_scope", the array of scopes can also be a space separated string. So the following is equivalent:

(4)

{

    "authorizations": [

        { 

            "type": "oauth_scope",

        }

    ]

}

Now let's say that the "oauth_scope" type is the default, so we can express it as:

(5)

{

}

(6)

{

}

(7)

{

    "authorizations": [

        {

            "locations": [

            ],

            "actions": [

                "read"

            ],

            "datatypes": [

                "contacts",

                "photos"

            ]

        }

    ]

}

And the space separated strings can be turned into individual strings and we have the equivalent request:

(8)

{

    "authorizations": [

        "create",

        "update",

        "delete",

        "read",

        "list",

        {

            "locations": [

            ],

            "actions": [

                "read"

            ],

            "datatypes": [

                "contacts",

                "photos"

            ]

        }

    ]

}

(9)

{

    "authorizations": {

        "reader": "read list",

        "customer": [

            {

                "locations": [

                ],

                "actions": [

                    "read"

                ],

                "datatypes": [

                    "contacts",

                    "photos"

                ]

            }    

        ]

    }

}

In a multi token request, if there is only one item in the array, we can shorten (9) to the following:

(10)

{

    "authorizations": {

        "reader": "read list",

        "customer": {

            "locations": [

            ],

            "actions": [

                "read"

            ],

            "datatypes": [

                "contacts",

                "photos"

            ]

        }    

    }

}

-- Txauth mailing list [email-masked] https://www.ietf.org/mailman/listinfo/txauth

---

From: Justin Richer <[email-masked]>
Date: Mon, 13 Jul 2020 09:27:50 -0400

Yaron,

Just as a data point: As it turns out, the type of polymorphism that I am proposing is in fact expressible in JSON Schema. I was unaware of this construct previously, since I don’t use JSON Schema with any regularity:

https://json-schema.org/understanding-json-schema/reference/combining.html#anyof <https://json-schema.org/understanding-json-schema/reference/combining.html#anyof>

I am unaware of the exact expression capabilities in any of the other half-dozen JSON-based schema definition languages, though. :) 

As for misunderstanding values, avoiding such things is actually the motivation behind the design I am proposing. A given data type in a particular place should have one and only one interpretation at all times.

And finally, as for the comment about the client needing to understand the response, perhaps the AS shouldn’t be the one doing the transformations when it returns data back to the client, and that should be restricted for exactly this reason. Additionally, I know of few OAuth clients that actively check the returned “scope” value in the wild. I know they are out there, but the common practice, in my experience, is to ask for stuff and use whatever comes back. I think the conversation on “directed tokens” might help us change this in a clear way, and it could include rules on how the AS is allowed to return information.

Thanks,
 — Justin

> On Jul 13, 2020, at 5:02 AM, Yaron Sheffer <[email-masked]> wrote:
> 
> <no hats>
>  
> For those not familiar with "turning up to 11" https://en.wikipedia.org/wiki/Up_to_eleven <https://en.wikipedia.org/wiki/Up_to_eleven>
>  
> On Fri, Jul 10, 2020 at 6:01 PM Dick Hardt <[email-masked] <mailto:[email-masked]>> wrote:
>>                 "https://example.com/customers <https://example.com/customers>",
>>             ],
>>             "actions": [
>>                 "read"
>>             ],
>>             "datatypes": [
>>                 "contacts",
>>                 "photos"
>>             ]
>>         }
>>     ]
>> }
>>  
>>                 "https://example.com/customers <https://example.com/customers>",
>>             ],
>>             "actions": [
>>                 "read"
>>             ],
>>             "datatypes": [
>>                 "contacts",
>>                 "photos"
>>             ]
>>         }
>>     ]
>> }
>>  
>>                     "https://example.com/customers <https://example.com/customers>",
>>                 ],
>>                 "actions": [
>>                     "read"
>>                 ],
>>                 "datatypes": [
>>                     "contacts",
>>                     "photos"
>>                 ]
>>             }    
>>         ]
>>     }
>> }
>>  
>>                 "https://example.com/customers <https://example.com/customers>",
>>             ],
>>             "actions": [
>>                 "read"
>>             ],
>>             "datatypes": [
>>                 "contacts",
>>                 "photos"
>>             ]
>>         }    
>>     }
>> }
> 
> -- 
> Txauth mailing list
> [email-masked] <mailto:[email-masked]>
> https://www.ietf.org/mailman/listinfo/txauth <https://www.ietf.org/mailman/listinfo/txauth>