[Federation] Specify the applicable JSON types for each policy operator

Issue #2078 resolved
Vladimir Dzhuvinov created an issue

Currently OpenID Federation specifies a set of 7 policy operators. Operators like value, default and essential can be expressed with any JSON type and applied to any JSON type. Others, by their nature, like one_of, can only be formulated as a JSON array and operate on strings. To ensure interop the spec should define the exact applicable JSON types for every operator.

https://openid.net/specs/openid-federation-1_0.html#name-operators

The ambiguous places:

  • Is add allowed to be specified as JSON string when a single value is being added to the metadata parameter?
  • What types can go into the JSON arrays of add, one_of, superset_of, subset_of ?

Comments (10)

  1. Stefan Santesson

    I was just about to add an issue about this, and was happy to see that one already exists.

    I found it hard to understand exactly in what context what data format is allowed. I had a discussion with Guiseppe where I argued that the easiest from en implementation standpoint would be that all parameters (except for essential) are given as an array of strings. I see the following variants:

    “value” → [“value”]

    “value1 value2” → [“value1”,”value2”]

    [“value1”, “value2”] → [“value1”,”value2”]

    1 → [“1”]

    1,2 → [“1”, “2”]

    true → [“true”]

    I think a rule where the policy operator is always expressed as a String Array is easier to handle from an implementation perspective and would cause least failure due to implementation differences.

    But that would of course break current implementations. And we may not want that. In any case it must be clear what data format must be used in the different cases we may encounter.

    I also have a rule in my implementation where only simple types are allowed. I don not accept metadata_policy operators for metadata parameters expressed as a JSON object. However, as Guiseppe showed me. There are some plans of doing that in the Wallet context. Which is bad.

  2. Stefan Santesson

    I would like to bump this issue as this has turned out to be substantial issue for our implementation and interop.‌‌

    The problem for me is that the whole policy processing logic must be aware of the ‌JSON type not only of the policy operators, but also the metadata parameter that is being processed.

    ‌This in turn forces an implementation that must be aware of all possible metadata parameters that can be processed in path validation.

    ‌This is unfortunate and makes it harder to adapt new metadata parameters as resolvers that are not aware of the JSON Type, is incapable of processing the metadata value through policy.

    An example of such issue is the need to distinguish a space separated list of values in a single string from a single string value or a JSON Array.‌

    The policy processing logic could be generalised a lot if the content type is declared. Unfortunately JSON type is not sufficient as space separated list in a single string must be distinguished from JSON Array and JSON String.‌

    ‌I can’t come up with a nice way to solve this. The most solid solution would be to declare the value type outside of the operators like:

    ‌‌

    {
        "metadata_policy": [
            {
                "id": "id_token_signed_response_alg",
                "enforced": false,
                "format": "string",
                "policy": {
                    "default": "ES256",
                    "one_of": [
                        "ES256",
                        "ES384",
                        "ES512"
                    ]
                }
            },
            {
                "id": "default_acr_values",
                "enforced": true,
                "format": "array",
                "policy": {
                    "superset_of": ["http://example.com/loa3"]
                }
            }
        ]
    }
    

    ‌This upgraded structure would allow expression of additional properties such as format outside of the actual policy. I also added the “enforced” property here as discussed in the separate issue on policy processing. IF this format would be adapted, the “enforced” property would be better placed here rather than as a new policy operator.

    ‌I believe the formats defined must include:

    • ‌string (default)
    • array (Array of string values)
    • space_list (Array expressed as space separated list of values in a single string
    • boolean
    • integer

    ‌I’m divided if there is a need for “object” and “integer_list”. I don’t think we can process policy on objects and I’m not aware of any existing metadata parameter expressed as list of integer, but who knows if one will be invented.

    ‌If this syntax is adopted, then I propose that 

    • value and default MUST be provided as specified by format
    • add, one_of, subset_of and superset_of MUST be specified as an Array consistent with the format property, even if a single value is provided. Exception: When the format is space_list, then add, one_of, subset_of and superset_of MUST be specified as an array of individual string values (not a space separated list of values).

  3. Stefan Santesson

    There is an error in the example. I forgot to include declaration of the Entity Type  

    {
        "metadata_policy": {
            "openid_relying_party": [
                {
                    "id": "id_token_signed_response_alg",
                    "enforced": false,
                    "format": "string",
                    "policy": {
                        "default": "ES256",
                        "one_of": [
                            "ES256",
                            "ES384",
                            "ES512"
                        ]
                    }
                },
                {
                    "id": "default_acr_values",
                    "enforced": true,
                    "format": "array",
                    "policy": {
                        "superset_of": ["http://example.com/loa3"]
                    }
                }
            ]
        }
    } 
    

  4. Stefan Santesson

    If you omit default parameters, it could be simplified as:

    {
        "metadata_policy": {
            "openid_relying_party": [
                {
                    "id": "id_token_signed_response_alg",
                    "policy": {
                        "default": "ES256",
                        "one_of": [
                            "ES256",
                            "ES384",
                            "ES512"
                        ]
                    }
                },
                {
                    "id": "default_acr_values",
                    "enforced": true,
                    "format": "array",
                    "policy": {
                        "superset_of": ["http://example.com/loa3"]
                    }
                }
            ]
        }
    }
    

  5. Log in to comment