[SAO] Output claim set varies depending on evaluation order

Issue #1276 resolved
Takahiko Kawasaki created an issue

The current specification of “Selective Abort/Omit” (SAO) does not prevent the output claim set from varying depending on evaluation order.

Example request and data:

{
  "id_token": {
    "verified_claims": {
      "verification": null,
      "claims": {
        "given_name": {
          "if_different": "omit_verified_claims",
          "value": "John"
        },
        "family_name": {
          "if_different": "omit_set",
          "value": "Smith"
        }
      }
    },
    "email": {
      "if_unavailable": "omit_set"
    }
  }
}
claim actual value
verified_claims / given_name Max
verified_claims / family_name Meier
email max@example.com

Case 1:

If "if_different" of "given_name" is evaluated before "if_different" of "family_name",

  1. The whole "verified_claims" is omitted.
  2. The value of "family_name" becomes unavailable.
  3. The action for "if_different" of "family_name", "omit_set", is not triggered.

As a result, "email":"max@example.com" is included in the output claim set.

Case 2:

If "if_different" of "family_name" is evaluated before "if_different" of "given_name",

  1. The "omit_set" action is triggered.
  2. The value of "email" becomes unavailable.

As a result, the "email" claim is not included in the output claim.

Comment from an implementer

I spent some weeks considering how to implement SAO, but I’ve not reached a conclusion yet. The difficult part of the specification is in that "if_different" may trigger omission of other nodes and even itself (not only by "omit_set" and "omit_verified_claims" but also by "omit" which may recursively omit upper nodes) and the omission may invalidate "if_different" of other nodes and even itself. Therefore, the evaluation order of "if_different" matters and may generate different claim sets.

I’m afraid that the current specification of SAO cannot be implemented in a deterministic way. Different implementations would generate different claim sets.

Comments (25)

  1. Daniel Fett

    Would this evalutation order fix things?

    1. evaluate all if_unavailable items, within those

      1. evaluate all omit
      2. evaluate all omit_set
      3. evaluate all omit_verified_claims
    2. evaluate all if_different items, within those same order as above

    3. finally, evaluate all items that became unavailable and are marked with if_unavailable.

  2. Takahiko Kawasaki reporter

    I will investigate whether the evaluation order works, but it will take time due to other higher-priority tasks. Sorry.

  3. Takahiko Kawasaki reporter

    I’ve started implementing SAO. It will take a couple of weeks for me to be able to confirm that the evaluation order works (or at least it can be implemented). If other problems are found while implementing the specification, I’ll report them.

  4. Takahiko Kawasaki reporter

    Example verified_claims request:

    {
      "id_token": {
        "verified_claims": {
          "verification": {
            "trust_framework": null,
            "assurance_level": {
              "if_unavailable":"omit_verified_claims",
              "if_different":"omit_set",
              "value":"example_assurance_level"
            }
          },
          "claims": {
            "family_name": {
              "if_unavailable":"omit_set",
              "if_different":"omit",
              "value":"nonexistent_family_name"
            },
            "given_name": {
              "if_unavailable":"abort"
            }
          }
        }
      }
    }
    

    Example data:

    property value
    assurance_level "example_assurance_level"
    family_name "example_family_name"
    given_name "example_given_name"

    Steps:

    1 “if_unavailable":"omit” Nothing is done
    2 “if_unavailable":"omit_set” Nothing is done
    3 "if_unavailable":"omit_verified_claims" Nothing is done
    4 "if_different":"omit" “if_different":"omit" of family_name is triggered. As a result, family_name is omitted. This will later trigger "if_unavailable":"omit_set” of family_name.
    5 "if_different":"omit_set" Nothing is done
    6 "if_different":"omit_verified_claims" Nothing is done
    7 Evaluate all items that became unavailable and are marked with "if_unavailable". "if_unavailable":"omit_set" of family_name is executed. As a result, "if_different":"omit_set" of assurance_level is triggered and executed. As a result, assurance_level is omitted. This will later (not at this timing) trigger "if_unavailable":"omit_verified_claims" of assurance_level if the same processing flow (“evaluate if_different then later if_unavailable”) should apply.
    8 "if_unavailable":"omit" (2nd) Nothing is done.
    9 "if_unavailable":"omit_set" (2nd) Nothing is done.
    10 "if_unavailable":"omit_verified_claims”(2nd) "if_unavailable":"omit_verified_claims" of assurance_level is executed. As a result, the whole verified_claims is omitted. This will later trigger "if_unavailable":"abort" of given_name.
    11 "if_unavailable":"abort" "if_unavailable":"abort" of given_name is executed. As a result, the whole request is aborted. (Here it is assumed that "abort" actions should be evaluated at the latest step.)

    In the example above, "if_unavalable" actions need to be rechecked after the step 7 again. This implies that the evaluation rule needs to be defined in a recursive manner, for example by using “until …” and “mark ‘processed’ and continue” (like garbage collection algorithms). Or a different syntax for SAO may have to be devised.

    In addition, although the example above does not include the following pattern, it should be noted that it is theoretically possible for mandatory claims/nodes to trigger "if_unavailable" actions of upper nodes recursively.

    {
      "optional_node": {
        "mandatory_node": {
          "mandatory_claim": {
            "if_different":"omit",
            "value":"impossible_value"
          },
          "if_unavailable":"omit_set"
        }
      },
      "optional_claim": {
        "if_unavailable":"abort",
        "if_different":"omit_set",
        "value":"possible_value"
      }
    }
    

    I now feel that it might be better to devise another different syntax for SAO. In particular, it might be better to let RPs specify evaluation order like below. (The concern described in the Privacy Considerations section is a different matter from SAO syntax.)

    {
      "sao": {
        "omit_set": [
          "/verified_claims/verification/assurance_level",
          "/verified_claims/claims/family_name"
        ],
        "evaluation_order": [
          [ "omit", "if_different", "/verified_claims/claims/family_name" ],
          [ "omit_set", "if_unavailable", "/verified_claims/claims/family_name" ],
          [ "omit_verified_claims", "if_unavailable", "/verified_claims/verification/assurance_level" ],
          [ "abort", "if_unavailable", "/verified_claims/claims/given_name" ]
        ]
      }
    }
    

    The above syntax is not necessarily my recommendation. It is just an example of other syntax for brainstorming.

  5. Daniel Fett

    Mark and I discussed this, and we thought to make the following changes to SAO:

    • omit_verified_claims is removed. In many cases, omit_set can be used instead.
    • omit and omit_set does not result in if_unavailable any longer. Instead, the respective claim(s) is just omitted from the response. This should break the cycle and avoid the need for recursive execution.
    • The execution order should be changed to the following:

      • check all claims with an abort action

        • for the claim, first check if_unavailable, then if_different.
        • as in the current spec, if any abort is triggered, further processing is not required
      • check all claims with an omit action

        • as above
      • check all claims with an omit_set action

        • as above

    What do you think, @Takahiko Kawasaki ?

  6. Takahiko Kawasaki reporter

    Well, I started to doubt that if_different is worthless, especially when its action is omit or omit_set

    if_different assumes that at least one of value, values and max_age is specified. AS implementations use value, values and max_age to find a dataset that matches the requirements. That the condition of if_different becomes true implies that the dataset is not selected. If so, what does it mean to omit some parts of the unselected dataset?

    Suppose that an AS receives the following request,

    {
      "userinfo": {
        "verified_claims": {
          "verification": {
            "trust_framework": null,
            "evidence": [
              {
                "type": {
                  "value": "electronic_signature"
                },
                "issuer": {
                  "value": "ABC",
                  "if_different": "omit"
                },
                "serial_number": {
                  "value": "123",
                  "if_different": "omit"
                },
                "created_at": null
              }
            ]
          },
          "claims": {
            "family_name": null
          }
        }
      }
    }
    

    and the AS holds the following evidence:

    type issuer serial_number
    electronic_signature ABC 456
    electronic_signature DEF 123

    In this case, what should the evidence array in the response hold? Possible answers may be the following.

    1. {"type":"electronic_signature", "issuer":"ABC", "created_at":"..."}
    2. {"type":"electronic_signature", "serial_number":"123", "created_at":"..."}
    3. No evidence available that matches the requirements

    I guess that AS implementers will choose the last answer. If so, if_different's in the request are meaningless.

    I’ve not dug into this deeply yet, but my intuition at the time of this writing is that it would be difficult to find use cases where if_different meaningfully functions. If there are any, please let me know.

  7. Takahiko Kawasaki reporter

    In my opinion, Joseph’s answer in the AB/Connect mailing list does not conflict with the OIDC4IDA specification.

    The Section 7.7.2. Data not Matching Requirements of OIDC4IDA says as follows:

    When the available data does not fulfill the requirements of the RP expressed through value, values, or max_age, the following logic applies:

    • If the respective requirement was expressed for a Claim within verified_claims/verification, the whole verified_claims element MUST be omitted.

    • Otherwise, the respective Claim MUST be omitted from the response.

    The value, values and max_age constraints can work as filters under verified_claims/verification. At the same time, the constraints under verified_claims/claims have a different role and they can be used to omit unmatched claims. The behavior of the constraints under verified_claims/claims is the same as the one described by Joseph’s answer (i.e. the behavior of OIDC Core).

  8. Takahiko Kawasaki reporter

    DataExtractor.java in the authlete-java-common library is an open-source implementation of “Data Minimization” and “Filtering” as I mentioned in my blog “OpenID Connect for Identity Assurance, explained by an implementer“. DataExtractorTest.java contains tests for the implementation.

    If you change the value of LOGGING_ENABLED in DataExtractorTest.java to true

        /**
         * Flag for logging of {@link DatasetExtractor}. Set {@code true} if you
         * want to view details logs.
         */
        private static final boolean LOGGING_ENABLED = true;
    

    and run the tests, you can see how the logic of Data Minimization and Filtering visits data elements in verified_claims.

    git clone https://github.com/authlete/authlete-java-common
    cd authlete-java-common
    vi src/test/java/com/authlete/common/ida/DatasetExtractorTest.java
    mvn -Dtest=com.authlete.common.ida.DatasetExtractorTest test
    

    The following is a sample output of the tests.

    [INFO] Scanning for projects...
    [WARNING] 
    [WARNING] Some problems were encountered while building the effective model for com.authlete:authlete-java-common:jar:3.36-SNAPSHOT
    [WARNING] 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-site-plugin is missing. @ line 120, column 29
    [WARNING] Reporting configuration should be done in <reporting> section, not in maven-site-plugin <configuration> as reportPlugins parameter. @ line 123, column 40
    [WARNING] 
    [WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
    [WARNING] 
    [WARNING] For this reason, future Maven versions might no longer support building such malformed projects.
    [WARNING] 
    [INFO] 
    [INFO] -----------------< com.authlete:authlete-java-common >------------------
    [INFO] Building com.authlete:authlete-java-common 3.36-SNAPSHOT
    [INFO] --------------------------------[ jar ]---------------------------------
    [INFO] 
    [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ authlete-java-common ---
    [INFO] Using 'UTF-8' encoding to copy filtered resources.
    [INFO] Copying 1 resource
    [INFO] 
    [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ authlete-java-common ---
    [INFO] Changes detected - recompiling the module!
    [INFO] Compiling 215 source files to /Users/taka/GitHub/authlete-java-common/target/classes
    [INFO] 
    [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ authlete-java-common ---
    [INFO] Using 'UTF-8' encoding to copy filtered resources.
    [INFO] Copying 1 resource
    [INFO] 
    [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ authlete-java-common ---
    [INFO] Nothing to compile - all classes are up to date
    [INFO] 
    [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ authlete-java-common ---
    [INFO] Surefire report directory: /Users/taka/GitHub/authlete-java-common/target/surefire-reports
    
    -------------------------------------------------------
     T E S T S
    -------------------------------------------------------
    Running com.authlete.common.ida.DatasetExtractorTest
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/trust_framework=null, original:/verification/trust_framework="uk_tfida"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/given_name={values=["Unknown0""Unknown1"]}, original:/claims/given_name="Sarah"> [DE07] The property does not satisfy the constraint, and therefore the property is omitted.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/family_name=null, original:/claims/family_name="Meredyth"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/trust_framework=null, original:/verification/trust_framework="uk_tfida"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/given_name=null, original:/claims/given_name="Sarah"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/trust_framework=null, original:/verification/trust_framework="my_framework"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/datetime_0={max_age=2000000000}, original:/claims/datetime_0="2022-04-22T12:34:56"> [DE08] The property satisfies the constraint, and therefore the property is put in the copy.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/datetime_1={max_age=2000000000}, original:/claims/datetime_1="2022-04-22T12:34:56+0900"> [DE08] The property satisfies the constraint, and therefore the property is put in the copy.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/datetime_2={max_age=2000000000}, original:/claims/datetime_2="2022-04-22T12:34:56Z"> [DE08] The property satisfies the constraint, and therefore the property is put in the copy.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/datetime_3={max_age=2000000000}, original:/claims/datetime_3="2022-04-22T12:34"> [DE08] The property satisfies the constraint, and therefore the property is put in the copy.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/datetime_4={max_age=2000000000}, original:/claims/datetime_4="2022-04-22T12:34+0900"> [DE08] The property satisfies the constraint, and therefore the property is put in the copy.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/datetime_5={max_age=2000000000}, original:/claims/datetime_5="2022-04-22T12:34Z"> [DE08] The property satisfies the constraint, and therefore the property is put in the copy.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/trust_framework=null, original:/verification/trust_framework="uk_tfida"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/given_name={value="Unknown"}, original:/claims/given_name="Sarah"> [DE07] The property does not satisfy the constraint, and therefore the property is omitted.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/family_name=null, original:/claims/family_name="Meredyth"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/trust_framework=null, original:/verification/trust_framework="uk_tfida"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/address/locality=null, original:/claims/address/locality="Edinburgh"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/trust_framework=null, original:/verification/trust_framework="uk_tfida"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/given_name=null, original:/claims/given_name="Sarah"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/:tc=null, original:/claims/:tc=null> [DE02] The property is unavailable, and therefore omitted.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/::predefined_tc={object}, original:/claims/::predefined_tc=null> [DE02] The property is unavailable, and therefore omitted.
    [main] DEBUG com.authlete.common.ida.DatasetExtractorTest - <request:/verification/trust_framework={value="unknown"}, original:/verification/trust_framework="uk_tfida"> [DE06] The property does not satisfy the constraint, so matching fails.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/trust_framework=null, original:/verification/trust_framework="uk_tfida"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/given_name={values=["Unknown0""Sarah"]}, original:/claims/given_name="Sarah"> [DE08] The property satisfies the constraint, and therefore the property is put in the copy.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/family_name=null, original:/claims/family_name="Meredyth"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/trust_framework=null, original:/verification/trust_framework="uk_tfida"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/assurance_process/assurance_details=null, original:/verification/assurance_process/assurance_details=[array]> [DE23] All available sub-elements under 'assurance_details' are unconditionally returned based on the special rule for the property.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/given_name=null, original:/claims/given_name="Sarah"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/trust_framework=null, original:/verification/trust_framework="uk_tfida"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/birthdate={max_age=2000000000}, original:/claims/birthdate="1976-03-11"> [DE08] The property satisfies the constraint, and therefore the property is put in the copy.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/family_name=null, original:/claims/family_name="Meredyth"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/trust_framework=null, original:/verification/trust_framework="uk_tfida"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] DEBUG com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/type={value="electronic_record"}, original:/verification/evidence/0/type="document"> [DE06] The property does not satisfy the constraint, so matching fails.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/type={value="electronic_record"}, original:/verification/evidence/1/type="electronic_record"> [DE08] The property satisfies the constraint, and therefore the property is put in the copy.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0/check_method=null, original:/verification/evidence/1/check_details/0/check_method="kbv"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0/organization={value="TheCreditBureau"}, original:/verification/evidence/1/check_details/0/organization="TheCreditBureau"> [DE08] The property satisfies the constraint, and therefore the property is put in the copy.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0/txn=null, original:/verification/evidence/1/check_details/0/txn="kbv1-hf934hn09234ng03jj3"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0={object}, original:/verification/evidence/1/check_details/0={object}> [DE20] The element in the array in the original dataset satisfies conditions of the element in the array in the request.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details=[array], original:/verification/evidence/1/check_details=[array]> [DE22] Some elements in the array in the original dataset satisfy any of the elements in the array in the request.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0={object}, original:/verification/evidence/1={object}> [DE20] The element in the array in the original dataset satisfies conditions of the element in the array in the request.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/type={value="electronic_record"}, original:/verification/evidence/2/type="electronic_record"> [DE08] The property satisfies the constraint, and therefore the property is put in the copy.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0/check_method=null, original:/verification/evidence/2/check_details/0/check_method="kbv"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] DEBUG com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0/organization={value="TheCreditBureau"}, original:/verification/evidence/2/check_details/0/organization="OpenBankingTPP"> [DE06] The property does not satisfy the constraint, so matching fails.
    [main] DEBUG com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details=[array], original:/verification/evidence/2/check_details=[array]> [DE21] None of the elements in the array in the original dataset satisfy any of the elements in the array in the request. Therefore, matching fails.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/type={value="electronic_record"}, original:/verification/evidence/3/type="electronic_record"> [DE08] The property satisfies the constraint, and therefore the property is put in the copy.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0/check_method=null, original:/verification/evidence/3/check_details/0/check_method="kbv"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] DEBUG com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0/organization={value="TheCreditBureau"}, original:/verification/evidence/3/check_details/0/organization="GSMA"> [DE06] The property does not satisfy the constraint, so matching fails.
    [main] DEBUG com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details=[array], original:/verification/evidence/3/check_details=[array]> [DE21] None of the elements in the array in the original dataset satisfy any of the elements in the array in the request. Therefore, matching fails.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/type={value="electronic_record"}, original:/verification/evidence/4/type="electronic_record"> [DE08] The property satisfies the constraint, and therefore the property is put in the copy.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0/check_method=null, original:/verification/evidence/4/check_details/0/check_method="data"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] DEBUG com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0/organization={value="TheCreditBureau"}, original:/verification/evidence/4/check_details/0/organization="GRO"> [DE06] The property does not satisfy the constraint, so matching fails.
    [main] DEBUG com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details=[array], original:/verification/evidence/4/check_details=[array]> [DE21] None of the elements in the array in the original dataset satisfy any of the elements in the array in the request. Therefore, matching fails.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/type={value="electronic_record"}, original:/verification/evidence/5/type="electronic_record"> [DE08] The property satisfies the constraint, and therefore the property is put in the copy.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0/check_method=null, original:/verification/evidence/5/check_details/0/check_method="data"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] DEBUG com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0/organization={value="TheCreditBureau"}, original:/verification/evidence/5/check_details/0/organization="NextLex"> [DE06] The property does not satisfy the constraint, so matching fails.
    [main] DEBUG com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details=[array], original:/verification/evidence/5/check_details=[array]> [DE21] None of the elements in the array in the original dataset satisfy any of the elements in the array in the request. Therefore, matching fails.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence=[array], original:/verification/evidence=[array]> [DE22] Some elements in the array in the original dataset satisfy any of the elements in the array in the request.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/given_name=null, original:/claims/given_name="Sarah"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/trust_framework=null, original:/verification/trust_framework="uk_tfida"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/birthdate={max_age=100}, original:/claims/birthdate="1976-03-11"> [DE07] The property does not satisfy the constraint, and therefore the property is omitted.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/family_name=null, original:/claims/family_name="Meredyth"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/trust_framework=null, original:/verification/trust_framework="uk_tfida"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] DEBUG com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/type={value="electronic_record"}, original:/verification/evidence/0/type="document"> [DE06] The property does not satisfy the constraint, so matching fails.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/1/type={value="document"}, original:/verification/evidence/0/type="document"> [DE08] The property satisfies the constraint, and therefore the property is put in the copy.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/1={object}, original:/verification/evidence/0={object}> [DE20] The element in the array in the original dataset satisfies conditions of the element in the array in the request.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/type={value="electronic_record"}, original:/verification/evidence/1/type="electronic_record"> [DE08] The property satisfies the constraint, and therefore the property is put in the copy.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0/check_method=null, original:/verification/evidence/1/check_details/0/check_method="kbv"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0/organization={value="TheCreditBureau"}, original:/verification/evidence/1/check_details/0/organization="TheCreditBureau"> [DE08] The property satisfies the constraint, and therefore the property is put in the copy.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0/txn=null, original:/verification/evidence/1/check_details/0/txn="kbv1-hf934hn09234ng03jj3"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0={object}, original:/verification/evidence/1/check_details/0={object}> [DE20] The element in the array in the original dataset satisfies conditions of the element in the array in the request.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details=[array], original:/verification/evidence/1/check_details=[array]> [DE22] Some elements in the array in the original dataset satisfy any of the elements in the array in the request.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0={object}, original:/verification/evidence/1={object}> [DE20] The element in the array in the original dataset satisfies conditions of the element in the array in the request.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/type={value="electronic_record"}, original:/verification/evidence/2/type="electronic_record"> [DE08] The property satisfies the constraint, and therefore the property is put in the copy.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0/check_method=null, original:/verification/evidence/2/check_details/0/check_method="kbv"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] DEBUG com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0/organization={value="TheCreditBureau"}, original:/verification/evidence/2/check_details/0/organization="OpenBankingTPP"> [DE06] The property does not satisfy the constraint, so matching fails.
    [main] DEBUG com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details=[array], original:/verification/evidence/2/check_details=[array]> [DE21] None of the elements in the array in the original dataset satisfy any of the elements in the array in the request. Therefore, matching fails.
    [main] DEBUG com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/1/type={value="document"}, original:/verification/evidence/2/type="electronic_record"> [DE06] The property does not satisfy the constraint, so matching fails.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/type={value="electronic_record"}, original:/verification/evidence/3/type="electronic_record"> [DE08] The property satisfies the constraint, and therefore the property is put in the copy.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0/check_method=null, original:/verification/evidence/3/check_details/0/check_method="kbv"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] DEBUG com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0/organization={value="TheCreditBureau"}, original:/verification/evidence/3/check_details/0/organization="GSMA"> [DE06] The property does not satisfy the constraint, so matching fails.
    [main] DEBUG com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details=[array], original:/verification/evidence/3/check_details=[array]> [DE21] None of the elements in the array in the original dataset satisfy any of the elements in the array in the request. Therefore, matching fails.
    [main] DEBUG com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/1/type={value="document"}, original:/verification/evidence/3/type="electronic_record"> [DE06] The property does not satisfy the constraint, so matching fails.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/type={value="electronic_record"}, original:/verification/evidence/4/type="electronic_record"> [DE08] The property satisfies the constraint, and therefore the property is put in the copy.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0/check_method=null, original:/verification/evidence/4/check_details/0/check_method="data"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] DEBUG com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0/organization={value="TheCreditBureau"}, original:/verification/evidence/4/check_details/0/organization="GRO"> [DE06] The property does not satisfy the constraint, so matching fails.
    [main] DEBUG com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details=[array], original:/verification/evidence/4/check_details=[array]> [DE21] None of the elements in the array in the original dataset satisfy any of the elements in the array in the request. Therefore, matching fails.
    [main] DEBUG com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/1/type={value="document"}, original:/verification/evidence/4/type="electronic_record"> [DE06] The property does not satisfy the constraint, so matching fails.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/type={value="electronic_record"}, original:/verification/evidence/5/type="electronic_record"> [DE08] The property satisfies the constraint, and therefore the property is put in the copy.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0/check_method=null, original:/verification/evidence/5/check_details/0/check_method="data"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] DEBUG com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0/organization={value="TheCreditBureau"}, original:/verification/evidence/5/check_details/0/organization="NextLex"> [DE06] The property does not satisfy the constraint, so matching fails.
    [main] DEBUG com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details=[array], original:/verification/evidence/5/check_details=[array]> [DE21] None of the elements in the array in the original dataset satisfy any of the elements in the array in the request. Therefore, matching fails.
    [main] DEBUG com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/1/type={value="document"}, original:/verification/evidence/5/type="electronic_record"> [DE06] The property does not satisfy the constraint, so matching fails.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence=[array], original:/verification/evidence=[array]> [DE22] Some elements in the array in the original dataset satisfy any of the elements in the array in the request.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/given_name=null, original:/claims/given_name="Sarah"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/trust_framework=null, original:/verification/trust_framework="uk_tfida"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/given_name=null, original:/claims/given_name="Sarah"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/:tc=null, original:/claims/:tc=null> [DE01] A transformed claim was found.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/::predefined_tc={object}, original:/claims/::predefined_tc=null> [DE01] A transformed claim was found.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/trust_framework={object}, original:/verification/trust_framework="uk_tfida"> [DE09] The request has no constraint for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/given_name=null, original:/claims/given_name="Sarah"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/trust_framework=null, original:/verification/trust_framework="uk_tfida"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/type={value="electronic_record"}, original:/verification/evidence/0/type="electronic_record"> [DE08] The property satisfies the constraint, and therefore the property is put in the copy.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0/check_method=null, original:/verification/evidence/0/check_details/0/check_method="kbv"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] DEBUG com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0/organization={value="OpenBankingTPP"}, original:/verification/evidence/0/check_details/0/organization="TheCreditBureau"> [DE06] The property does not satisfy the constraint, so matching fails.
    [main] DEBUG com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details=[array], original:/verification/evidence/0/check_details=[array]> [DE21] None of the elements in the array in the original dataset satisfy any of the elements in the array in the request. Therefore, matching fails.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/type={value="electronic_record"}, original:/verification/evidence/1/type="electronic_record"> [DE08] The property satisfies the constraint, and therefore the property is put in the copy.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0/check_method=null, original:/verification/evidence/1/check_details/0/check_method="kbv"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0/organization={value="OpenBankingTPP"}, original:/verification/evidence/1/check_details/0/organization="OpenBankingTPP"> [DE08] The property satisfies the constraint, and therefore the property is put in the copy.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0/txn=null, original:/verification/evidence/1/check_details/0/txn="kbv2-nm0f23u9459fj38u5j6"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details/0={object}, original:/verification/evidence/1/check_details/0={object}> [DE20] The element in the array in the original dataset satisfies conditions of the element in the array in the request.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0/check_details=[array], original:/verification/evidence/1/check_details=[array]> [DE22] Some elements in the array in the original dataset satisfy any of the elements in the array in the request.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence/0={object}, original:/verification/evidence/1={object}> [DE20] The element in the array in the original dataset satisfies conditions of the element in the array in the request.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/verification/evidence=[array], original:/verification/evidence=[array]> [DE22] Some elements in the array in the original dataset satisfy any of the elements in the array in the request.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/given_name=null, original:/claims/given_name="Sarah"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/family_name={value="Unknown"}, original:/claims/family_name="Meredyth"> [DE07] The property does not satisfy the constraint, and therefore the property is omitted.
    [main] TRACE com.authlete.common.ida.DatasetExtractorTest - <request:/claims/address/locality=null, original:/claims/address/locality="Edinburgh"> [DE04] The request does not have constraints for the property, and therefore the property is put in the copy unconditionally.
    Tests run: 16, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.49 sec
    
    Results :
    
    Tests run: 16, Failures: 0, Errors: 0, Skipped: 0
    
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  8.994 s
    [INFO] Finished at: 2022-09-08T00:58:17+09:00
    [INFO] ------------------------------------------------------------------------
    

    A point worth learning from the log is that element-level if_unavailable and if_different conditions will not work well due to the nature of “Logical OR by Array”.

    For example, in the OR operation, [false, true] should be regarded as true although the first element is false. If if_unavailable is a per-element operator and is attached to the first element, the action specified by the if_unavailable has to be executed although the final evaluation of the upper array (i.e. [false, true]) should become true.

    This is the reason I have reached a conclusion that per-element if_unavailable and if_different won’t work and another approach has to be devised. See also my comments in Issue 1301.

  9. Daniel Fett

    I thought about this problem a little more. One problem identified in this discussion is that anything we put into the claims' dictionaries in the structure lacks an explicit evaluation order. If we want to make this order explicit, we need to have an array with the rules that are to be applied. If we have such an array, it would need to live outside of particular claims and it would need to reference the claims. For the reference, I see no good way other than using established syntax, like JsonPath. If we start with JsonPath, we can use it to refer to both the claims to which a rule applies as well as the claims which shall be omitted.

    How about this structure?

    {
      "id_token": {
        "verified_claims": {
          "verification": {
            "trust_framework": null,
            "assurance_level": {
              "value":"example_assurance_level"
            }
          },
          "claims": {
            "family_name": {
              "value":"nonexistent_family_name"
            },
            "given_name": null,
            "birthdate": {
              "value":"1980-01-01"
            }
          }
        },
        "asc/sao-processing-rules": [
            // when assurance level is unavailable, omit verified_claims
            {
                "claim": ["$.verified_claims.verification.assurance_level"],
                "if": "unavailable",
                "then": "omit",
                "what": ["$.verified_claims"]
            },
            // when assurance level is different, omit verified_claims
            {
                "claim": ["$.verified_claims.verification.assurance_level"],
                "if": "different",
                "then": "omit",
                "what": ["$.verified_claims"]
            },
            // when either name component is unavailable, omit both components
            {
                "claim": ["$.verified_claims.claims.family_name", "$.verified_claims.claims.given_name"],
                "if": "unavailable",
                "then": "omit",
                "what": ["$.verified_claims.claims.family_name", "$.verified_claims.claims.given_name"]
            },
            // when birthdate is unavailable, abort transaction
            {
                "claim": ["$.verified_claims.claims.birthdate"],
                "if": "different",
                "then": "abort"
            }
        ]
      }
    }
    

    Advantages:

    • The order of the rules is explicit: Just follow from top to bottom.
    • No backtracking needed: Each rules is evaluated based on the previous rule’s output.
    • Easy to read.
    • Easy to process - for the JSONPaths, we would only allow dot-separated components, not other elements of JSONPath. (I.e., only $.a.b.c, not, for example $.a.* or $.a..c as the meaning might not be clearly defined.) Implementers can use a JSONPath library, but don’t need to.
    • The rules in asc/sao-processing-rules can be evaluated after retrieving the data - there is no need to mix logic for retrieving the data and processing the ASC/SAO rules.

    This is similar to Taka’s approach proposed above, but does not need explicit sets (for the price of some repetition, but I guess that will be fine).

  10. Takahiko Kawasaki reporter
    • "if":"different" needs an argument for comparison.
    • A point to consider is that the value of verified_claims can be a JSON array. So, the new syntax has to be able to accommodate both a JSON object and a JSON array. (e.g. $.verified_claims.xyz matches "verified_claims":{”xyz”:123} but does not match "verified_claims":[{"xyz": 123}])

  11. Daniel Fett

    Regarding the first point, the value to compare with would be given in usual OIDC syntax as the “value” element in the original claim.

    For the second point: Indeed, we need to find a good way to handle that. Not sure what that could be yet.

  12. Mark Haine

    I have been thinking this through again and it strikes me that we are writing a domain specific language for expressing some policy that the RP would like applied to the returned claims. If that is the case then I think there is some merit in looking at existing policy description languages. There are two that I know of that are ‘standardised’ in some way… XACML and Rego.

    I’m pretty sure we are not interested in an XML based approach so I had a look at Rego.

    While I think that Rego is probably far too rich for our needs I think there may be some significant merit in copying what we need from it. There is also a possibility (Daniel’s idea not mine) that defining a DSL that is a close derivative of Rego might allow for easy transformation of a SAO policy into compliant Rego which could then in turn be executed using existing OPA software implementations potentially reducing the complexity for implementers.

  13. Mark Haine

    Here’s an example Rego policy that implements quite a bit of the use case Daniel’s example shows. The input object is the claims request parameter without SAO extensions and the data object is the data held at the IDP about the end-user.

    The current output is a list of actions either abort or omit (with list of objects to omit)

    package app.sao
    
    import future.keywords.if
    import future.keywords.contains
    
    omit contains omitlistentry if { # family name different then omit family_name only unless aborted
        data.verified_claims.claims.family_name != input.id_token.verified_claims.claims.family_name.value
        not abort # don't list omit if abort is true 
        omitlistentry := "data.verified_claims.claims.family_name"
    }
    
    omit contains omitlistentry if { # assurance level different then omit verified_claims
        data.verified_claims.verification.assurance_level != input.id_token.verified_claims.verification.assurance_level.value
        not abort # don't list omit if abort is true 
        omitlistentry := "data.verified_claims"
    }
    
    omit contains omitlistentry if { # assurance level unavailable then omit verified_claims
        not data.verified_claims.verification.assurance_level
        not abort # don't list omit if abort is true 
        omitlistentry := "data.verified_claims"
    }
    
    abort := true if { # claims request birthdate value different from data birthdate then abort
        data.verified_claims.claims.birthdate != input.id_token.verified_claims.claims.birthdate.value
    }
    

  14. Takahiko Kawasaki reporter

    As we talked in the last WG call, if we adopt a rich language like Rego for SAO (Selective Abort/Omit), the language would be able to be used for TC (Transformed Claims), too. And the language may be able to replace the current “verified_claims” request sytax completely.

    Daniel pointed out that SAO/TC capabilities should not enable clients to retrieve unintended information of the user. Other points to consider are how easy to implement, how easy to use, whether Rego implementations are available in popular computer languages developers use.

    A small language is interesting to support and implement. However, a good point of the current specification of TC is “all are expressed in JSON”. Because JSON parsers available widely can be used, lexer & tokenizer and parser don’t have to be written from scratch.

  15. Daniel Fett

    I revisited the latest proposal and took another look at DIF Presentation Exchange. It seems that the current proposal has at least the following problems:

    1. The problem with arrays identified by Taka above
    2. The fact that if_different does not translate well into database queries as pointed out also by Taka
    3. We cannot currently express things like “I need an evidence document with these two properties or one with these two other properties” (i.e., we cannot express related properties over more than one claim at a time)

    I’m comparing again to PE and looking at other existing JSON query approaches (like jq) to figure out the best way forward.

  16. Mark Haine

    Some of the following are covered by current propsal but we should be clear about our scope and avoid complexity if possible. I suspect there may be more use cases that we might consider. It would be good to find consensus on what is in scope what is out of scope.

    Some are about conditions and some are about actions, some may be combinations…

    Single claim conditions:

    • return a sub-claim e.g. address.country
    • perform data minimisation on a single claim e.g.

      • 01/01/2010 → over-18;
      • “James” → “J”;
      • jim@example.com → example.com
    • match presented value e.g.

      • email = “is e-mail jim@example.com → true. (special case of data minimisation?)
    • Combination of sub claim and data minimisation e.g.

    Combination of claim conditions across multiple ase claims:

    • (address.country = GB) AND (age over 18)

    Actions:

    • Abort whole request
    • omit the single claim subject to the condition
    • omit a single set of claims
    • omit verified claims regardless of base claim of condition
    • omit more than one set of claims

  17. Daniel Fett

    Together with Transformed Claims, the approaches in the slide deck can all cover all of these cases. The one case where they differ is

    • ((address.country = GB) AND (age over 18)) OR ((address.country = US) AND (age over 21))

    This can only be covered by 3, 4, and 5.

  18. Mark Haine

    During the WG call today there was a decision to move forward with Proposal 5 in Daniel’s spreadsheet “Partial JSON Schema + filter“

    Next steps are that DF will update the ASC draft, the WG may choose to proceed to ASC Implementers' draft 1 and Authlete have kindly said that they will find time to do a POC implementation.

  19. Log in to comment