[Federation] Problems with mandatory merge strategy for path processing of metadata

Issue #2087 resolved
Stefan Santesson created an issue

During actual implementation work of the data and metadata processing model of OpenID federation, we have encountered problems with the mandatory merge logic of metadata processing.

The basic problems in summary are the following

  1. Change of semantics of policy operators
  2. Loss of control over policy rules
  3. Optimization deficiencies
  4. Complex logic and unpredictable results

Change of semantics

One of the most obvious examples is the “value” modifier. This is a modifier and its intended function is not to make any subordinate metadata invalid. Its sole purpose is to enforce a value. The value of a parameter, no matter what it was, is simply replaced.

In merge, the value modifier function is altered from just setting a value to invalidate any metadata if any subordinate policy has a different value modifier.

Loss of control

An Entity Statement by a federation entity that includes a “metadata_policy” is supposed to define explicit rules that must be applied to subordinate entities. But in fact, this metadata policy will not apply to paths longer than 1. For longer paths, the policy in the Entity Statement will be altered through the merge process, creating an unpredictable result.

It is hard even for a human brain to figure out exactly in what ways the total merged policy may turn out based on different setups, but it is even harder to write code that ensures a certain predictable outcome. One complicating factor is that metadata can be modified in several ways by a federation entity. One way is by metadata_policy, the other is by entering explicit values as “metadata”. It is very hard to foresee how such direct changes may impact processing against a combined policy of a path.

Optimisation deficiencies

OpenID federation allows alternatives for resolving information about entities. One possibility is to traverse a path, but a much more effective option is offered through the resolve endpoint. This could be used by a superior entity to learn information about all leafs under an Intermediary. The problem is that it delivers metadata that has already been processed against policy. And as such it is not compatible with the mandatory merge process. We see this as a big lost opportunity.

Complex logic and unpredictable results

We have gone through great efforts to try to model our national environment using policy merge. In order to make this work we need to impose severe restrictions on subordinate federations on how metadata policies are constructed. But even with a complex ruleset we fail to create a generic model that will ensure predictable results.

Alternative paths and proposals:

We see two different possible logics that could be used to process metadata through a chain of policies. One is the defined merge approach. The other is sequential processing where the metadata from the leaf is processed against one policy at the time, and that the result of each policy processing is fed into the policy of the next superior entity. I.e:

Metadata --> policy 1 --> policy 2 --> Result policy

Our conclusion is that this model has none of the problems raised above. Using a sequential processing logic in this way makes it possible to allow local federations to be connected to national federations of different kinds with a predictable result. Local federations can apply any local rules regarding scopes and security policies and we can still ensure that a service from that federation is either represented by suitable metadata, or prevented from participation, in one of the national (superior) federations just by applying a suitable policy. With merge we can’t see how we can create this in a predictable way with the level of control we need on the Trust Anchor level.

We would propose one of two possible solutions:

  1. Replace the merge logic in the current specification with sequential processing
  2. Allow a metadata policy to be flagged for sequential processing

We would prefer to remove merge as we have not found any reasonable use for it. But if that is not possible, we could solve the issue by a flag. When such flag is encountered this means that this policy must be processed in unaltered form. The metadata fed into this process must be the processed metadata in the form it would have been received from a resolve endpoint by the subordinate Intermediate entity (this logic is already defined). 

We are really stuck on this issue and we hope for a favourable resolution or enlightenment on how we should solve our problems.

Comments (41)

  1. Vladimir Dzhuvinov

    Hi Stefan,

    I read your post and have a few questions to build a picture for myself what the issues are.

    In “Change of semantics” you mention the value operator and how it’s being merged.

    When you say “merge”, do you refer specifically to the merging of the values of two policy operators of the same type, which occurs when two authorities in the Trust Chain specify the same policy operator type for a metadata parameter?

    https://openid.bitbucket.io/connect/openid-federation-1_0.html#section-5.1.3.1

    For example the hypothetical merge of a Trust Anchor’s

    "id_token_signed_response_alg" : {
      "value":"PS256"
    }
    

    and Intermediate’s

    "id_token_signed_response_alg" : {
      "value":"ES256"
    }
    

    Or, do you refer to the general process where the policies of each authority in the Trust Chain are being combined?

    https://openid.bitbucket.io/connect/openid-federation-1_0.html#section-5.1.3

    (I’m trying to use the spec terminology here)

  2. Stefan Santesson reporter

    Hi Vladimir,

    I deliberately tried to keep the posting short. So there is a lot of things to say here.

    Your assessment is absolutely right. What happens logically is that when the policies you outline are combined, this is a failure in the policy merge process. The practical consequence is that the policy being processed is rejected.

    The the practical consequence of this is that setting the “value” to “P256” is that it invalidates the metadata, but only if the subordinate metadata value was set by a conflicting policy. If the subordinate Intermediary instead directly altered the metadata of its subordinate to a specific value in the “metadata” claim to “ES256” it would not cause an error because there is no policy merge conflict. Then “value” works as the pure value modifier as it was designed to be.

    I fully understand the mechanisms here, but it makes it very hard for a superior to formulate a policy with a predictable outcome. (I count unintentional rejection of services as unpredictable outcome). The intention with assigning a “value” in the policy was just to assign an explicit value, the practical result is that some subordinate entities down a path may be invalidated dependent on how subordinate Intermediaries are configured from time to time.

    We have a strong need to be able to setup the TrustAnchor to produce a predictable result, without knowing or caring about how the subordinate infrastructure is configured from time to time. We also have a need to allow Intermediaries to just focus on their world below them without having to adapt to a specific policy decided by a superior. An Intermediary may have many superiors with different policies. It should not have to care about what policy the superior use.

    It turns out that “merge” in practice require some kind of awareness of the whole structure of Federation Entities in order to be sure that the end result of policy processing is what it was intended to be. This “Awareness” is very hard to put into code.

    A sequential processing strategy allows each entity to focus on their task.

  3. Stefan Santesson reporter

    So I would like to clarify that it is not the policy processing part that is hard. It is the policy creation part that is hard if you want to make sure what will be the result of processing your policy. This is caused by the fact that your policy is going to be merged by unknown downstream policies, and it is very hard to know beforehand is the outcome is what you wanted to enforce or change.

  4. Stefan Santesson reporter

    I would like to make an update with what I think would be a better resolution to the problem.

    Proposal: Either one of the following:

    1. When resolving entity metadata through a chain of entities, only apply the TA metadata_policy assigned to that chain. Do not process policies defined by subordinate IE:s
    2. Allow the TA to advertise its policy processing strategy to either “direct” (as defined in 1), “merge” (as currently defined) or sequential(as originally proposed here).

    Rationale

    When modelling different scenarios I run into problems with both merge and sequential processing of policies.

    The problems with merge is outlined in the initial argumentation. In addition to this, I think merge is in violation with the definition of metadata_policy.

    An Intermediary can also be a Trust Anchor for a local federation (e.g.) a federation for the Health Care sector. While the superior TA can be a national ID federation where you will find the national eID services for login to government services and other services in the general domain. It is important that the Health Care sector can set the metadata rules that applies to them, but allowing the national ID federation to select what is appropriate and required in order to participate on this level.

    When an Intermediary issue an Entity Statement for a subordinate entity it tells those who trust this Intermediary that when you resolve metadata through me, these rules apply. The problem is that those rules do not have to apply to metadata when resolved in a superior context.

    Examples:

    We are considering two federations Health Care Federation (HCF) and National ID Federation (NIF). The HCF has a local Trust Anchor (TA) used by services when they operate in a health care context.

    The HCF TA is also acting as an Intermediate Entity (IE) in the NIF federation having the TA of NIF as its superior entity.

    The goal here is that the TA of NIF in its Entity Statement for the IE/TA of HCF can set a suitable policy that 1) Filters out the services in HCF that are equipped to participate in NIF as OP or RP. For this it wants full control over what rules that apply. But it also want access to the full capabilities that are advertised by each service in HCF

    Problem with merge

    The problem with merge as outlined above is that the policy decided by TA in HCF will be altered in an unpredictable way. If HCF has a rule that response_types_supported must use “code” specified as a subset_of value modifier. Consider if the HCF has a local policy that allows “id_token” and “code” also expressed as a subset_of modifier. The merge will alter the policy at NIF to include “id_token” making NIF loosing control over its policy. This violates the definition of metadata_policy stating:

    The metadata policy applies to the Entity that is the subject of this Entity Statement as well as to all Entities that are Subordinate to it

    But in this case it doesn’t. The policy being applied is different from what is expressed in the Entity Statement issued by the TA

    Problem with sequential processing

    We find that sequential processing has other problems that can be equally hard to overcome.

    Say in this case that the Leaf OP supports ACR both usable in HCF and NIF advertising in its metadata acr_values_supported = [“hcf_loa_mediium”, “hcf_loa_strong”, “loa3”, “loa4”]. HCF use “hcf_loa_mediium” and “hcf_loa_strong”, while NIF use “loa3” and “loa4”. Say then that HCF applies a policy where the acr_values_supported are limited to the HCF ACR set through subset_of [“hcf_loa_mediium”, “hcf_loa_strong”]. Likewise the NIF does the same and attempts to limit the ACR set to the NIF set using subset_of [“loa3”,”loa4”]. Both sets the policy operator essential=true.

    In sequential processing then the NIF ACR values will be filtered out in the HCF policy processing, forwarding only the HCF ACR set to the NIF policy processing, resulting in an empty set, even though the OP advertise that it supports the NIF ACR set.

    Why direct processing always works

    Direct processing (only process the top policy, ignoring subordinate policies) is actually doing exactly what the definition of metadata_policy defines and promises. It takes the leaf entity metadata in unaltered form, retaining all capabilities advertised by that entity and applies that policy. There is no difference if the leaf entity is situated directly under the TA, or the last entity in a long path. It also allows each IE node to also be a TA in its own context, applying exactly the suitable rules on that level without messing up policy processing at higher levels.

    Conclusion and recommendation

    There is nothing that can be set as a policy at lower level that a superior entity can’t replicate if it wants to. Skipping multiple policy processing makes the rules so much simpler to understand and to implement. With direct processing I can shape my federations with out limitations and risk of false acceptance or false rejections. I can set exactly the rules I care about and get exactly the result I want. With multiple policy processing a constantly run into problems and corner cases that I can’t fix in a generic implementation.

    The proposal is therefore to validate the path as defined, then process the target entity metadata directly against the metadata_policy defined in the top Entity Statement.

  5. Stefan Santesson reporter

    I’m so sorry. My example of merge problem was a mind slip. This example actually works as the merge of subset_of is the intersection. Bu I hope you get the point. I can come up with many examples, where the merge of policy does not produce the intended result, but this one was not one of them :)

    Just imagine any case where the TA actually want to allow a subset of a set of values, but the subordinate policy cause that subset to be reduced. It will then be filtered out even if it is allowed in the context of the TA.

    Likewise if the TA has both a subset_ and a superset_of with some minimum values. Then the subordinate policy adds to the superset_of with a value that is not supported by the subset_of.

    Things like these are problematic

  6. Vladimir Dzhuvinov

    Hi Stefan,

    I read this thread couple of times to get a feeling of how much the issues that you shared are due to frustration with the spec not being particularly clear in parts of the policy section, how much it’s finding it difficult to imagine how to code it, and how much it’s actual policy operator issues.

    I voiced my opinion with the editors that the metadata_policy section needs a preamble, to state the following 3 principles and properties:

    1. Subordinates are only able to create more restrictive policies, not make them more permissive.
    2. The processing metadata_policy is deterministic and predictable.
    3. The trust_chain consumer is ultimately responsible for the application of the policy_metadata. This includes the situation when the federation provides a resolve endpoint. This is to dispel the expectation that there is a way to enforce and guarantee, with an algorithm or otherwise, that consumers will always process and apply the policies as the TA and other authorities specify, and that a consumer would never be able to break this.

    At present this is not clearly stated and can only be found out by examining the metadata_policy specification and how it works in practice.

    Why is the logic deterministic?

    1. Every operator has a well-defined behaviour. The JSON entities that configure the operators are currently not explicitly defined and this doesn’t affect the operator behaviour in regard to metadata. There is a ticket to specify the JSON entities exactly.
    2. There is a well-defined rule set how individual operators for a particular metadata parameter may be combined.
    3. The combining of metadata_policy s and the merging of the the values for each operator is well-defined.
    4. There is a defined application sequence for all operators.

    With these points I want to counter the claim that the metadata policies are “unpredictable” or result in “loss of control”.

    Points 2 and 3 establish the property that Subordinates are only able to create more restrictive policies, not make them more permissive.

    In 2020 we implemented the metadata_policy as part of a general OIDC SDK written in Java. If we found things complex, it was in our effort to make the policy engine pluggable with an interface for custom operators. The code can be found here, feel free to copy it or adapt it for other languages.

    https://bitbucket.org/connect2id/oauth-2.0-sdk-with-openid-connect-extensions/src/master/src/main/java/com/nimbusds/openid/connect/sdk/federation/policy/

    The proposed alternative bottom-up metadata_policy processing is probably attractive, because it skips the step where the policies from each authority in the Trust Chain get combined and checked to ensure they can only become more restrictive. So the thinking probably is, let’s make the Trust Anchor policy be the last check, this is a great simplification and it will ensure the Trust Anchor always stays “on top”. This would work if all policy operators were commutative in regard to whether they are applied starting from the Trust Anchor first or Trust Anchor last. The “default” operator doesn’t have this property, so in a bottom-to-top processing where the combination step + check is skipped the Trust Anchor can be overridden by any Subordinate. A federation that wants to practice this alternative bottom-up processing either has to prohibit “default”, or use the standard processing only for it.

    There are ways to improve the clarity of the spec in metadata policy section, first by stating its principles and properties upfront, second by a good editing to better express the algorithms and hence make its implementation easier.

    About the proposal to only honour the policies of a Trust Anchor and ignore those of Subordinates. This runs counter to the spirit of the spec and how people want federations to work. If trust can be delegated, why deny the ability to delegate the setting of policies (provided they stay inline with a TAs policies)?

  7. Stefan Santesson reporter

    Thank you Vladimir for elaborate explanations.

    To start with the leading question. My problem is not with clarity and it is definitely not any problems knowing how to code it.

    My problem lies in trying to apply the specification to my use case. We have operated a federation based on SAML for some 10 years now for the purpose of national eID. At the same time we have other federations on a national level. Most importantly we have federations for health care and for the educational sector. These are today different federation. Any service participating in one federation must re-enroll in any of the other federations to interact with services there. Operating these federation comes with a huge administrative burden.

    We see such a great potential with using OpenID federation where we potentially could allow services to access services cross federations without having to re-enroll, making a federation infrastructure that is unifying, but allowing underlying federations to have their profile.

    The frustration and regrets (if any) lies in if the standard we develop here makes it impossible to use it to reach our goals. Nothing else. And there are a few little things we need in order to succeed.

    Let’s start with where we agree:

    I fully agree that the current definition of policy processing is deterministic.

    If you have all data of a chain and apply policy processing, then the output is definitely deterministic.

    However…

    My use of the word deterministic and predictability has a totally different context. I’m talking about the issuer of the Entity Statement that contains a policy. The federation entity that issues this statement does not know how that policy will be applied unless it can take into account exactly how all subordinate federation entities defines their policy.

    So when a federation entity attempts to formulate a policy, it may not know all subordinate policies that may come into play in all subordinate paths. And if any subordinate federation entity changes their policy, it may alter what merged policy that will be applied. This created unpredictability and loss of control over what policy that will be applied during chain validation (even if the chain validation is deterministic).

    Problems with enforcing a restrictive policy requirement

    The first problem is what it means by being restrictive and permissive across all possible metadata parameters. What about policy parameters that have boolean values. Is changing that boolean value restrictive or permissive in a general context?

    The second problem is that the current merge rules does not impose a rule that enforce a subordinate policy to be more restrictive. As they are defined today, the result can be either more permissive or restrictive. I’m not convinced that it will be easy to define and enforce such rules. There is a risk here to create a level of complexity that will be hard to deal with.

    A third problem is that metadata policy may contain other custom operators, such as regex (as in current examples). How do you ensure that these operators are more permissive or restrictive?

    But the biggest problem, at least for us, is that a federation entity may have multiple superior entities. This is clearly supported by the “authority_hints” Entity Statement claim. Now it can become really tricky because now I’m required to meet the restrictive policy requirement against all superior entities and there is a great risk that this will be impossible.

    The biggest risk

    The biggest risk and the greatest loss in my mind is if this requirement in practice makes it impossible to build anything but small homogenous federations under a closely monitored administrative domain where all nodes know all about how other nodes will formulate their policies and that only policies that can meet these narrow requirements can be formulated and enforced.

    Only applying the TA policy

    I see your point in the lost capability of accumulating policy settings if you just apply the top policy. And as you say. The application if “default” will be reversed. However. I think this is much less of a problem. These problems I can counter by altering the top policy and putting relevant requirement on the leaf entity metadata. I think the current approach has many more and harder problems that I don’t know how to overcome.

    I’m not sure what the best path forward is. I understand and respect current implementations that may depend on merge, and I don’t want to mess with them. All I ask for is a legal option to not apply merge where it does not work. Perhaps a flag in the Entity Statement?

    I think applying the policy declared in an Entity Statement to all subordinate entities as it is defined is exactly in line with what the definition of metadata_policy states today.

  8. Michael Jones
    • changed status to open

    A question in my mind is whether the two strategies are equivalent. Or if not, when do they produce different results?

  9. Stefan Santesson reporter

    Unfortunately they produce different result.

    Simple example. Entity policy declare option 1, 2 and 3. Next superior entity limits the set to 1 and 2, TA limits the set to 3 and 4

    Technically the entity would be capable of operating in the TA context as it supports option 3 and 4. Processing all policies results in an empty set at the TA and the entity is rejected.

    Other example. Entity declare a parameter to true, superior entity sets it to false, TA requires that it is true. Processing all policies will invalidate the entity at the TA because the intermediary changed the value. Applying the TA policy directly on the entity metadata would allow the service at the TA.

    Unfortunately the merge approach, the sequential processing of all policies, and by choice applying only the relevant policy at the current used TA all produce different results.

    My take on this is that the only general approach that could support all use cases is that you apply the policy at the requested TA only. The choice of TA determines the context that determines the metadata in that context. This decouples the dependencies between different federation nodes and how they express metadata policy at their level.

  10. Vladimir Dzhuvinov

    Hi Stefan,

    I read your comments several times, to try to get the gist of your perspective about policies in particular and federations in general.

    When we look at the concept of people or orgs coming together, they always have to establish some sort of coordination between themselves (to be successful at their common purpose), and decide on how to structure their responsibilities.

    When orgs with OPs and RPs come together to form a "federation", this would mean establishing a baseline of OAuth grant types, response types, client authentication methods and ID token + UserInfo algs that every entity would agree to support, to ensure protocol interoperability. Second, the orgs may agree on some LoA (ACR) nomenclature, supported scopes and OIDC claims, for the identity assurance and the available attributes.

    In a OIDC federation, once these parameters get agreed (and expressed in terms of Trust Anchor metadata_policy), it may not make much sense for every org (intermediate) down the trust chain to formulate more policies. But okay, let's say that a particular org may decide that some client auth method is considered too weak for their own internal security standard, and may insist that only mTLS auth be used, and all access tokens must be X.509 cert bound. The intermediary may choose to express this own policy as a metadata_policy, or not. If it does choose to define an explicit metadata_policy for this, it will have to put it down in such a way, that it is still compliant and meshes with the federation's TA metadata_policy. If only the TAs policy would count, as you propose, there would be no need for the org to formulate its own policy, but the org will still have to make sure its own internal policy gets "applied" in practise.

    I believe there is value in permitting orgs down the chain to formulate their own policies, and making them explicit. If the trust chain breaks due to a "bad" intermediate policy - which could be due to using the wrong operator (a mistake), or non-compliance - the trust chain resolution for all inbound transactions into the intermediate's RPs / OPs will also break. Whose responsibility would that be? The TAs? No, this is the responsibility of the org and the people who devised the org's own metadata_policy. If something is not right, the org will have to fix the issue where it “broke” the chain. If the org finds that its own security policy is not compliant with the TAs / federation's policy, then this is alright too, they shouldn’t be part of this federation :)

    Because the TA's metadata_policy will always get evaluated, this means that its design must not be haphazard either, and care must be taken there too. So, an intermediate's admin may come and say, hey, we should be able to override this and that, according to our contract, but look, your metadata_policy doesn't allow this!

    If only the TAs policy gets evaluated, errors or interop issues may still happen, but this will tend to occur in the app layer / protocol, let's say in the middle of an OIDC flow. In this circumstance, I also imagine there to be cases where the issue of effective policy mismatch may not get detected at all, let's say with unsupported OIDC claims that the RP may think it didn't receive because consent was withheld by the user.

    So, there is value in allowing entities down the trust chain to be able to be explicit about their policies and put them down in JSON form. Yes, an intermediate may break its own trust chains because of a poorly designed policy, but this is healthy, because it shows an actual issue. This doesn't have to break the entire federation and it is the intermediate's responsibility to get right.

    I imagine there will be federations where intermediaries won't have the need to add any metadata_policy of their own at all. Maybe even the federation scenario you're dealing with won't need that in practise and if that is the case, this could be communicated by saying "Please, don't devise any policies of your own!" :)

    This value of enabling metadata_policies throughout the trust chain also becomes evident in scenarios where multiple TAs get used, or when TAs become intermediates in some super federation. For example when national federations decide to operate under a common TAs with some common minimal guaranteed OIDC interop.

  11. Stefan Santesson reporter

    Hi Vladimir,

    Thank you for many valid points.

    There are indeed many ways to build and combine federations. In some federations I’m sure it makes all the sense to delegate the policy building to the whole chain of Intermediaries.

    I think one of the biggest mistakes we can do as standards writers is to believe that the scenario we have in our mind when we create the standard, is the one that all will use, and that there does not exist any legitimate use-case outside of it. That is certainly a trap that I have fallen into over some 25 years of creating standards.

    I don't want everybody to do it my way. I just want to be allowed to apply a processing rule that works, where my use-case requires it. And I think my use-case is legitimate.

    I’d love to demonstrate that :)

    Therefore I have a suggestion:

    Define a new claim that can go into the Entity Statement. Let’s call it “metadata_processing_policy”. This claim determine how metadata_policies in this Entity Statement must be applied. There are 3 choices I can think of now.

    1. merge (default) - As currently defined
    2. direct - Policies must be applied directly to the original policy of the subject entity, disregarding any policy expressed by any Intermediate entity in the chain
    3. subordinate - Policies must be applied to the metadata that is the output of processing the metadata through the subordinate entity in the chain, as defined by that subordinate entity

    This allows the best freedom to create federations for different environments. Different federations can define the model that suits them best and the process will be 100% deterministic. Technically this is not very hard to implement once you have the policy processing and merge engine in place, you just engage the same logic using different strategies.

    If we can’t find a resolution here, we will most probably have to define this as a private extension claim and require support for it in our local profile. The sad thing is that we will have to break the standard (that demands merge), which we really don’t want to do if we don’t have to.

    P.s. Great thanks for the Java code link. I’m a big fan of Nimbus and we have used it as the main library for JWT and also OIDC. I use a lot of Nimbus also in my implementation.

    I really appreciate that you don’t want to break your code at this stage. But with the latest proposal here, I don’t think you have to. Your current logic would still be the default.

  12. Stefan Santesson reporter

    Just adding for clarity that option 3 (subordinate) would be completely equivalent to obtaining the metadata of the leaf from a resolver with the subordinate as a TA, and then applying your policy on top of that.

    If all Intermediates of the federation applies this processing policy, this becomes equivalent to sequential processing of all policies.

    I imagine that most federations would agree on one common policy that makes sense to them.

  13. Stefan Santesson reporter

    Posting the image of the proposed new merge algorithm.

    This is my preferred solution rather than having different policy processing rules.

    This merge strategy means that we don’t attempt to merge individual policy operators. Instead we process individual metadata parameters. If a superior entity has a policy of a specific metadata parameter, then that policy is used. If the superior entity has no policy for that metadata parameter, the policy of the subordinate Intermediate is used. This allows both inheritance of policies set by subordinate entities, but gives superior entity the power to replace them if necessary.

    A big advantage with this algorithm is that it can never produce errors caused by policy merge errors, and it does not cause problems if custom policy operators are used.

  14. Stefan Santesson reporter

    I was asked to come up with concrete examples. Here is one that we discussed recently that is very realistic:

    In this example a local federation has OIDC RP:s that only support client_secret_post while others support private_key_jwt as token endpoint authentication method. Some services in this federation need to access services in a national eID federation where there is a requirement to use only private_key_jwt.

    The requirements imposed by both federations are realistic and reasonable for their local context.

    To enforce these rules, the local federation provides a policy for token_endpoint_auth_methods_supported with the policy operator superset_of set to {client_secret_postprivate_key_jwt}. This enforces all OP:s in this federation to support both client_secret_post and private_key_jwt in order to support their RP:s that can only do client secret. They opt to not use subset_of as they don't want to restrict other authentication methods, just to enforce that these two are supported.

    The national eID federation provides a policy for the same metadata parameter but with the intention to restrict values to only private_key_jwt. The TA can enforce this policy by setting the policy operator subset_of to the value private_key_jwt in combination with setting the policy operator essential to true. This will filter out any options supported by any OP other than the value private_key_jwt and ensures that the policy check will fail if no value is present. This means that only OP:s that support private_key_jwt will be accepted.

    The problem is however that when the policy of the eID federation is merged with the policy of the local federation, it will produce a merged policy that has both superset_of set to {client_secret_postprivate_key_jwt} and subset_of set to the value private_key_jwt. This is an illegal combination and policy merge will fail since subset_of must be a superset of superset_of. That is, the mandated minimum value set declared by superset_of must all be members of the maximum set declared by subset_of

    In conclusion, there is no way that both federations can enforce the policy they deem to be relevant and still allow an OP of the local federation to deliver its services to both federations. This even if the OP can meet the requirements of both federations.

  15. Michael Jones

    Thanks for your concrete proposal, Stefan.  I’ve been trying to think through what it would mean in practice.  Examples help me do that. ;-)

    Let’s consider your column 22, in which TA and IE1 both have policies that apply.  In my thought experiment, these are the two policies:

    TA: "id_token_signing_alg_values_supported": {"one_of": ["RS256", "RS384", "ES256"]}

    IE1: "id_token_signing_alg_values_supported": {"one_of": ["ES256", "ES256K"]}

    With the current merge algorithm, the merged result would be:

    "id_token_signing_alg_values_supported": {"one_of": ["ES256"]}

    If I understand your proposed model, the result would be:

    "id_token_signing_alg_values_supported": {"one_of": ["RS256", "RS384", "ES256"]}

    Am I correct?

    If I’m correct, here’s the practical problem I have.  The point of IE1 (perhaps a university) having the policy ["ES256", "ES256K"] is to communicate what algorithms its implementations support.  In this example, its implementations don’t support “RS256” or “RS384”.  But if they’re included in the result, that could lead to an RP thinking that it can use “RS256” with the OP, which will break at runtime because it doesn’t support the algorithm.  The useful information provided by IE1 is discarded.

    Am I missing something here?

  16. Stefan Santesson reporter

    Great example Michael. This makes the discussion more concrete.

    I have two comments on your example. The first is that yes I think you are missing something here. The function of the policy modifier “one_of” is to select ONE of the values that IS declared by the OP. If the OP does not declare RS256, it can’t be selected. If the OP has declared support of RS256, it will be selected using the TA policy.

    So in your example, the result can never be what you suggest. That is, it can’t lead to a situation where RS256 is not supported by the OP but still declared in the OP metadata.

    Secondly, and this is something I think should be elaborated in the standard, I think the primary use of metadata policy should be to:

    • Exclude services not compliant with the policy
    • Limit metadata value sets declared by the leaf entity to filter out non supported options

    You need to be very careful when applying policies that add or set values into the leaf entity metadata that was not declared by that entity. And that is regardless of what type of merge algorithm we apply. When you do this type of modification of metadata you have to make sure that this will not lead to situations, as you point out, where peers will think that the target entity with modified metadata has capabilities that in fact it does not have.

    The point I’m trying to make here is that it is of vital importance that the TA can decide what is allowed when validating metadata through this TA. This is ensured if the TA has the capability to override policy settings set by subordinate entities for the metadata parameters it cares about.

  17. Stefan Santesson reporter

    Just adding to my comment above. I would not oppose to limit metadata policy operators to contain only value checks and modifiers that restrict values already declared by the target entity.

    I am a bit scared of the concept of even allowing values to be set by policy that was not declared by the target entity. I think we could remove the “value”, “add” and “default” modifiers. I think the others are fine.

    I think that, if you really want to set a value in the target entity metadata, then that should be done in the Entity Statement “metadata” claim of that entity and not by metadata policy by superior entities.

  18. Stefan Santesson reporter

    Is there any progress or decision made on this subject?

    I have written a challenges report as part of the work on a profile for the Sweden OIDC federation where this issue and possible work-arounds. This is available here: https://github.com/oidc-sweden/specifications/blob/main/swedish-oidc-fed-challenges.md

    The draft profile of OpenID federation is available here: https://github.com/oidc-sweden/specifications/blob/main/swedish-oidc-fed-profile.md

    This draft defines new policy operators to be used as the standard ones, using prioritised merge logic (defined in section 4).

    I hate to do what we propose, but I see no reasonable way around it. But at least it would not violate the current profile.

  19. Roland Hedberg

    It seems that the present text in the draft is not explicit enough for everyone to

    understand how the merge operator works.

    In this text I will try to explain it by example which may make it easier to follow.

    Let us start with a short trust chain with only one intermediate

    and we will use the subset_of operator.

    The trust anchor sets the following policy for a parameter {"subset_of": ["A", "B"]}

    Using the definition of subset_of from section 6.1.1 (draft 33) together

    with the definition of the merge process in 6.1.3.1 .

    Merging the TA's policy with different intermediate policies will give the following results:

    intermediates policy -> merge result

    -----------------+--------------

    ["A", "B"]           | ["A", "B"]

    ["A", "B", "C"]      | ["A", "B"]

    ["B"]                | ["B"]

    ["X", "Y"]           | []

    # How [] is interpreted depends on whether essential is True or False as discussed in 6.1.1

    If there are two or more intermediates then the TA's policy is first merged with the

    intermediate that is immediately beneath the TA and then the result of that merge is

    merge with the next intermediate in the trust chain. And so on until the leaf is

    reached.

    With the following policies:

    TA: {"subset_of": ["A", "B"]}

    Intermediate 1: {"subset_of": ["A", "B", "C"]}

    Intermediate 2: {"subset_of": ["B"]}

    The result will be {"subset_of": ["B"]}

    Merging {"subset_of": ["A", "B"]} with {"subset_of": ["A", "B", "C"]} will

    result in {"subset_of": ["A", "B"]} and merging this with {"subset_of": ["B"]}

    will finally give {"subset_of": ["B"]}.

    All of the above will be worked into the spec.

    To respond directly to a couple of your statements (from your text):

    "A summary of the challenges that arise from this merge process is that:

    1. The TA has no way to control what the applied policy will be, since it can be changed by subordinate entities
    2. Many combinations of policies can't be merged without causing merge errors
    3. The standard allows the creation of custom policy rules, but not all rules can be merged in any meaningful way."

    My comments are:

    1. The TA sets the overall limits for the policy. Given that merging two policies is done according to the draft the TA can be sure that the result of the merging is within the limits it sets.
    2. True. This is by design. Such problems might be solved by having the parties discuss the policies with each other.
    3. If you create custom policy operators then all bets are off. The draft can not take responsibility for something to work that it knows nothing about.

    To this I can add that you specifically brings out the problem of having one federation (FederationA)

    becoming a member of another federation (FederationB) by having the TA of FederationA becoming an

    intermediate in FederationB. This might cause problems since the policy set by the TA+intermediates of

    FederationA may not agree with the policies set by FederationB.

    Now if FederationA wants to become a member of FederationB one would assume that it could imaging living

    under the rules set out by FederationB. You seem to expect FederationA to become a member of FederationB

    without changing anything. I don't think that is very reasonable.

    You’ve stated that you want to guard the leafs from having to enroll in more than one federation and I

    can sympathise with that. There is though ways of allowing enrolling once and then become member of

    more than one federation (as I’ve told you) by using intermediates that has no metadata policies or

    policies that are accepted by more then one federation. All provided that the leaf entity has the

    necessary functionality.

    To the above I can add that within the editors collective there has been some thought on rules for

    people that defines custom operators. This to make it easier for others to implement these new operators.

    And lastly, Stefan thank you for the thoughtful feedback motivating us to do this rewrite.

  20. Stefan Santesson reporter

    Roland.

    What breaks this algorithm apart is that a set of policy values can both represent requirements, capabilities and obligations.

    Therefore you can’t say that it is within the boundary of the TA policy to reduce the policy set declared by the TA.

    If A, B in your example represents obligations, then reducing that set is not in the boundary of the TA.

    If the TA creates a value check that ensures that a leaf has declared both obligation A and B, then no subordinate should be allowed to change that.

    Unless the TA has a way to declare policy parameters that are regarded as essential for allowing a leaf to be validated through that TA, the system is broken.

  21. Stefan Santesson reporter

    I do believe that I have found a much better solution to this problem with very little impact on the current specification.

    Proposed resolution

    Define a new policy operator named enforced

    When this policy operator is present and set to true, then this stops further merge with subordinate policies for this metadata parameter.

    Example1 : enforced set at TA

    TA: {"subset_of": ["A", "B"], enforced = true}

    Intermediate 1: {"subset_of": ["A", "B", "C"]}

    Intermediate 2: {"subset_of": ["B"]}

    Merge result = “subset_of”: [“A”, “B”]

    Example2 : enforced set at Intermediate

    TA: {"subset_of": ["A", "B", “C”]}

    Intermediate 1: {"subset_of": ["A", "B"], enforced = true}

    Intermediate 2: {"subset_of": ["B"]}

    Merge result = “subset_of”: [“A”, “B”]

    Example3 : enforced not set

    TA: {"subset_of": ["A", "B"]}

    Intermediate 1: {"subset_of": ["A", "B", "C"]}

    Intermediate 2: {"subset_of": ["B"]}

    Merge result = “subset_of”: [“B”]

    Impact analysis

    This change retains the current merge algorithm for policy operators as the default behaviour and all code implementing the current merge algorithm is preserved.

    This only has a minimum impact on the overall merge process that is extended with the function to skip merging of a particular metadata parameter policy when this flag is set to true.

    Benefits

    This allows any federation that has been created based ont the current standard to work without any changes. The result of policy processing remains exactly the same.

    Only federations that introduce this new operator are impacted and must make sure that chain processing software used in this federation has implemented this update. As an intermediate work-around to ensure compliance, these federations could set the new operator as critical, forcing software not up to date to fail.

    This update will solve all issues related to complex federation interactions and allows a TA to enforce a certain policy in situations where it has good reasons to do so. This is tremendously helpful to avoid having to build silos of federations, forcing leaf entities to re-enroll to each federation.

  22. Stefan Santesson reporter

    I would like to add to the examples how this also can help avoiding merge errors:

    ‌Example : Enforcing restriction while avoiding merge errors

    TA: {"subset_of": ["A", "B"], enforced = true}

    Intermediate 1: {"subset_of": ["A", "B", “C”]}

    Intermediate 2: {"superset_of": ["B", “C”]}

    Merge result = “subset_of”: [“A”, “B”]

    ‌If enforced was not set in this example, metadata policy processing would have caused a merge error because subset_of": ["A", "B"] is incompatible with "superset_of": ["B", “C”]. But because the TA in this case has set the enforced flag, it is able to process the leaf under the enforced policy rule. This is very important in cross federation situations where the Intermediate 2 may belong to another federation where the "superset_of": ["B", “C”] could be legitimate for its local context. A leaf that declares “A”, “B” and “C” will now be able to operate in Both federation contexts as it complies with all superior requirements.

  23. Michael Jones

    Hi Stefan. You wrote:

    a set of policy values can both represent requirements, capabilities and obligations.

    I’m trying to map that statement to actual metadata values in my mind, to make it concrete. As I see it, metadata values tend to be one of:

    • Endpoint addresses, such as authorization_endpoint. Is this a capability in your characterization?
    • Lists of features supported, such as id_token_signing_alg_values_supported. Is this also a capability in your characterization?

    What metadata values are examples of requirements and obligations, as you see it?

    And once you’ve given us examples of requirements and obligations, what things might federations specifically want to do with them? And what of those things are and are not possible with the current metadata policy language?

    The more concrete we can be in these discussions, the less misunderstandings will likely occur. I’ll admit, it’s hard for me to reason about what we have and what may be missing in the abstract.

    Thanks again for thinking deeply about this and sharing your thoughts with us.

  24. Stefan Santesson reporter

    Hi Mike,

    ‌The characterisation of metadata parameters as requirements, capabilities and obligations might be an unnecessary detour. Let me take back that as a relevant argument and focus on concrete issues. Following is an example of the problem that I run by Roland and he agreed that it can’t be solved using the current merge algorithm without work-arounds:

    Let’s assume we have 3 federations:‌

    • ‌SWAMID (Swedish educational federation)
    • eduGain (International educational federation)
    • eIDAS (EU federation using eIDAS authentication)

    Let’s now assume that these federations have different acr requirements on OP:s that are allowed to serve RP:s in that federation:‌

    • SWAMID's TA applies a policy for subordinate OPs that acr:s “password” or “multi-factor” must be supported. They opt to use “subset_of”: [“password”, “multi-factor”] (proposed value check “intersects” could have worked better here)
    • eDUgain TA applies a policy for subordinate OPs that acr:s "eg-1 and eg-2" must be supported. They opt to use “superset_of”: [“eg-1”, “eg-2”]
    • eIDAS TA applies a policy for subordinate OPs that ONLY acr:s "substantial" and "high" are allowed. They opt to use subset_of: [“substantial”, “high”]

    The SWAMID federation now wants to interconnect with both eDUgain and eIDAS federations by having an Entity Statement issued to their TA from both federations. The goal is to allow OP:s in SWAMID to act as OP in the other federations if they are capable to do so and also allow RPs to use the OPs in the other federations if they are capable of doing so. The goal of applying policy is here to filter out (at each TA) only those services that are fit to participate in each federation.

    SWAMID has an OP that has declared that it supports [“multi-factor”, “eg-1”, “eg-2”, ”substantial”]. This meets the requirements of all federation policies. How do we apply policies that allow this OP to participate in all federations?

    ‌‌The problem here is that these policies can’t be merged without creating merge conflicts. The problem is also that SWAMID has not only one superior TA, but 2 to try to adapt to with incompatible requirements.

    ‌Following my proposal above, the EIDAS and eduGain TA:s could issue an EntityStatement for the SWAMID TA, setting enforced to true for acr. This would effectively allow these TA:s to enforce their policy directly on the services in SWAMID, while allowing SWAMID to keep its local policy.

    ‌Is this more clear?

  25. Stefan Santesson reporter

    Mike,

    ‌Thinking very careful about this. I start to see this, and its problem in a new light and I think I understand more where we disconnect.

    ‌The merge algorithm is actually a very beautiful design. Many kudos to Roland for coming up with it.

    Roland is very correct in his assessment that when you work with the same policy operator. The result will always stay in the boundary set by the TA. Examples:‌

    • ‌If the TA sets “value” then no one can change it
    • If the TA sets one_of, then no one can expand that set
    • If the TA sets a minimum value set, then no one can reduce that
    • If the TA sets a maximum value set, then no one can expand it

    The fact is, that this guarantee not only that the merged policy stays in the boundary of the TA policy. It guarantees that the merged policy stays in the boundary of all policies in the chain. All have an equal power over the result. The result is either compatible with all Entities, or merge will fail.

    This requires however that all Entities in a chain agrees on the same policy strategy. That is, if all Entities agree to express a maximum value set using “subset_of” then merge will never produce a result that extends the maximum set of the TA or any other Entity in the chain. The same goes for any other policy operators. I recognise this as the beauty of the design --> Either everyone gets their way, or merge will fail. It’s federation democracy in its prime!

    ‌As long as we build a local federation where every leaf only chains to a single TA, and all nodes sign up for the same policy strategy, then this works nicely.

    ‌The problem I have is that I don’t want to build a single federation. I want to build a national federation that can extend to other national federations. And here it becomes problematic to allow every Entity in all federations to have an equal say about the policy being applied in any chain, and here it becomes really hard to coordinate how every TA and Intermediate in the infrastructure express their policy.

    If different nodes in this infrastructure applies different strategies for their policies, E.g. one node express a maximum set (subset_of), and another express a minimum set (superset_of), then this can easily create a merge errors.

    The more complex the federation environment grows, the more this democracy feature grows inte a huge interoperability problem. This is what my example above attempts to demonstrate.‌ In this environment each TA in the system may need more executive power.

    All I humbly ask for is: Just give me one legitimate way that does not break the standard, where the superior Entity can express a policy that overrides subordinate policies, where and when this is deemed necessary. I think the future will thank you granting my request. If you don’t want to provide this feature, then at least do not prohibit it!. Offer at least a legitimate way where I can solve it using local extensions.

    I wish you all a Merry X-mas!

  26. Michael Jones

    Thanks, Stefan. This is insightful analysis and increases my understanding of what the policy language does and achieves. Your observation “Either everyone gets their way, or merge will fail. It’s federation democracy in its prime!“ is particularly spot on.

    As you point out (using other words), the result of applying all the parties' metadata policies in the chain must result in workable metadata. To that I’ll add, there’s one other party that must be compatible with resulting metadata - the implementations running at the leaves - the OPs and RPs. The deployed code must implement features corresponding to the resulting metadata, or things won’t work.

    You wrote “All I humbly ask for is: Just give me one legitimate way that does not break the standard, where the superior Entity can express a policy that overrides subordinate policies, where and when this is deemed necessary.“ Indeed, let’s imagine a world where superiors have the capability to impose metadata values on inferiors that produce results that override the subordinates' policies. Here’s my concern with that. The imposed metadata may align with what the superior wants, but it may also be incompatible with the implementations at the leaves.

    It’s always been my presumption that to function in a federation, deployments will have to implement the features that may be used in metadata that applies to them. And that implementations' feature choices will necessarily correspond to the policies of their superiors in their trust chains. It’s both democracy in action and purposeful cooperation.

    It’s my fear that if superiors are given the power to override choices made below them, they will also often be correspondingly trying to override the choices made by the implementations at the leaf entities below them, resulting in broken systems. Changing the metadata won’t change the code. Convince me that I’m wrong. 😉

    Merry Christmas to you too! 🎄 😀

  27. Stefan Santesson reporter

    Thanks for that fine analysis Mike. I’ll try to convince you 🙂

    And I hope I succeed. Because if I don’t, I’m convinced that future will, and then it may be to late 😏

    Let me start to say that In my opinion, I don’t think policy operators should be allowed to add anything that was not declared by the target Entity. I think that is dangerous (as I have written before). I think policy operators should be limited to:

    • ‌Value checks that put requirements on content, without changing the content.
    • Value modifiers that restrict what has been declared by the target Entity, but does not add anything.

    I have several reasons why I think this is important:

    • ‌Otherwise an Entity may end up being represented by metadata that does not reflect its capabilities. This will require all Entities to keep track of how their metadata is represented at each TA, and that may be well beyond the capability of the Entity.
    • Only the Intermediate that registered the target entity (who knows this entity well can be assumed) should be allowed to alter or set values for its registered entity. But this can be done directly in the metadata claim of the Entity Statement. This should not be set using the metadata_policy claim.

    If the role of the policy is not limited to these functions, then I see a minor problem of overriding policy entires, as you state. Because now you run the risk of loosing added or set metadata values.

    In our profile we propose to implement these limitations on policy settings, that is, policy can only check or reduce values declared by the entity, never change them.

    Now it becomes even more valid for a TA to say: “These are my rules for being accepted at this TA, and if you have declared metadata that meets my requirements I have stated here I will accept you, regardless of the requirements for acceptance that is stated in the federation your come from.

    But even as the policy operators are defined today, I still think this would be a valid statement by the TA. See my analysis below!

    So let’s analyse a realistic use case that I think we MUST solve.

    Let’s assume an OP in fed A that is interconnected with fed B. This OP will then be validated through TA in fed B using this chain:

    OP fed A → IE fed A → TA fed A acting as IE in fed BTA fed B

    This OP will serve two different RPs one in fed A and one in fed B using two different chains

    RP fed A → IE fed A → TA fed A. This entity is reading OP metadata as: OP fed A → IE fed A → TA fed A

    and

    RP fed B - IE fed B - TA fed B. This entity is reading OP metadata as: OP fed A → IE fed A → IE fed A → TA fed B

    Say now that fed A requires support for client_secret_post and private_key_jwt, expressed as "token_endpoint_auth_methods_supported": {"superset_of": ["client_secret_post","private_key_jwt"]}. TA in fed B on the other hand has a stricter policy and demands that privateKeyJWT must be used using "token_endpoint_auth_methods_supported": {"subset_of": ["private_key_jwt"]}.

    This is pretty legitimate for both TA:s. Fed A has some clients that can’t do privateKeyJWT, so OPs must support client secret in this federation context. Fed B has a stricter security policy. Fair enough.

    And this should work. If the policies are allowed to be enforced as stated. RP fed A will see the metadata of the OP as supporting both client authentication options, and RP fed B will only see privateKeyJWT as the only supported option.

    That would be fantastic!! Except that this does not work 😣

    The OP supports both privateKeyJWT and client secret, so it is fit to serve in both federations. But!

    • ‌Using federation democracy, not everyone in the chain can have their way!
    • So using current merge algorithm, the OP will be banned from participating in fed B because of the policy applied by TA fed A acting as IE in fed B. This is because the superset in fed A does not fit inside the subset in fed B.

    In this situation I claim that TA should be allowed to declare its policy for this metadata parameter as “enforced”, and thus applying it directly on the target entity OP metadata.

    So what are the risks involved by allowing this?

    I see no real risks. The TA of fed B will use the chain to validate the EntityConfiguration containing the metadata claims asserted by the OP. Here it can read exactly what the OP has declared as its capabilities. If the TA in fed B is interested only in the capabilities of the OP (not in the restrictions applied in fed A advertised to RP in fed A) then it should be able to use the metadata of the OP directly in its assessment of the OPs suitability to serve in fed B.

    What are the consequences of not allowing this?

    The consequence is that you simply can’t interconnect federations with different policy requirements. The risk of merge conflicts is too big. This leads to severe work-arounds such as remodelling federations structures so you can bypass defined policies. This was actually proposed by Roland. The solutions here would be to chain the IE in fed A directly to the TA of Fed B, bypassing the TA of fed A. This works if you enforce that IE in fed A is not allowed to set any policy.

    Think about this!

    If ALL policies in any chain always must be honoured (Vive la démocratie ). Is it then better re-rout the path around the policies you don’t like??? That is sort of a huge double standard. Is it OK to bypass policies or not? You have to make up your mind!

    Then at least I think a better solution is to honestly declare an enforced rule openly, instead of remodelling federations to bypass policies, because of shortage in the standard. Don’t you agree?

    The only other available option is to give up the dream of interconnected federations and keep all federations separate 😢 . In this case entities wanting to participate in both federations have to enroll to both separately.

    I think that would be a huge loss. And I’m convinced future will prove me right. And it would cause other problems. Entities that delegated their publication of Entity Configuration to their IE will also have to enroll with different Entity Identifiers!

    I really hope I convince you, because I don’t want to make ugly workarounds 😏

  28. Michael Jones

    Stefan, you proposed:

    “I don’t think policy operators should be allowed to add anything that was not declared by the target Entity.“

    That might be a good convention to follow. I’m curious what others think. If people agree, it could be documented in a set of non-normative suggestions about using metadata.

    Of course, you have already advocated for a contradiction to this convention - where an intermediate node immediately superior to a leaf declares its metadata for it. So the description would need to be accordingly nuanced.

    As for your Fed A and Fed B example, it seems to me that the root problem is that A doesn’t comply with B’s policies, even though it’s nominally a member of B’s federation. This would have been caught when A tried to join B - especially during initial interop testing. One or the other of A’s or B’s policies need to change. The obvious change to make this work seems to me for A to change to:

    "token_endpoint_auth_methods_supported": {"subset_of": ["client_secret_post","private_key_jwt"]}

    Then the OP will be able to work in both A and B.

  29. Stefan Santesson reporter

    Mike, on the two separate issues:

    On policy operators adding to leaf entity

    If you read carefully, I do not propose a contradiction at all. The IE being the superior entity to the leaf has two entirely different mechanisms to set a value for the leaf entity metadata according to the current spec:

    • Using the metadata claim in the Entity Statement
    • Using the metadata_policy claim in the Entity Statement‌

    From section 3, describing the metadata claim:

    In some cases, a Superior may want to be explicit about what metadata should be used for a Subordinate. In that case metadata MAY be used in a Subordinate Statement.

    What I propose is that IF the superior entity (in agreement with the leaf) wants to set a value, it should use the metadata claim. No IE should ever use metadata_policy to add anything not declared by the leaf entity.

    Even using metadata this ways should be made with care. The superior IE should only do this when it has such relationship with the target entity that it knows that this capability is supported and will be accepted by the entity.

    On the role of TA and federation compliance

    I see that we have quite different view on the role of a TA policy. I’ll try to explain what I mean.

    First of all. Federations do not comply with each other. That is not their purpose. Their purpose is to set a common policy for interaction of services within their local domain.

    A TA should be viewed as a policy enforcement point. The purpose of the TA is to set the rules that decides which services that comply with the policy of the TA, and to allow metadata from these services to be validate through that TA.

    Example:

    TA(HC) is a TA for health care services that operates under a common ruleset. The TA applies a policy that determines what healthcare services must support. This assures interoperability between healthcare services only. This could include requirements to support certain scopes, ACR:s, authentication methods, algorithms etc.

    TA(ID) is a TA for a national eID federation. This federation has other requirements on supported scopes, ACRs, authentication methods etc.

    Now we have a number of services that can chain to one TA or both IF they comply with both TA policies. What determines if a service is fit to chain to TA(HC) or TA(ID) is mainly determined by if the service complies with the policy for TA(HC) and TA(ID). When service A chains to TA(ID) it is no relevance if it also complies with TA(HC). And when the same service chains to TA(HC) it is of no relevance if it complies with the policy of TA(ID).

    And it is not so easy that you can always say that one federation should comply with the other. They could be mutually cross linked. TA(HC) could offer an Entity Statement for TA(ID), while TA(ID) offer an Entity Statement for TA(HC). Now who should comply with who? We actually have exactly this case in Sweden. We want to allow the main OP in the HC fed to participate as OP in TA(ID) to support HC professionals to log into government services using their HC eID. At the same time we want those services in the HC federation that pass the TA(ID) policy to be allowed to use the national eID services. E.g. to allow patients with a national eID to log into the patient page of a HC service. But this possibility is blocked for us. We have exactly 0 options to solve this in a reasonable manner with the current spec!

    You MUST allow these TA:s to set different policies for their local context. Your suggestion does not work in my example. I intentionally used superset_of because subset_of does NOT assert that all services include both "client_secret_post" and "private_key_jwt". Now you changed it so that they can support either or instead of both. You also changed the policy so that no other alternatives can be used, which is not what this federation needs to function.

    To assume that all federations and their TA:s must use similar policies that can be successfully merged is impossible to uphold in a big open federation environment.

    To summarise, The merge algorithm is clever and beautiful. Let’s keep it. Only add a capability to mark a policy for a given metadata parameter to be flagged to ignore subordinate policies in the chain. This simple modification solves everything and it is just a minor fix in the specification. I have already implemented it in my code by adding a new policy operator with this semantic. It’s very easy. And I really, really need it. Please!!! 🙂

    I have provided two mechanisms that I think works:

    • ‌Add a new policy operator (In my implementation I ended up naming it “skip_subordinates” which is semantically better than “enforce”.
    • If you extend the structure of metadata parameter policy (to provide information about value format), then you could also provide this statement here (This would be even better but requires more changes to the draft).

    I hope you can accept one of these.

  30. Michael Jones

    Thanks for continuing the conversation, Stefan. You wrote:

    First of all. Federations do not comply with each other. That is not their purpose. Their purpose is to set a common policy for interaction of services within their local domain.

    It seems to me that what you’re describing is a situation in which two federations co-exist but neither is a subordinate to the other. Indeed, that’s exactly what Figure 1 in https://openid.net/specs/openid-federation-1_0-32.html#name-introduction depicts. Neither is expected to comply with the other’s policies. But their subordinates do comply with the policies of their superiors, including the trust anchor chosen for any particular interaction. With that organizational structure, it seems to me that things will work just fine, including for the use case you describe above. Do you agree?

    Happy New Year!

  31. Stefan Santesson reporter

    Happy New Year!

    What is shown in that image can certainly work in some situations. The great thing though with this image is that it shows that it is indeed appropriate to ignore/bypass policies of nodes that are not of relevance to you. As the policy of TA A is of no relevance of TA B it is appropriate to bypass it.

    However this assumes that the federations are setup in a way that allows this. For example:

    • That no part of the policy you want to bypass is implemented by Intermediate of TA A
    • That OP directly of TA A is of no interest to TA B (or any other service directly linked to TA A) ‌

    I think that what the difference in our views all is about, is how we trust the ability to control that federations out there will be built in a way that allows them to successfully interact. After over 10 years of building federations, I don’t have the same trust as you have.

    In my experience, people will interpret the standard differently and will build incompatible structures and policies. And once they got it working, it will be really hard to change. In particular if it involves a Government Agency where you have to start educating them on the issues and what to do about it. I really hope that you are right and I’m wrong. And I would hate to find out that I was right.

    I think I have found a possible work-around now. I have defined a new policy operator in our draft profile (skip_subordinates) that is our emergency backdoor if we can't solve things any other way. Please read it here: https://github.com/oidc-sweden/specifications/blob/main/swedish-oidc-fed-profile.md section 5.1.3. I would also invite you to read the background description of the problem at https://github.com/oidc-sweden/specifications/blob/main/swedish-oidc-fed-challenges.md section 2.2

    We assure that there will be no conflicts with existing implementations by marking this operator critical. Those who don’t understand this must fail. But our resolvers will be required to support this.

    I would at least want your sign-off that this in your opinion is not a breach of the standard. Ideally I still hope that this type of capability to bypass subordinate policies is supported by the standard, in cases where it is deemed necessary.

  32. Log in to comment