W3C
First
Public
Working
Draft
09
Copyright © 2026 World Wide Web Consortium . W3C ® liability , trademark and permissive document license rules apply.
This specification describes an extension mechanism for the Verifiable Credential Data Model, that can be used to represent a Verifiable Credential through a visual, auditory, or haptic medium. It covers rendering a Verifiable Credential to a physical document, digital image, screen reader, or braille output.
This section describes the status of this document at the time of its publication. A list of current W3C publications and the latest revision of this technical report can be found in the W3C standards and drafts index .
This is an experimental specification and is undergoing regular revisions. It is not fit for production deployment.
This document was published by the Verifiable Credentials Working Group as a First Public Working Draft using the Recommendation track .
Publication as a First Public Working Draft does not imply endorsement by W3C and its Members.
This is a draft document and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to cite this document as other than a work in progress.
This document was produced by a group operating under the W3C Patent Policy . W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent that the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy .
This document is governed by the 18 August 2025 W3C Process Document .
Rendering methods can be used when the issuer has a specific way that they want to express a verifiable credential to an observer through a visual, auditory, or haptic mechanism. For example, an issuer of an employee badge credential might want to include rich imagery of their corporate logo and specific placement of employee information in specific areas of the badge. They might also want to provide an audio read out of the important aspects of the badge for individuals that have accessibility needs related to their eyesight.
The following terms are used to describe concepts in this specification.
Our definition of credential differs from, NIST's definitions of credential .
did:example:123456abcdef
.
verifiableCredential
.
These
properties
result
in
separate
graphs
that
contain
all
claims
defined
in
the
corresponding
JSON
objects.
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The
key
words
MAY
,
MUST
,
MUST
NOT
,
OPTIONAL
,
RECOMMENDED
,
and
REQUIRED
,
and
SHOULD
in
this
document
are
to
be
interpreted
as
described
in
BCP
14
[
RFC2119
]
[
RFC8174
]
when,
and
only
when,
they
appear
in
all
capitals,
as
shown
here.
A
conforming
render
method
is
any
concrete
expression
of
the
data
model
that
complies
with
the
normative
statements
in
this
specification.
Specifically,
all
relevant
normative
statements
in
Sections
2.
Data
Model
and
3.
2.2.4.5
Algorithms
of
this
document
MUST
be
enforced.
A conforming processor is any algorithm realized as software and/or hardware that generates or consumes a conforming render method . Conforming processors MUST produce errors when non-conforming documents are consumed.
This
document
also
contains
examples
that
contain
JSON
and
JSON-LD
content.
Some
of
these
examples
contain
characters
that
are
invalid
JSON,
such
as
inline
comments
(
//
)
and
the
use
of
ellipsis
(
...
)
to
denote
information
that
adds
little
value
to
the
example.
Implementers
are
cautioned
to
remove
this
content
if
they
desire
to
use
the
information
as
valid
JSON
or
JSON-LD.
The following sections outline the data model that is used by this specification for rendering methods
The
renderMethod
property
is
a
reserved
extension
point
in
the
Verifiable
Credentials
Data
Model
specification
[
VC-DATA-MODEL-2.0
].
An
issuer
can
utilize
this
property
in
a
verifiable
credential
to
express
one
or
more
preferred
render
methods.
renderMethod
property
MUST
specify
one
or
more
rendering
methods
that
can
be
used
by
software
to
express
the
verifiable
credential
using
a
visual,
auditory,
or
haptic
mechanism.
Each
renderMethod
value
MUST
specify
its
type
,
for
example,
TemplateRenderMethod
.
The
precise
contents
of
each
rendering
hint
is
determined
by
the
specific
renderMethod
type
definition.
When
an
issuer
desires
to
specify
template-based
rendering
instructions
for
a
verifiable
credential
,
they
MAY
add
a
renderMethod
property
that
uses
the
data
model
described
below.
| Property | Description | ||||||||
|---|---|---|---|---|---|---|---|---|---|
| id | An OPTIONAL string that follows the URL Standard and, when fetched, dereferences to a render template. | ||||||||
| type |
A
REQUIRED
string
that
MUST
be
the
value
TemplateRenderMethod
.
|
||||||||
| renderSuite | A REQUIRED string that identifies the algorithms that are used for generating the concrete rendering. | ||||||||
| name | An OPTIONAL human-readable string that can be displayed to provide a hint to the type of rendering that will be performed. This property might be used in a graphical interface that enables an individual to select between multiple presentation modes. | ||||||||
| description |
An
OPTIONAL
human-readable
string
that
provides
a
more
involved
description
than
name
of
when
the
particular
rendering
might
be
useful.
|
||||||||
| renderProperty |
An
OPTIONAL
list
of
string
values
that
each
conform
to
the
JavaScript
Object
Notation
(JSON)
Pointer
syntax
that
specifies
which
properties
from
the
verifiable
credential
are
exposed
when
using
this
specific
render
method.
If
renderProperty
is
not
provided,
the
entire
verifiable
credential
is
presumed
to
be
shared
when
the
render
method
is
used.
|
||||||||
| template |
An
OPTIONAL
string
or
map
that
provides
the
template
that
will
be
used
to
perform
the
rendering.
If
the
value
is
a
string
,
it
MUST
be
a
URL.
If
the
value
is
a
map
,
it
MUST
conform
to
the
following
rules:
|
||||||||
| digestMultibase |
An
OPTIONAL
multibase-encoded
Multihash
of
the
render
method
referenced
if
id
is
specified.
The
multibase
value
MUST
be
u
(base64url-nopad)
and
the
multihash
value
MUST
be
SHA-2
with
256-bits
of
output
(
0x12
).
|
The data model shown above is expressed in a verifiable credential in the example below.
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://www.w3.org/ns/credentials/examples/v2",
"https://w3id.org/vc/render-method/v1"
],
"id": "http://example.edu/credentials/3732",
"type": ["VerifiableCredential", "UniversityDegreeCredential"],
"issuer": "https://example.edu/issuers/14",
"validFrom": "2010-01-01T19:23:24Z",
"credentialSubject": {
"id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
"degree": {
"type": "BachelorDegree",
"name": "Bachelor of Science and Arts"
}
},
"renderMethod": {
"type": "TemplateRenderMethod",
"renderSuite": "svg-mustache",
"template": {
"id": "https://example.edu/credential-templates/BachelorDegree",
"mediaType": "image/svg+xml",
"digestMultibase": "zQmerWC85Wg6wFl9znFCwYxApG270iEu5h6JqWAPdhyxz2dR",
"renderProperty": [
"/issuer", "/validFrom", "/credentialSubject/degree/name"
]
}
}
}
In
the
example
above,
the
issuer
has
provided
a
Mustache-based
SVG
rendering
template
for
a
Bachelor's
degree
that
will
be
filled
in
with
specific
information
from
the
verifiable
credential
listed
in
renderProperty
.
The
svg-mustache
render
suite
uses
the
Mustache
templating
language
to
modify
an
SVG
file,
which
is
then
used
to
render
a
visual
representation
of
the
verifiable
credential
.
In the example below, a fully embedded SVG file is used as the rendering template.
{
...
"renderMethod": {
"type": "TemplateRenderMethod",
"renderSuite": "svg-mustache",
// the SVG file is embedded in the VC
"template": "data:image/svg+xml;base64,Qjei89...3jZpW"
}
}
The
next
example
links
to
the
SVG
file
on
the
Web
and
secures
it
against
modification
by
using
the
digestMultibase
property.
{
...
"renderMethod": {
"type": "TemplateRenderMethod",
"renderSuite": "svg-mustache",
"template": {
// this SVG file is fetched from the Web
"id": "https://degree.example/credential-templates/bachelors",
"mediaType": "image/svg+xml",
"digestMultibase": "zQmerWC85Wg6wFl9znFCwYxApG270iEu5h6JqWAPdhyxz2dR"
}
}
The
next
example
links
to
the
rendering
template
on
the
Web
and
secures
it
using
the
digestMultibase
property:
{
...
"renderMethod": {
// this render method is fetched from the Web
"id": "https://degrees.example/bachelors-svg.jsonld",
"mediaType": "application/ld+json",
"type": "TemplateRenderMethod",
"renderSuite": "svg-mustache",
"digestMultibase": "zQmG270iEu5h6JqWAPdhyxz2dRerWC85Wg6wFl9znFCwYxAp"
}
The
pdf-mustache
render
suite
uses
the
Mustache
templating
language
to
modify
a
PDF
file,
which
is
then
used
to
render
a
visual
representation
of
the
verifiable
credential
.
In the example below, a fully embedded PDF file is used as the rendering template.
{
...
"renderMethod": {
"type": "TemplateRenderMethod",
"renderSuite": "pdf-mustache",
// this PDF file is embedded in the VC
"template": "data:application/pdf;base64,k309SK...pwK83b"
}
}
The
next
example
links
to
the
PDF
file
on
the
Web
and
secures
it
against
modification
by
using
the
digestMultibase
property.
{
...
"renderMethod": {
"type": "TemplateRenderMethod",
"renderSuite": "pdf-mustache",
"template": {
// this PDF file is fetched from the Web
"id": "https://degree.example/bachelors.pdf",
"mediaType": "application/pdf",
"digestMultibase": "zQmznFCwYxApG270iEu5h6JqWAPdhyxz2dRerWC85Wg6wFl9"
}
}
The
next
example
links
to
the
rendering
template
on
the
Web
and
secures
it
using
the
digestMultibase
property:
{
...
"renderMethod": {
// this render method is fetched from the Web
"id": "https://degrees.example/bachelors-pdf.jsonld",
"type": "TemplateRenderMethod",
"renderSuite": "pdf-mustache",
"digestMultibase": "zQmEu5h6JqWAPdhyxmz2dRerWC85Wg6wFl9znFCwYxApG270"
}
The
nfc
render
suite
transmits
a
binary
payload
representing
the
verifiable
credential
over
a
wireless
NFC
connection.
In the example below, a fully embedded NFC payload is used as the rendering template, which only discloses the barcode identifier associated with the credential.
{
...
"renderMethod": {
"type": "TemplateRenderMethod",
"renderSuite": "nfc",
"name": "Tap to send",
// the NFC payload is embedded
"template": "data:application/octet-stream;base64,2QZkpQGDG...G8XJWnROcY4Biw",
// only the barcode is transmitted over NFC
"renderProperty": ["/credentialSubject/barcode"]
}
}
The
html
render
suite
allows
template
authors
to
provide
an
HTML
template
which
may
contain
JavaScript
to
render
a
Verifiable
Credential
.
The
HTML
may
be
provided
via
either
a
template
property
or
an
id
property
that
dereferences
to
HTML.
JavaScript
within
the
HTML
fragment
is
responsible
for
rendering
the
filtered
Verifiable
Credential
data
provided
via
an
HTML
data
block
(i.e.
`
Referenced in:
Referenced in:
{ "@context": [ "https://www.w3.org/ns/credentials/v2", "https://www.w3.org/ns/credentials/examples/v2" ], "type": [ "VerifiableCredential", "NameCredential" ], "issuer": { "id": "did:example:1234", "name": "The Issuer" }, "credentialSubject": { "name": "Example Name", "notRendered": "should not appear" }, "renderMethod": { "type": "TemplateRenderMethod", "renderEngine": "html", "renderProperty": [ "/issuer/name", "/credentialSubject/name" ], "template": { "id": "https://test.example/credential-templates/NameCredential.html", "mediaType": "text/html", "digestMultibase": "zQmerWC85Wg6wFl9znFCwYxApG270iEu5h6JqWAPdhyxz2dR" }, "outputPreference": { "mode": [ "visual", "audio" ], "mediaType": "application/html", "style": { "width": "800px", "height": "800px" } } }
}
Implementations MUST provide an environment that allows for JavaScript to safely render the HTML template using the filtered Verifiable Credential data. At minimum, this environment MUST prevent navigation, loading of external content, and access to the host page.
Browser
based
implementations,
for
example,
can
provide
such
an
environment
using
a
combination
of
Content
Security
Policy
[
CSP3
]
restrictions
on
a
Host
Page,
sandboxing
of
an
iframe
hosting
the
HTML
template,
and
shim
code
that
wraps
the
HTML
template
to
add
additional
CSP
restrictions
and
provides
ready
and
error
event
communication
with
the
Host
Page.
The Host Page (typically a Wallet or VC Renderer) MUST prevent the HTML template from navigating the top-level browsing context, accessing external content, accessing the host page, and loading any remote content.
The following MUST be set on the Host Page:
frame-src
'none'
forces
the
use
of
srcdoc
instead
of
src
for
iframes,
preventing
loading
the
HTML
template
via
the
browser
forcing
the
Host
Page
to
preload
and
check
the
digestMultibase
value
for
the
template
prior
to
using
it.
sandbox="allow-scripts
allow-modals"
MUST
be
set
on
the
iframe
hosting
the
HTML
template
to
prevent
navigation
and
top-level
access.
<html> <head> <meta http-equiv="content-security-policy" content="frame-src 'none'"> </head> <body> <iframe id="renderer" sandbox="allow-scripts allow-modals" srcdoc=""></iframe> </body>
</
html
>
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
``,
``,
or
``
tags
as
these
will
be
provided
by
the
Shim
Code.
<div> <script> console.log('running template render script'); // display credential as JSON as an example renderer; anything // could be done here instead, including mustache/other-style // template processing to generate the HTML for display // FIXME: determine best name/location for the datablock/script tag const credential = JSON.parse(document.querySelector( 'head > script[name="credential"]').innerHTML); document.querySelector('#credentialSubject-name').innerText =
credential.credentialSubject.name;
document.querySelector('#issuer-name').innerText =
credential.issuer.name;
// TBD: signal to host that rendering is complete window.renderMethodReady() </script> <style> h1 { color: blue;
}
</style> <h1 id="credentialSubject-name"></h1> <p>Issued by: <span id="issuer-name"></span></p>
</
div
>
The
template
HTML
fragment
MUST
be
wrapped
in
shim
code
that
provides
the
data
block
containing
the
partial
Verifiable
Credential
and
adds
an
additional
CSP
policies
to
prevent
navigation
and
external
content
loading.
Specifically,
the
shim
code
MUST
add
the
following
CSP
restrictions
of
default-src
'none'
data:
'unsafe-inline'
to
prevent
any
network
requests
from
being
made
by
the
template
code.
<html> <head> <meta http-equiv="content-security-policy" content="default-src 'none' data: 'unsafe-inline'"> <script name="credential" type="application/vc">${JSON.stringify(credential)}</script> </head> <body>${template}</body>
</
html
>
To
complete
the
setup,
the
Host
Page
MUST
inject
the
shim
code
(once
populated
with
the
credential
and
the
template)
into
the
iframe's
srcdoc
attribute
which
will
run
any
JavaScript
contained
in
the
shim
code
and
template.
<html> <head> <meta http-equiv="content-security-policy" content="default-src 'none' data: 'unsafe-inline'"><!-- The credential data block injected into the Shim Code. --><script name="credential" type="application/vc">{ "@context": [ "https://www.w3.org/ns/credentials/v2", "https://www.w3.org/ns/credentials/examples/v2"
],
"type": [ "VerifiableCredential", "NameCredential"
],
"issuer": { "id": "did:example:1234", "name": "The Issuer"
},
"credentialSubject": { "name": "Example Name"
}
}</script>
<!-- End credential data block --></head><body><!-- The template HTML injected into the Shim Code. --><div> <script> console.log('running template render script'); // display credential as JSON as an example renderer; anything // could be done here instead, including mustache/other-style // template processing to generate the HTML for display // FIXME: determine best name/location for the datablock/script tag const credential = JSON.parse(document.querySelector( 'head > script[name="credential"]').innerHTML); document.querySelector('#credentialSubject-name').innerText =
credential.credentialSubject.name;
document.querySelector('#issuer-name').innerText =
credential.issuer.name;
// TBD: signal to host that rendering is complete window.renderMethodReady() </script> <style> h1 { color: blue;
}
</style> <h1 id="credentialSubject-name"></h1> <p>Issued by: <span id="issuer-name"></span></p></div><!-- End template HTML --> </body>
</
html
>
The
iframe
created
in
the
Shim
Code
MUST
provide
a
communication
channel
to
allow
the
template
to
notify
the
Host
Page
when
rendering
is
complete
or
if
there
was
an
error
during
rendering.
This
can
be
accomplished
using
the
postMessage
API
with
a
MessageChannel
setup
by
the
Shim
Code.
The
JavaScript
shown
below
would
be
added
to
the
above
Host
Page
to
add
an
onload
event
to
the
iframe
which
sets
up
the
MessageChannel
.
The
Host
Page
also
creates
a
Promise
that
resolves
when
a
ready
message
is
received
from
the
Shim
Code
or
rejects
when
an
error
message
is
received.
The
Shim
Code
also
provides
a
window.renderMethodReady
method
for
use
by
the
template
to
notify
the
Host
Page
that
rendering
is
complete
or
send
back
an
error
message.
// a promise that resolves when the rendering is ready (or rejects if it// fails); can be used to show the display or an error insteadlet resolveRender;let rejectRender;const readyPromise = new Promise((resolve, reject) => {
resolveRender = resolve;
rejectRender = reject;
});
// Setup communication channel for use by the template code in the iframe
renderer.onload = () => {
// create a MessageChannel; transfer one port to the iframe const channel = new MessageChannel(); // start message queue so messages won't be lost while iframe loads
channel.port1.start();
// handle `ready` message
channel.port1.onmessage = function ready(event) {
if(event.data === 'ready') { // unhide the iframe because it's ready resolveRender();
} else {
rejectRender(new Error(event.data?.error?.message));
}
channel.port1.onmessage = undefined;
};
// send "start" message; send `port2` to iframe for return communication
renderer.contentWindow.postMessage('start', '*', [channel.port2]);
};
// setup event responses to ready or error// NOTE: this section is idiosyncratic to the Wallet/Renderer's UX needs
readyPromise.then(() => {
console.log('rendering ready'); const renderer = document.getElementById('renderer');
renderer.hidden = false;
}).catch(err => {
const errorMessage = document.getElementById('error-message');
errorMessage.style.display = 'block';
errorMessage.innerText = 'Rendering failed: ' + err.message;
console.error('rendering failed', err);
});
// add promise that will resolve to the communication port from// the parent windowconst portPromise = new Promise(resolve => { window.addEventListener('message', function start(event) { if(event.data === 'start' && event.ports?.[0]) { window.removeEventListener('message', start); resolve(event.ports[0]);
}
});
});
// attach a function to the window for the template to call when// it's "ready" (or that an error occurred) that will send a message// to the parent so the parent can decide whether to show the iframewindow.renderMethodReady = function(err) {
portPromise.then(port => port.postMessage(
!err ? 'ready' : {error: {message: err.message}}));
};
With
this
setup,
the
template
JavaScript
can
call
window.renderMethodReady()
to
notify
the
Host
Page
that
rendering
is
complete
or
call
window.renderMethodReady(new
Error("error
message"))
to
notify
the
Host
Page
of
an
error.
The
following
sections
outline
the
algorithms
that
are
used
by
the
html
render
suite
to
safely
render
the
HTML
template.
The
Host
Page
MUST
create
an
iframe
element
to
host
the
HTML
template.
The
Host
Page
MUST
set
the
sandbox
attribute
on
the
iframe
to
allow-scripts
allow-modals
to
prevent
navigation
and
top-level
access.
vc
be
the
verifiable
credential
to
be
rendered.
renderMethod
be
the
chosen
renderMethod
property
in
vc
where
renderMethod.type
is
TemplateRenderMethod
and
renderMethod.renderSuite
is
html
.
renderMethod.template
is
a
string
,
then
let
templete
be
the
value
of
renderMethod.template
.
renderMethod.template
is
a
map
,
then
let
template
be
the
result
of
fetching
the
URL
in
renderMethod.template.id
.
The
Host
Page
MUST
filter
the
verifiable
credential
vc
to
only
include
the
properties
specified
in
renderMethod.renderProperty
,
if
it
is
present.
If
renderMethod.renderProperty
is
not
present,
the
entire
verifiable
credential
is
used.
This
filtering
MUST
be
done
by
applying
the
selectJsonLd
algorithm
defined
in
Section
3.4.13
selectJsonLd
of
the
Data
Integrity
ECDSA
Cryptosuites
v1.0
specification
[
VC-DI-ECDSA
]
to
the
JSON
Pointer
[
RFC6901
]
values
present
in
renderMethod.renderProperty
.
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.
shimCode
be
an
HTML
Document
with
`
`
in
the
``.
datablock
be
an
HTML
Data
Block
with
a
type
of
application/vc
.
datablock
to
be
the
filtered
verifiable
credential
in
stringified
JSON
format.
datablock
into
the
`
of
shimCode`.
template
into
the
`
of
shimCode`.
The
Host
Page
MUST
set
the
srcdoc
attribute
of
the
iframe
to
the
resulting
Shim
Code.
srcdoc
attribute
of
the
iframe
to
the
stringified
HTML
of
shimCode
.
The
Host
Page
MUST
setup
a
communication
channel
with
the
Shim
Code
to
receive
ready
and
error
messages
as
described
above.
renderPromise
be
a
new
Promise
that...
resolve
,
may
be
used
to
display
the
iframe
to
the
user.
reject
,
display
the
error
message
to
the
user.
onload
event
of
the
iframe
...
channel
be
a
new
MessageChannel
.
port1
listener
on
channel
that
listens
for
a
ready
message
from
the
code
in
template
now
injected
into
the
iframe
via
shimCode
.
port1
listener,
if
a
ready
message
is
received,
resolve
renderPromise
.
If
an
error
message
is
received,
reject
renderPromise
with
the
error
message.
postMessage
to
send
port2
of
channel
to
the
iframe
content
window.
The
Host
Page
SHOULD
use
the
renderPromise
to
determine
when
rendering
is
complete
or
if
there
was
an
error
during
rendering.
The
Shim
Code
MUST
setup
to
receive
communication
from
the
Host
Page
via
the
MessageChannel
and
provide
the
window.renderMethodReady
method
for
use
by
the
template
code.
window.onload
event...
port
be
the
MessagePort
received
from
the
Host
Page
via
the
message
event.
window.renderMethodReady
function
that...
ready
message
to
the
Host
Page
via
port
.
Error
argument,
sends
an
error
message
to
the
Host
Page
via
port
with
the
error
message.
OpenAttestationEmbeddedRenderer
is
used
by
an
issuer
to
render
a
verifiable
credential.
The
verifiable
credential
is
rendered
in
HTML
within
an
embedded
<iframe>
through
a
Template
Renderer
website
referenced
in
the
document.
This
arrangement
allows
for
interactive
selective
disclosure
using
OpenAttestationMerkleProofSignature2018.
The Template Renderer is a web application embedded in an iframe. It renders verifiable credentials based on selected templates and must listen for specific messages from the Host application to facilitate the rendering process.
There currently exists a number of OpenAttestationEmbeddedRenderer issuers and decentralized renderer implementations.
When
an
issuer
desires
to
specify
an
embedded
rendering
instructions
for
a
verifiable
credential
,
they
MAY
add
a
renderMethod
property
that
uses
the
data
model
described
below.
| Property | Description |
|---|---|
| id | A URL that locates a website that implements the OpenAttestationEmbeddedRenderer Action API. |
| type |
The
type
property
MUST
be
OpenAttestationEmbeddedRenderer
.
|
| renderName |
Name
of
the
template
used
by
the
website
specified
by
id
to
render
the
document.
A
different
template
can
be
used
for
the
decentralized
renderer
to
present
a
different
HTML
view
of
the
verifiable
credential.
|
The data model shown above is expressed in a verifiable credential in the example below.
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://schemata.openattestation.com/com/openattestation/4.0/alpha-context.json"
],
"type": ["VerifiableCredential", "OpenAttestationCredential"],
"validFrom": "2021-03-08T12:00:00+08:00",
"name": "Republic of Singapore Driving Licence",
"issuer": {
"id": "did:ethr:0xB26B4941941C51a4885E5B7D3A1B861E54405f90",
"type": "OpenAttestationIssuer",
"name": "Government Technology Agency of Singapore (GovTech)",
"identityProof": { "identityProofType": "DNS-DID", "identifier": "example.openattestation.com" }
},
"credentialSubject": {
"id": "urn:uuid:a013fb9d-bb03-4056-b696-05575eceaf42",
"type": ["DriversLicense"],
"name": "John Doe",
"address": "123 Choa Chu Kang Road, Singapore 123456",
"licenses": [
{
"class": "3",
"description": "Motor cars with unladen weight <= 3000kg",
"effectiveDate": "2013-05-16T00:00:00+08:00"
},
{
"class": "3A",
"description": "Motor cars with unladen weight <= 3000kg",
"effectiveDate": "2013-05-16T00:00:00+08:00"
}
]
},
"renderMethod": [{
"id": "https://demo-renderer.opencerts.io",
"type": "OpenAttestationEmbeddedRenderer",
"rendererName": "GOVTECH_DEMO"
}]
}
The
verifiable
credential
specifies
a
decentralized
renderer
at
https://demo-renderer.opencerts.io
,
using
the
template
named
GOVTECH_DEMO
.
The decentralized renderer can support different templates that can provide different views of the verifiable credentials. Below are two renderings of the same verifiable credential using different templates.
The
Host
is
the
application
that
displays
the
document
with
the
help
of
the
Template
Renderer.
The
Template
Renderer
MUST
be
a
web
application
embedded
within
an
iframe
specified
by
renderMethod
.
id
.
It
MUST
communicate
with
the
Host
application
using
postMessage
API
to
perform
actions.
All
actions
follow
the
same
structure.
They
are
composed
of
type
and
payload
:
type
indicates
the
kind
of
action
being
executed,
for
instance,
RENDER_DOCUMENT
means
rendering
a
document.
The
type
of
an
action
is
mandatory.
payload
indicates
optional
data
associated
to
the
type,
for
instance,
the
content
of
the
document
to
render.
An open source reference implementation is available on GitHub .
The interaction between the Host and the Template Renderer is illustrated in the following diagram.
When the iframe is first displayed, the host sends commands to the iframe to render the document. The 4 types of actions supported are described below.
| type | payload | action |
|---|---|---|
GET_TEMPLATES
|
|
Obtain a list of templates supported by the renderer for the given document. The list of templates is returned from UPDATE_TEMPLATES call from the iframe. |
SELECT_TEMPLATE
|
|
Select the template to be used for rendering. It should be from the list returned by GET_TEMPLATES. If not found, a default template is used. |
RENDER_DOCUMENT
|
|
Render the verifiable credential inside the IFRAME using the selected template. Document is JSON object form of the verifiable credential. |
PRINT
|
|
MUST show the print dialog so the contents of the IFRAME can be printed. |
These are used by the iframe to update the host to make adjustments on formatting, or selective redaction.
| type | payload | action |
|---|---|---|
OBFUSCATE
|
|
This is used for selective redaction. The Host is informed of the path of the field that has been obfuscated so that the host can create an updated version of the document with the selected field obfuscated. |
UPDATE_HEIGHT
|
|
Notify the Host of the height of the embedded iframe in pixels so the Host can adjust the size on the browser. |
UPDATE_TEMPLATES
|
|
Notify the Host of the list of template names that are usable from RENDER_METHOD, or GET_TEMPLATES calls. |
The following sections outline the algorithms that is used by this specification for rendering methods.
The
following
algorithm
is
used
to
transform
the
SVG
image
template
into
the
final
SVG
image
that
is
displayed.
The
inputs
to
the
algorithm
are
the
verifiable
credential
(
verifiableCredential
)
and
the
SVG
image
source
code
(
svgImage
).
The
output
is
a
SVG
image.
replacementMap
,
by
finding
all
strings
in
svgImage
that
start
with
{{
(double
open
braces)
and
end
with
}}
(double
close
braces).
For
each
string,
templateKey
,
that
is
found:
templateValue
,
by
evaluating
the
value
of
templateKey
(without
the
opening
or
closing
braces)
using
the
JSON
Pointer
[
RFC6901
]
algorithm
with
the
verifiableCredential
as
input
to
the
algorithm.
If
the
evaluation
is
null
,
set
templateValue
to
the
empty
string.
replacementMap
by
using
templateKey
and
associate
it
with
templateValue
.
replacementMap
,
replace
each
corresponding
string
in
svgImage
that
matches
the
key
with
the
associated
value
in
the
replacementMap
.
The list of security considerations listed below need to be converted into sections:
The list of privacy considerations listed below need to be converted into sections:
id
to
track
individuals.
These
values
should
be
aggressively
cached
client-side,
or
looked
up
using
a
mixnet
or
proxy
service.
The list of internationalization considerations listed below need to be converted into sections: