Closed dwaite closed 2 years ago
While this has a very nice simplicity to it, I do believe it will be necessary to support additional header values per-payload such as content type. One alternative strategy might be for JWP to require the JWK simply uniquely name/identify each payload, and that applications must be able to determine the content type from the name/id by context or some external mechanism. This is similar to how the JWT defines certain claim names and the exact type of value for each (NumericDate
, StringOrURI
, etc) and it's opaque to the JWS.
This would look something like:
{ "payloads": ["family_name", "given_name", "E18FF842", "http://www.w3.org/2002/12/cal/ical#"] }
The path-like syntax would only be relevant to applications that want to re-combine multiple payloads, and given the privacy focus of JWP I'm not sure that is a safe approach to encourage. Applications will need to understand for any given payload if the result is from a proof (predicate, boolean, etc) and should not rely on always expecting the raw claim values.
Since we seem to have a primary pattern of data applied to a template [e.g. MadLibs] there could be a lot of variance and bike shedding to how we describe JWT-style claims. I suggest we try to have a solid initial proposal before going to a wider group, and be willing to encourage multiple sheds if things are too divergent.
Converting between objects and arrays is a very solved problem... its a terrible idea for a JSON based standard to invent a new way of doing this... here is an example using JSON Pointer.
import pointer from 'json-pointer';
const objectToMessages = (obj: any) => {
const dict = pointer.dict(obj);
const messages = Object.keys(dict).map(key => {
return `{"${key}": "${dict[key]}"}`;
});
return messages;
};
const messagesToObject = (messages: string[]) => {
const obj = {};
messages
.map(m => {
return JSON.parse(m);
})
.forEach(m => {
const [key] = Object.keys(m);
const value = m[key];
pointer.set(obj, key, value);
});
return obj;
};
export { objectToMessages, messagesToObject };
const messages = await objectToMessages(credential);
expect(messages).toEqual([
'{"/@context/0": "https://www.w3.org/2018/credentials/v1"}',
'{"/@context/1/alsoKnownAs": "https://www.w3.org/ns/activitystreams#alsoKnownAs"}',
'{"/id": "http://example.edu/credentials/3732"}',
'{"/type/0": "VerifiableCredential"}',
'{"/issuer": "https://example.edu/issuers/14"}',
'{"/issuanceDate": "2010-01-01T19:23:24Z"}',
'{"/credentialSubject/alsoKnownAs": "did:example:ebfeb1f712ebc6f1c276e12ec21"}',
]);
The domain of the "key" side should be fixed and use json pointer.
The domain of the "value" side is the problem.
I would propose that it be limited to legal JSON primitive "values", aka:
https://www.json.org/json-en.html
"string", "number", "boolean" or "null".
When handling a higher order JWP object, you might find that "isOver21: true" is constructed from complexity, but a holder when inspecting these credentials should not be forced to see that when observing claims.
Since we've currently settled on the simple flat claims
array in the latest draft, I'm going to close this issue.
We can open a new issue if there's a new proposal moving forward from the current draft.
I would like to propose an alternative format for credential claims from metadata:
Payload slot metadata
Corresponding payload slot
The claims payload property is always an array of one or more keys, while the slot would be an array of one or more values.
A credential-level specification can use this definition for combining claims into a JSON document, including how to combine multiple payload slots into a resulting JSON document for exposure to the application level on the verifier.
One motivation here is to have a simplified path-like syntax for the claims names for describing how to compose more complex documents, e.g. a payload slot metadata of: