Skip to content

First draft of HTML Render Method.#42

Open
BigBlueHat wants to merge 17 commits intomainfrom
html-render-method
Open

First draft of HTML Render Method.#42
BigBlueHat wants to merge 17 commits intomainfrom
html-render-method

Conversation

@BigBlueHat
Copy link
Member

@BigBlueHat BigBlueHat commented Jan 9, 2026

This is a very early draft of the HTML Render Method approach mentioned on this weeks call. It's currently more descriptive than "spec-ready" so the MUST language is likely misplaced and decisions need making around what the MUSTs must be (heh) for environments not running in a "classic" Web browser of WebView.

Additionally, I'm also writing up the specifics for providing and using a "ready"/"error" handler so the template can let the Wallet know when it's ready to be displayed...or when it's errored out.

@dlongley deserves all the credit for this design.

Cheers!
🎩


Preview | Diff

@dlongley
Copy link

dlongley commented Jan 9, 2026

For interested developers, there is a dev-targeted demo here (may be actively changed so be forewarned):

https://digitalbazaar.github.io/html-render-method-test

With source code here:

https://github.com/digitalbazaar/html-render-method-test

To make it clear these are not to be rendered on their own.
@dmitrizagidulin
Copy link
Collaborator

PR discussed in the Wed Jan 28 call. This is a great start, moving in the right direction. Ivan requested a bit more specification algorithm code before merging the PR (diagram will come later). To do:

  • Add spec language / algorithm
  • Consider instead of injecting the full (but pre-filtered) VC, instead inject a "data" object that is just key/value pairs (keys being the JSON Pointers, values being the property values from the VC)
  • Add a separate template example, with CSS
  • Clarify roles -- trusted template provider, renderer (who has access to the full VC)
  • Clarify the use of "selective disclosure" (the filtering of non-shared fields before it gets injected into the template)
  • We're using JSON Pointers instead of JSON Paths here

@BigBlueHat
Copy link
Member Author

  • Add spec language / algorithm

First draft of this is done.

  • Consider instead of injecting the full (but pre-filtered) VC, instead inject a "data" object that is just key/value pairs (keys being the JSON Pointers, values being the property values from the VC)

I corrected the example code and also referenced the selectJsonLd method described in Data Integrity ECDSA Cryptosuites v1.0 per @dlongley's suggestion. It essentially uses JSON Pointer on the original VC and results in a partial VC as a JSON object.

Sample code for that approach is available at https://github.com/digitalbazaar/html-render-method-test/blob/main/select.js

  • Add a separate template example, with CSS

I added CSS to the main example instead.

  • Clarify roles -- trusted template provider, renderer (who has access to the full VC)

I wasn't quite sure how to address this one. The template code is considered to have the same "trust" levels as any other data in or referenced by the VC in question. A sandboxed iframe is used to prevent network access, etc. to (in part) avoid the need for additional "trust" to be brokered around the template code provided via the render method.

  • Clarify the use of "selective disclosure" (the filtering of non-shared fields before it gets injected into the template)

The flowchart I added used "selective disclosure" but much of the text I wrote talks about a "filtered" VC. It's something the group should discuss as I don't think we want to force selective disclosure cryptograph on folks considering this Render Method approach, but if a Wallet/Renderer had that capability, there's perhaps added value for certain use cases (such as rendering a VC Barcode of the derived credential.

  • We're using JSON Pointers instead of JSON Paths here

Yeah...that "bug" was just in how I was talking about things on the call. It wasn't in the text. They're very easy to confuse (imo) given the one that looks like a filesystem path is the Pointer... 😖 Anyhow. Not a bug with the text, in this case (thankfully!).

If folks seem happy "enough", I'd love to get this PR merged, so we can then work on smaller revisions to it and avoid a long lived PR.

Thanks!
🎩

Copy link
Member

@msporny msporny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some general suggestions:

  • We need to create definitions for what 'host page', 'shim code', and 'template code' mean -- they can be inline definitions (don't have to go in the Terminology section), but having to capitalize things repeatedly throughout the document is a code smell that usually signals that a definition is needed.
  • Use lowercase names for definitions and links to definitions -- we had a big discussion about this in previous WGs and decided to just lowercase all definitions (except for acronyms).
  • Don't use lowercase RFC words because we get ding'd for it when others review the spec and it's also been used as a DDoS on the WG in the 11th hour, so we shouldn't open that opportunity.

I didn't try to put forward change corrections for every usage of "Host Page" or "Shim Code", so please make those changes globally as I stopped around halfway through.

Other than that, LGTM, thanks for doing all the work that went into this, @BigBlueHat and @dlongley!

Comment on lines +856 to +857
If `renderMethod.template` is a [=map=], then let `template` be the result of
fetching the URL in `renderMethod.template.id`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should note that, in general, all fetches SHOULD be performed over OHTTP or similar mechanism. I think we have a section in the VC Data Model that says something to this effect, so pointing there might be a good thing to do here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's this section: https://w3c.github.io/vc-data-model/#device-tracking-and-fingerprinting

Maybe we reference that generally in this spec (as a separate PR)?

Copy link
Member

@msporny msporny Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine to put it in another PR (as long as we don't forget to do so).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe create an issue to track doing so?

On `resolve`, may be used to display the `iframe` to the user.
</li>
<li>
On `reject`, display the error message to the user.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
On `reject`, display the error message to the user.
On `reject`, displays the error message to the user.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is an algorithm, I think the active voice (display) makes more sense here than the passive voice (displays). We're dictating what action needs to be done. /cc @TallTed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine to keep it as long as the language is consistently active voice.

Copy link
Member

@TallTed TallTed Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The preceding can be used to display doesn't flow well into the imperative display the error message, though I do agree the latter is better for an algorithm. Consistency is challenging.

Copy link
Member

@TallTed TallTed Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rereading in context, the imperative is incorrect.

With imperative, the full sentence becomes "Let renderPromise be a new Promise that, on reject, display the error message to the user." ("a new Promise ... that display the ... message").

Without the imperative, the full sentence becomes "Let renderPromise be a new Promise that, on reject, displays the error message to the user." ("a new Promise ... that displays the ... message").

@BigBlueHat
Copy link
Member Author

  • We need to create definitions for what 'host page', 'shim code', and 'template code' mean -- they can be inline definitions (don't have to go in the Terminology section), but having to capitalize things repeatedly throughout the document is a code smell that usually signals that a definition is needed.
  • Use lowercase names for definitions and links to definitions -- we had a big discussion about this in previous WGs and decided to just lowercase all definitions (except for acronyms).
  • Don't use lowercase RFC words because we get ding'd for it when others review the spec and it's also been used as a DDoS on the WG in the 11th hour, so we shouldn't open that opportunity.

@msporny these should all be taken care of now.

Render Method.
</dd>

<dt><dfn>shim code</dfn></dt>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not for this PR, but it would be nice if this was more specifically named, like sandbox code (though, that's not right either). It's something that constrains the environment in which the template code runs and provides constrained communication channels into and out of the sandbox.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shell Code? or Secure Shell Code?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not for this PR, but it would be nice if this was more specifically named, like sandbox code (though, that's not right either). It's something that constrains the environment in which the template code runs and provides constrained communication channels into and out of the sandbox.

Yeah, "sandbox code" would encompass a bit more (it would include the template too), but it's not too far off. Maybe we need another layer in the description. We can first talk about the components in one layer:

  1. The host page
  2. The sandbox code

And then break the "sandbox code" into two parts in another layer. The sandbox code is a combination of:

  1. the template code, and
  2. a wrapper around the template code that "constraints the environment in which the template code runs and provides a constrained communication channel with the host page".

We should probably move this to a separate issue.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per https://en.wikipedia.org/wiki/Shim_(computing) shim code means

intercepts API calls and changes the arguments passed, handles the operation itself or redirects the operation elsewhere.

and that really does not fit what we have here. To consider a lesser evil, "sandbox code" sounds better...

@iherman
Copy link
Member

iherman commented Feb 10, 2026

I wouldn't do my job if I did not raise a red flag to the normative reference to CSP3, which is a Working Draft. The relevant WG's charter runs out at the end of April, no one knows how the rechartering will go (it is a charter with a very large number of deliverables in a sensitive area).

Per the changes documented in CSP3:

  1. The child-src model has been substantially altered:

    1. The frame-src directive, which was deprecated in CSP Level 2, has been undeprecated,

meaning that referring to CSP2 is also questionnable. In other words, we could not consider this feature as "stable" at this point, meaning that a normative reference may not be acceptable.

My question is whether we can get away with saying in our spec that "host page MUST use srcdoc instead of src" and leave it at that normatively. A note may be added to the spec that the host page may use CSP3 to implement this. After all, the whole structure of the host page abide to a bunch of structural rules, one more may not change the picture too much.

cc-ing @simoneonofri who is the staff contact to that WG. He may know more what happens there.

@simoneonofri
Copy link

WebAppSec WG is planning to recharter.

There are discussions about treating CSP in perpetual CR mode.

cc'ing the editors @mikewest and @antosart (and Mike is also the co-chair of the WG) if clarifications are needed

@iherman
Copy link
Member

iherman commented Feb 10, 2026

Something Dave and I discussed on the call, but it is better to get it on records: a reference to the selectJsonLd function defined in the ECDSA Cryptosuite spec, though technically correct, looks strange. That function was defined in a very specific context (selective disclosure via ECDSA) and it is not immediately clear to a reader that it can be used outside this context. I believe if we go down that route, a modification to the ECDSA may be in order, "factoring out" those helper functions that may be usable for other purposes. Whether they would remain part of the ECDSA spec or put it as a (normative) appendix to, say, into the DI spec is an additional question.

@iherman
Copy link
Member

iherman commented Feb 10, 2026

WebAppSec WG is planning to recharter.

There are discussions about treating CSP in perpetual CR mode.

cc'ing the editors @mikewest and @antosart (and Mike is also the co-chair of the WG) if clarifications are needed

Perpetual CR mode is fine for us but, at this moment, it is only a WD...

Comment on lines +906 to +908
<li>
Let `shimCode` be an HTML Document with `<meta http-equiv="Content-Security-Policy"
content="default-src data: 'unsafe-inline'">` in the `<head>`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<li>
Let `shimCode` be an HTML Document with `<meta http-equiv="Content-Security-Policy"
content="default-src data: 'unsafe-inline'">` in the `<head>`.
<li>
Let `shimCode` be an HTML Document with <code>&lt;meta http-equiv="Content-Security-Policy"
content="default-src data: 'unsafe-inline'"></code> in the <code>&lt;head></code>.

Using the "`" trick in respec did not seem to work, and the whole content got swallowed in the final HTML. I presume it conflicted with the tags.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the failure of the backtick wrappers is due to the line break before content=. In any case, I strongly suggest logging an issue against ReSpec, as this must be impacting other people as well.

The gotcha I'm accustomed to (which I have treated as by design) is that ` can't be used around tags you want to be interpreted within a <code> block (like <b> or <em>), so you have to use <code>, like <code>foo bar <b>blat thud</b> zoom</code> instead of `foo bar <b>blat thud</b> zoom`...

<p>
The [=host page=] MUST create the [=shim code=] by embedding the filtered
[=verifiable credential=] and the HTML template into the [=shim code=] template
defined above.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[=verifiable credential=] and the HTML template into the [=shim code=] template
defined above.

I presume that "defined above" means §2.2.4.3, but (a) put in a link is better (b) I am not sure it is a good reference for an algorithm. It sounds too generic for my taste. Isn't it better to refer §2.2.4.5.2?

in stringified JSON format.
</li>
<li>
Insert `datablock` into the `<head>` of `shimCode`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Insert `datablock` into the `<head>` of `shimCode`.
Insert `datablock` into the <code>&lt;head></code> of `shimCode`.

The HTML [=template code=] referenced by the `template` property in the
`renderMethod` MUST be an HTML fragment that contains the HTML, CSS,
and JavaScript necessary to render the [=verifiable credential=]. The
[=template code=] MUST NOT include any `<html>`, `<head>`, or `<body>` tags
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[=template code=] MUST NOT include any `<html>`, `<head>`, or `<body>` tags
[=template code=] MUST NOT include any <code>&lt;html></code>, <code>&lt;head></code>, or <code>&lt;body></code> tags

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my comment below; it seems that respec cannot handle the combination of "`" and a tag.

@msporny
Copy link
Member

msporny commented Feb 10, 2026

WebAppSec WG is planning to recharter.
There are discussions about treating CSP in perpetual CR mode.
Perpetual CR mode is fine for us but, at this moment, it is only a WD...

Yes, well, what are we going to do when we want to go to REC? CSP being in "perpetual CR" creates a problem for us there and I'd like for us to have a good understanding of the plan to get to REC. None of that is for this PR (the current PR is fine), but just want to make sure we don't lose track of this.

@iherman
Copy link
Member

iherman commented Feb 11, 2026

WebAppSec WG is planning to recharter.
There are discussions about treating CSP in perpetual CR mode.
Perpetual CR mode is fine for us but, at this moment, it is only a WD...

Yes, well, what are we going to do when we want to go to REC? CSP being in "perpetual CR" creates a problem for us there and I'd like for us to have a good understanding of the plan to get to REC. None of that is for this PR (the current PR is fine),

Well, we might consider a slight formulation change which puts the reasons for using CSP as a MUST requirements into the text and refers to CSP as a means to implement it. At this moment, the text requires CSP with a slightly vague explanation on the side later in the text. Such a change is part of this PR imho.

but just want to make sure we don't lose track of this.

If CSP becomes perpetual CR a.k.a. "Living Standard" then I am almost sure we will have a green light to refer to it as long as the functionality we refer to is stable. But we are not yet there

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants