W3C Candidate Recommendation Draft
Copyright © 2024 World Wide Web Consortium . W3C ® liability , trademark and permissive document license rules apply.
This specification describes a privacy-preserving, space-efficient, and high-performance mechanism for publishing status information such as suspension or revocation of Verifiable Credentials through use of bitstrings.
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 technical reports index at https://www.w3.org/TR/.
The Working Group is actively seeking implementation feedback for this specification. In order to exit the Candidate Recommendation phase, the Working Group has set the requirement of at least two independent implementations for each mandatory or optional feature in the specification. For details on the conformance testing process, see the implementation report .
This document was published by the Verifiable Credentials Working Group as a Candidate Recommendation Draft using the Recommendation track .
Publication as a Candidate Recommendation does not imply endorsement by W3C and its Members. A Candidate Recommendation Draft integrates changes from the previous Candidate Recommendation that the Working Group intends to include in a subsequent Candidate Recommendation Snapshot.
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 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 which 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 03 November 2023 W3C Process Document .
This section is non-normative.
It is often useful for an issuer of verifiable credentials [ VC-DATA-MODEL-2.0 ] to link to a location where a verifier can check to see if a credential has been suspended or revoked. There are a variety of privacy and performance considerations that are made when designing, publishing, and processing status lists.
One such privacy consideration happens when there is a one-to-one mapping between a verifiable credential and a URL where the status is published. This type of mapping enables the website that publishes the URL to correlate the holder , time, and verifier when the status is checked. This could enable the issuer to discover the type of interaction the holder is having with the verifier , such as providing an age verification credential when entering a bar. Being tracked by the issuer of a driver's license when entering an establishment violates a privacy expectation that many people have today.
Similarly, there are performance considerations that are explored when designing status lists. One such consideration is where the list is published and the burden it places from a bandwidth and processing perspective, both on the server and the client fetching the information. In order to meet privacy expectations, it is useful to bundle the status of large sets of credentials into a single list to help with group privacy. However, doing so can place an impossible burden on both the server and client if the status information is as much as a few hundred bytes in size per credential across a population of hundreds of millions of holders .
The rest of this document proposes a highly compressible, bitstring-based status list mechanism with strong privacy-preserving characteristics, that is compatible with the architecture of the Web, is highly space-efficient, and lends itself well to content distribution networks. As an example of using this specification to achieve a number of beneficial privacy and performance goals, it is possible to create a status list that can be constructed for 100,000 verifiable credentials that is roughly 12,500 bytes in size in the worst case. In a case where a few hundred credentials have been revoked, the size of the list is less than a few hundred bytes while providing privacy in a group of 100,000 individuals.
This section is non-normative.
This
section
outlines
the
core
concept
utilized
by
the
status
list
mechanism
described
in
this
specification.
At
the
most
basic
level,
status
information
for
all
verifiable
credentials
issued
by
an
issuer
is
expressed
as
items
in
a
list.
Each
issuer
manages
a
list
of
all
verifiable
credentials
that
it
has
issued.
Each
verifiable
credential
is
associated
with
an
item
in
its
list.
When
a
single
bit
specifies
a
status,
such
as
"revoked"
or
"suspended",
then
that
status
is
expected
to
be
true
when
the
bit
is
set
(
1
)
and
false
when
unset
(
0
).
One of the benefits of using a bitstring is that it is a highly compressible data format since, in the average case, large numbers of credentials will remain unrevoked. This will ensure long sections of bits that are the same value and thus highly compressible using run-length compression techniques such as GZIP [ RFC1952 ]. The default status list size is 131,072 entries, equivalent to 16 KB of single bit values. When only a handful of verifiable credentials are revoked, GZIP compresses the bitstring to a few hundred bytes.
Another benefit of using a bitstring is that it enables large numbers of verifiable credential statuses to be placed in the same list. This specification uses a minimum list length of 131,072. This size ensures an adequate amount of group privacy in the average case. If better group privacy is required, the bitstring can be made larger.
The status information associated with a particular verifiable credential is about the verifiable credential itself and might not apply to any underlying or backing credential , such as an educational degree. For example, in the case of such an educational degree, it is possible for a verifiable credential to be revoked because the mechanism used to create its digital signature has been compromised, while the backing educational degree remains valid.
This section is non-normative.
Terminology used throughout this document is defined in the Terminology section of the Verifiable Credentials Data Model v2.0 specification.
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 , SHOULD , and SHOULD NOT 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 document is any concrete expression of the data model that follows the relevant normative requirements in Section 2. Data Model .
A conforming processor is any algorithm realized as software and/or hardware that generates and/or consumes a conforming document according to the relevant normative statements in Section 3. Algorithms . Conforming processors MAY choose to only support bitstring entry sizes of 1. Conforming processors MUST produce errors when non-conforming documents are consumed.
There are numerous ways to express status information associated with digital credentials. Some of these mechanisms include Certificate Revocation Lists (CRL) [ RFC5280 ], the Online Certificate Status Protocol (OCSP) [ RFC2560 ], Bloom Filters [ RFC8932 ], and cryptographic accumulators [ ALLOSAUR ]. This specification optimizes for a variety of requirements that are different from other mechanisms. These requirements include:
Technology | CRL | OCSP | Bloom | Accumulator | Bitstring |
---|---|---|---|---|---|
Provides tunable group privacy | ✓ | ✗ | ✓ | ✓ | ✓ |
Does not require signed assertion for each credential | ✓ | ✗ | ✓ | ✓ | ✓ |
Resistant to issuer tracking when fetched by verifier | ✓ | ✓ | ✓ | ✓ | ✓ |
Caching is space efficient with many revocations | ✗ | ✗ | ✓ | ✓ | ✓ |
Highly compressible (>90% average compression) | ✗ | ✗ | ✓ | ✓ | ✓ |
Updates are efficient (fast and entire population does not need to update) | ✓ | ✗ | ✓ | ✗ | ✓ |
Uses cryptographic primitives approved by IETF | ✓ | ✓ | ✓ | ✗ | ✓ |
No false positives | ✓ | ✓ | ✗ | ✓ | ✓ |
Can be delivered by holder (stapling) | ✗ | ✓ | ✗ | ✓ | ✓ |
Easily profiled for usage with verifiable credentials | ✗ | ✗ | ✗ | ✗ | ✓ |
When
an
issuer
desires
to
enable
status
information
for
a
verifiable
credential
,
they
MAY
add
a
credentialStatus
property
that
uses
the
data
model
described
in
this
section.
Any
expression
of
the
data
model
in
this
section
MUST
be
expressed
in
a
conforming
verifiable
credential
as
defined
in
[
VC-DATA-MODEL-2.0
].
The Working Group is currently seeking implementer feedback regarding the utility of bitstring entries that have sizes greater than one. Supporting such entries adds complexity to the solution, and it's not clear whether there is enough of an implementation community to support the feature. The WG is considering three options: (1) require conforming implementations to support the feature; (2) allow implementations to optionally support the feature; or (3) remove the feature. At present, the specification implements option (2).
Property | Description | ||||||||
---|---|---|---|---|---|---|---|---|---|
id |
An
optional
identifier
for
the
status
list
entry.
The
constraints
on
the
id
property
are
listed
in
the
Verifiable
Credentials
Data
Model
specification
[
VC-DATA-MODEL-2.0
].
If
present,
the
value
is
expected
to
be
a
URL
that
identifies
the
status
information
associated
with
the
verifiable
credential
.
It
MUST
NOT
be
the
URL
for
the
status
list.
The
value
is
not
used
during
the
verification
or
validation
process,
and
does
not
need
to
be
related
to
the
statusListCredential
value.
If
necessary,
the
value
can
be
used
to
uniquely
identify
the
BitstringStatusListEntry
object,
such
as
when
it
is
stored
in
a
database.
|
||||||||
type |
The
type
property
MUST
be
BitstringStatusListEntry
.
|
||||||||
statusPurpose |
The
purpose
of
the
status
entry
MUST
be
a
string.
While
the
value
of
the
string
is
arbitrary,
the
following
values
MUST
be
used
for
their
intended
purpose:
|
||||||||
statusListIndex |
The
statusListIndex
property
MUST
be
an
arbitrary
size
integer
greater
than
or
equal
to
0,
expressed
as
a
string
in
base
10.
The
value
identifies
the
position
of
the
status
of
the
verifiable
credential
.
Implementations
SHOULD
assign
indexes
randomly,
such
that
inferences
—
such
as
the
recency
of
the
assignment
or
the
size
of
the
group
—
cannot
be
easily
drawn
from
that
position.
|
||||||||
statusListCredential |
The
statusListCredential
property
MUST
be
a
URL
to
a
verifiable
credential
.
When
the
URL
is
dereferenced,
the
resulting
verifiable
credential
MUST
have
type
property
that
includes
the
BitstringStatusListCredential
value.
|
||||||||
statusSize |
The
statusSize
indicates
the
size
of
the
status
entry
in
bits.
statusSize
MAY
be
provided.
If
statusSize
is
not
present
as
a
property
of
the
credentialStatus
,
then
statusSize
MUST
be
processed
as
1
.
If
present,
statusSize
MUST
be
an
integer
greater
than
zero.
If
statusSize
is
provided
and
is
greater
than
1
,
then
the
property
credentialStatus.statusMessage
MUST
be
present,
and
the
number
of
status
messages
MUST
equal
the
number
of
possible
values.
|
||||||||
statusMessage |
If
present,
the
statusMessage
property
MUST
be
an
array,
the
length
of
which
MUST
equal
the
number
of
possible
status
messages
indicated
by
statusSize
(e.g.,
statusMessage
array
MUST
have
2
elements
if
statusSize
has
1
bit,
4
elements
if
statusSize
has
2
bits,
8
elements
if
statusSize
has
3
bits,
etc.).
statusMessage
MAY
be
present
if
statusSize
is
1
,
and
MUST
be
present
if
statusSize
is
greater
than
1
.
If
the
statusMessage
array
is
not
present,
the
message
values
associated
with
the
status
bit
values
of
1
and
0
are
"set"
and
"unset",
respectively.
If
the
statusMessage
array
is
present,
each
element
MUST
contain
the
two
properties
described
below,
and
MAY
contain
additional
properties.
statusMessage
array.
Implementers
MAY
use
the
string
value
of
undefined
in
the
value
to
indicate
that
a
corresponding
status
is
not
defined
for
the
associated
status
value,
but
that
it
may
be
defined
in
the
future.
Rules
for
how
to
handle
various
status
messages
are
outside
the
scope
of
normative
requirements
in
this
document,
but
it
is
assumed
that
implementers
will
document
rules
for
processing
various
status
codes.
|
||||||||
statusReference |
An
implementer
MAY
include
the
statusReference
property.
If
present,
its
value
MUST
be
a
URL
or
an
array
of
URLs
[
URL
]
which
dereference
to
material
related
to
the
status.
Implementers
using
a
statusPurpose
of
message
are
strongly
encouraged
to
provide
a
statusReference
.
Note
:
Details
around
reference
|
Status
list
entries
can
be
used
to
express
the
purpose
of
a
status
associated
with
a
verifiable
credential
by
using
the
statusPurpose
property.
The
use
of
revocation
or
suspension
as
the
status
purpose
includes
the
semantics
of
the
status,
with
revocation
indicating
that
a
status
bit
expresses
whether
a
verifiable
credential
has
been
revoked
and
suspension
indicating
that
a
status
bit
expresses
whether
a
verifiable
credential
has
been
suspended.
The
example
below
demonstrates
the
use
of
these
status
purposes:
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://www.w3.org/ns/credentials/examples/v2"
],
"id": "https://example.com/credentials/23894672394",
"type": ["VerifiableCredential", "EmployeeIdCredential"],
"issuer": "did:example:12345",
"validFrom": "2024-04-05T14:27:42Z",
"credentialStatus": [{
"id": "https://example.com/credentials/status/3#94567",
"type": "BitstringStatusListEntry",
"statusPurpose": "revocation",
"statusListIndex": "94567",
"statusListCredential": "https://example.com/credentials/status/3"
}, {
"id": "https://example.com/credentials/status/4#23452",
"type": "BitstringStatusListEntry",
"statusPurpose": "suspension",
"statusListIndex": "23452",
"statusListCredential": "https://example.com/credentials/status/4"
}],
"credentialSubject": {
"id": "did:example:6789",
"type": "Person",
"employeeId": "A-123456"
}
}
The
use
of
message
as
the
status
purpose
enables
an
issuer
to
define
an
arbitrary
number
of
custom,
descriptive
messages
about
the
status
of
the
verifiable
credential
.
The
issuer
commits
to
the
set
of
messages
that
may
be
associated
with
a
particular
entry
(i.e.,
with
a
particular
verifiable
credential
)
through
the
statusSize
,
statusMessage
,
and
optional
statusReference
properties,
at
the
time
of
verifiable
credential
issuance.
This
is
to
ensure
that
the
holder
knows
what
sort
of
information
might
be
associated
with
a
particular
verifiable
credential
they
keep
in
their
possession,
that
could
then
be
discoverable
by
a
verifier
that
later
receives
that
credential.
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://www.w3.org/ns/credentials/examples/v2"
],
"id": "https://example.com/credentials/2947478373",
"type": ["VerifiableCredential", "BillOfLadingExampleCredential"],
"issuer": "did:example:12345",
"validFrom": "2024-04-05T03:52:31Z",
"credentialStatus": {
"id": "https://example.com/credentials/status/8#492847",
"type": "BitstringStatusListEntry",
"statusPurpose": "message",
"statusListIndex": "492847",
"statusSize": 2,
"statusListCredential": "https://example.com/credentials/status/8",
"statusMessage": [
{"status":"0x0", "message":"pending_review"},
{"status":"0x1", "message":"accepted"},
{"status":"0x2", "message":"rejected"},
...
],
"statusReference": "https://example.org/status-dictionary/"
},
"credentialSubject": {
"id": "did:example:6789",
"type": "BillOfLading",
...
}
}
When a status list verifiable credential is published, it MUST be a conforming document, as defined in [ VC-DATA-MODEL-2.0 ], that expresses the data model in this section. The following section describes the format of the verifiable credential that encapsulates the status list.
The status list is expressed inside a verifiable credential in order to enable a holder to provide it directly to a verifier . This mechanism, sometimes called "certificate stapling", increases privacy for the holder by ensuring that the verifier does not need to contact the issuer to retrieve the status list. Still, a verifier might choose to ignore the holder -provided status list, even when its authenticity is verifiable, if it desires a more recent version of a status list, for instance.
Issuers
and
verifiers
are
advised
that
the
issuer
of
a
verifiable
credential
and
the
issuer
of
an
associated
BitstringStatusListCredential
might
not
be
the
same.
There
are
technical,
legal,
institutional,
political,
and
other
reasons
that
might
make
it
appropriate
to
separate
the
authority
over
the
original
credential
from
the
authority
to
revoke,
or
otherwise
change
the
status
of,
such
a
credential.
Therefore,
the
issuer
value
of
a
verifiable
credential
containing
a
BitstringStatusListEntry
MAY
be
different
from
the
issuer
value
of
a
BitstringStatusListCredential
.
The
Working
Group
is
considering
the
removal
of
the
ttl
("time
to
live")
feature
because
its
semantics
conflict
with
the
semantics
of
the
validUntil
feature
of
verifiable
credentials
.
When
a
verifier
performs
validation
and
evaluates
a
BitstringStatusListCredential
that
contains
both
a
ttl
property
and
a
validUntil
property,
each
with
a
different
value
(i.e.,
each
indicating
a
different
point
in
time
when
the
credential
is
to
"expire"),
it
is
not
clear
which
(if
either)
property
a
validator
can
be
expected
to
ignore.
In
other
words,
if
a
ttl
value
specifies
an
expiration
datetime
of
midnight
today,
but
the
validUntil
property
specifies
an
expiration
datetime
of
midnight
tomorrow,
then
what
is
a
verifier
expected
to
do?
Fundamentally,
ttl
and
validUntil
have
conflicting
semantics.
One
way
to
resolve
this
conflict
is
to
remove
ttl
and
specify
that
caching
behavior
can
be
expressed
using
protocol
mechanisms
(such
as
the
expires
header
in
HTTP),
and
that
any
caching
performed
MUST
align
with
the
validUntil
value
for
the
verifiable
credential
.
The
Working
Group
is
seeking
feedback
from
the
implementer
community
regarding
this
feature.
Property | Description | ||||||||
---|---|---|---|---|---|---|---|---|---|
id |
The
verifiable
credential
that
contains
the
status
list
MAY
express
an
id
property
that
matches
the
value
specified
in
statusListCredential
for
the
corresponding
BitstringStatusListEntry
(see
2.1
BitstringStatusListEntry
).
|
||||||||
type |
The
verifiable
credential
that
contains
the
status
list
MUST
express
a
type
property
that
includes
the
BitstringStatusListCredential
value.
|
||||||||
validFrom | The earliest point in time at which the status list is valid. This property is defined in the Verifiable Credentials Data Model specification in Section 4.6: Validity Period . | ||||||||
validUntil | The latest point in time at which the status list is valid. This property is defined in the Verifiable Credentials Data Model specification in Section 4.6: Validity Period . | ||||||||
credentialSubject.type |
The
type
of
the
credential
subject
,
which
is
the
status
list,
MUST
be
BitstringStatusList
.
|
||||||||
credentialSubject.statusPurpose |
The
value
of
the
purpose
property
of
the
status
entry,
statusPurpose
,
MUST
be
one
or
more
strings.
While
the
value
of
each
string
is
arbitrary,
the
following
values
MUST
be
used
for
their
intended
purpose:
|
||||||||
credentialSubject.encodedList |
The
encodedList
property
of
the
credential
subject
MUST
be
a
Multibase-encoded
base64url
(with
no
padding)
[
RFC4648
]
representation
of
the
GZIP-compressed
[
RFC1952
]
bitstring
values
for
the
associated
range
of
verifiable
credential
status
values.
The
uncompressed
bitstring
MUST
be
at
least
16KB
in
size.
The
bitstring
MUST
be
encoded
such
that
the
first
index,
with
a
value
of
zero
(
0
),
is
located
at
the
left-most
bit
in
the
bitstring
and
the
last
index,
with
a
value
of
one
less
than
the
length
of
the
bitstring
(
bitstring_length
-
1
),
is
located
at
the
right-most
bit
in
the
bitstring.
Further
information
on
bitstring
encoding
can
be
found
in
Section
6.1
Bitstring
Encoding
.
|
||||||||
credentialSubject.ttl |
The
ttl
indicates
the
"time
to
live"
in
milliseconds.
This
property
MAY
be
present.
If
not
present,
implementers
MUST
use
a
value
of
300000
for
this
property.
A
verifier
MUST
NOT
use
a
cached
BitstringStatusListCredential
that
was
cached
for
more
than
the
ttl
duration
prior
to
the
start
of
verification
operation
on
a
verifiable
credential
.
Implementations
that
publish
the
status
list
SHOULD
align
any
protocol-specific
caching
information,
such
as
the
HTTP
Cache-Control
header,
with
the
value
in
this
field.
|
The
example
below
demonstrates
how
the
BitstringStatusListEntry
is
used
with
a
BitstringStatusListCredential
to
provide
the
verifier
with
the
information
necessary
to
determine
the
status
of
a
particular
verifiable
credential
.
{ "@context": [ "https://www.w3.org/ns/credentials/v2" ], "id": "https://example.com/credentials/status/3", "type": ["VerifiableCredential", "BitstringStatusListCredential"], "issuer": "did:example:12345", "validFrom": "2021-04-05T14:27:40Z", "credentialSubject": { "id": "https://example.com/status/3#list", "type": "BitstringStatusList", "statusPurpose": "revocation", "encodedList": "uH4sIAAAAAAAAA-3BMQEAAADCoPVPbQwfoAAAAAAAAAAAAAAAAAAAAIC3AYbSVKsAQAAA" } }
The following section outlines the algorithms that are used to generate and validate status lists as described by this document.
If an implementation of any of the algorithms in this section processes a property defined in Section 2. Data Model whose value is malformed due to not complying with associated " MUST " statements, a MALFORMED_VALUE_ERROR MUST be raised.
The Working Group is seeking feedback related to implementer desire to align with the IETF OAuth Working Group Token Status List specification (formerly titled OAuth Status List , and JWT and CWT Status List ). If there is interest, and to the extent possible, this specification might align more closely with the Token Status List bitstring format, as it could be beneficial to have one code base able to process bitstring values from both lists. If there is implementer support for such changes, they might be made during the Candidate Recommendation phase.
The following process, or one generating the exact output, MUST be followed when producing a BitstringStatusListCredential . The algorithm takes a list of issued credentials as input and either throws an error or returns a status list credential as output.
encodedList
property
set.
encodedList
to
compressed
bitstring
.
Issuers SHOULD publish status list credentials in a way that can be cached and that does not track who retrieves the status list credential, such as through Oblivious HTTP , a content distribution network that is not operated by the issuer , or business processes for which the access logs are not accessible by data analysts or systems administrators.
The following process, or one generating the exact output, MUST be followed when validating a verifiable credential that is contained in a BitstringStatusListCredential . The algorithm takes a status list verifiable credential as input and either throws an error or returns a status list credential as output.
credentialStatus
entry
that
is
a
BitstringStatusListEntry
.
statusPurpose
in
the
credentialStatus
entry
in
the
credentialToValidate
.
statusListCredential
URL,
and
ensure
that
all
proofs
verify
successfully.
If
the
dereference
fails,
raise
a
STATUS_RETRIEVAL_ERROR
.
If
any
of
the
proof
verifications
fail,
raise
a
STATUS_VERIFICATION_ERROR
.
statusPurpose
value
in
the
statusListCredential
.
Note:
The
statusListCredential
might
contain
multiple
status
purposes
in
a
single
list.
If
the
values
are
not
equal,
raise
a
STATUS_VERIFICATION_ERROR
.
encodedList
property
of
the
BitstringStatusListCredential
.
statusListIndex
property
of
the
BitstringStatusListEntry
.
statusSize
is
less
than
minimumNumberOfEntries
,
raise
a
STATUS_LIST_LENGTH_ERROR
.
status
key
in
result
to
status
,
and
set
the
purpose
key
in
result
to
the
value
of
statusPurpose
.
0
,
set
the
valid
key
in
result
to
true
;
otherwise,
set
it
to
false
.
statusPurpose
is
message
,
set
the
message
key
in
result
to
the
corresponding
message
of
the
value
as
indicated
in
the
statusMessages
array.
When
a
statusListCredential
URL
is
dereferenced,
server
implementations
MAY
provide
a
mechanism
to
dereference
the
status
list
as
of
a
particular
point
in
time.
When
an
issuer
provides
such
a
mechanism,
it
enables
a
verifier
to
determine
changes
in
status
to
a
precision
chosen
by
the
issuer,
such
as
hourly,
daily,
or
weekly.
If
such
a
feature
is
supported,
and
if
query
parameters
are
supported
by
the
URL
scheme,
then
the
name
of
the
query
parameter
MUST
be
timestamp
and
the
value
MUST
be
a
valid
URL-encoded
[
XMLSCHEMA11-2
]
dateTimeStamp
string
value.
The
result
of
dereferencing
such
a
timestamp-parameterized
URL
MUST
be
either
a
status
list
credential
containing
the
status
list
as
it
existed
at
the
given
point
in
time,
or
a
STATUS_RETRIEVAL_ERROR
.
If
the
result
is
an
error,
implementations
MAY
attempt
the
retrieval
again
with
a
different
timestamp
value,
or
without
a
timestamp
value,
as
long
as
the
verifier
's
validation
rules
permit
such
an
action.
Verifiers SHOULD cache the retrieved status list and SHOULD use proxies or other mechanisms, such as Oblivious HTTP , that hide retrieval behavior from the issuer .
It is expected that a verifier will ensure that it trusts the issuer of a verifiable credential , as well as the issuer of the associated BitstringStatusListCredential , before using the information contained in either credential for further decision making purposes. Implementers are advised that the issuers of these credential might differ, such as when the original issuer of the verifiable credential does not maintain a record of its validity.
The following process, or one generating the exact output, MUST be followed when generating a status list bitstring. The algorithm takes an issuedCredentials list as input and either throws an error or returns a compressed bitstring as output.
bitstring
,
if
there
is
a
corresponding
statusListIndex
value
in
a
credential
in
issuedCredentials
,
set
the
value
to
the
appropriate
status.
The
position
of
the
value
is
computed
as
statusListIndex
times
the
statusSize
.
The following process, or one generating the exact output, MUST be followed when expanding a compressed status list bitstring. The algorithm takes a compressed bitstring as input and either throws an error or returns a uncompressed bitstring as output.
The algorithms described in this specification throw specific types of errors. Implementers might find it useful to convey these errors to other libraries or software systems. This section provides specific URLs, descriptions, and error codes for the errors, such that an ecosystem implementing technologies described by this specification might interoperate more effectively when errors occur.
When exposing these errors through an HTTP interface, implementers SHOULD use Problem Details for HTTP APIs [ RFC9457 ] to encode the error data structure. If [ RFC9457 ] is used:
type
value
of
the
error
object
MUST
be
a
URL
that
starts
with
the
value
https://www.w3.org/ns/credentials/status-list#
and
ends
with
the
value
in
the
section
listed
below.
code
value
MUST
be
the
integer
code
described
in
the
table
below
(in
parentheses,
beside
the
type
name).
The
title
value
SHOULD
provide
a
short
but
specific
human-readable
string
for
the
error.
detail
value
SHOULD
provide
a
longer
human-readable
string
for
the
error.
Accept-Language
HTTP
header
field
to
select
the
most
appropriate
resources.
There are multiple ways that the information in Section 2. Data Model can be secured. These mechanisms are elaborated upon in the Securing Mechanisms section of the Verifiable Credentials Data Model v2.0 .
When securing a verifiable credential that contains a reference to a BitstringStatusListCredential , implementers SHOULD use the same securing mechanism with the same cryptographic parameters and the same media type for both verifiable credentials .
When
dereferencing
statusListCredential
,
the
content
of
the
returned
statusListCredential
might
be
any
media
type
registered
for
the
purpose
of
expressing
a
verifiable
credential
with
one
or
more
proofs.
For
example,
a
verifiable
credential
secured
with
Data
Integrity
Proofs
might
have
media
type
application/vc+ld+json
,
while
a
verifiable
credential
secured
with
SD-JWT
might
have
media
type
application/sd-jwt
.
Some
implementations
might
choose
to
support
less
specific
media
types
such
as
application/ld+json
or
application/json
.
When
dereferencing
over
HTTP,
the
use
of
the
accept
and
content-type
headers,
might
allow
some
implementations
to
negotiate
for
the
proof
format
used
to
secure
the
statusListCredential
.
Some implementations might use the 415 Unsupported Media Type status code to signal that they do not support the requested media type.
This section is non-normative.
This section details the general privacy considerations and specific privacy implications of deploying this specification into production environments.
Readers are urged to familiarize themselves with the general privacy advice provided in the Privacy Considerations section of the Verifiable Credentials specification before reading this section.
This section is non-normative.
This document specifies a minimum revocation bitstring length of 131,072, or 16KB uncompressed. This is enough to give holders an adequate amount of group privacy if the number of verifiable credentials issued is large enough. However, if the number of issued verifiable credentials is a small population, the ability to correlate an individual increases because the number of allocated slots in the bitstring is small. Correlating this information with, for example, where the geographic request came from can also help to correlate individuals that have received a credential from the same geographic region.
This section is non-normative.
There
are
a
number
of
global
identifiers
used
in
a
status
list
entry,
defined
in
Section
2.1
BitstringStatusListEntry
,
that
can
be
used
across
verifiers
to
correlate
subjects
.
Some
of
the
properties
that
can
express
these
values
are
id
,
statusListIndex
,
and
statusListCredential
.
In some cases, such as when presenting a verifiable credential that contains a global identifier (such as a driver's license identification number), adding one or more global identifier(s) for status list information does not increase correlation harm, since a single globally unique identifier is all that is required for correlation.
When global identifiers are used in presentations that use selective disclosure or unlinkable disclosure , they can violate privacy expectations. Issuers are urged to enable status information to be selectively disclosable/concealable when a particular verifiable credential is expected to be disclosed in a way that does not need correlation, such as when proving that an individual is above a certain age. Verifiers can require that status information be revealed in situations that require them to know the current status of a credential, and the holder might then consent or refuse to reveal that information for a given transaction. In all cases, both issuers and verifiers are urged to avoid the use of global identifiers in order to prevent correlation, unless it is required for or by a particular exchange.
For information on other types of potential correlation, readers are urged to study the Privacy Considerations section of the Verifiable Credentials Data Model v2.0 specification, particularly the subsections on Identifier-Based Correlation , Signature-Based Correlation , Long-Lived-Identifier-Based Correlation , and Metadata-Based Correlation .
This section is non-normative.
It is possible for verifiers to increase the privacy of the holder whose verifiable credential is being checked by caching status lists that have been fetched from remote servers. By caching the content locally, less correlatable information can be inferred from verifier -based access patterns on the status list.
This section is non-normative.
The use of content distribution networks by issuers can increase the privacy of holders by reducing or eliminating requests for the status lists from the issuer . Often, a request for a revocation list will be served by an edge device and thus be faster and reduce the load on the server as well as cloaking verifiers and holders from issuers .
This section is non-normative.
Issuer use of decoy values in status lists has been explored as a mechanism to increase the privacy of subjects . While algorithms for employing decoy values are out of scope for this specification, implementers are advised that...
The Working Group is currently discussing what sort of guidance to provide for decoy values. It has been suggested that decoy values are, in general, harmful to this specification's privacy characteristics. However, the group has not provided a complete analysis and thorough review for that assertion. The analysis might result in some use cases where decoy values are helpful, or might conclude that decoy values are, in general, harmful. Further thought is currently being put into the language around decoy values and it is expected that this language will be finalized during the Candidate Recommendation phase.
This section is non-normative.
In general, the group privacy protections offered by this specification can be circumvented by malicious issuers and verifiers . Its privacy benefits can only be realized when issuers and verifiers intend to avoid tracking or sharing the presentation of particular credentials.
A malicious verifier might intentionally attack group privacy by sharing information from presented credentials with a malicious issuer . This sort of collusion is difficult to detect as it is typically performed via a secure communication channel between the issuer and the verifier .
A malicious issuer might intentionally attack group privacy by creating a unique status list for each issued credential, in order to establish a one-to-one mapping to track when a verifier processes each mapped credential. Similarly, they could establish a one-to-one mapping by using a different cryptographic key for each issued credential that is tracked by a given status list.
This sort of collusion can be detected by holder software that serves multiple holders (e.g., a holder app that runs on a server) if it has, for example, an opt-in process that finds that some global identifier(s) used within a verifiable credential are not adequately shared by other credentials. Holders could then be warned when presenting a verifiable credential that contains some global identifier(s) that are unique to that credential. Such an opt-in service could represent some additional privacy concerns; whether this potential exposure via the holder software is justified by the awareness of possible global identifier correlation can only be evaluated by the users of such a system.
This section is non-normative.
Once a verifier knows of a status list and entry index that is associated with a specific holder or subject , it becomes possible for that verifier to see updates to that status entry as long as the status list continues to be updated. This is useful to a verifier that needs to understand when a particular verifiable credential has changed status without asking the issuer directly for status information on the specific verifiable credential or when interacting with the holder to get the latest status information is not possible. The feature can also cause a privacy violation for the holder and/or subject if the verifier is able to perform near-real-time checks on the status of the verifiable credential .
Issuers can provide a level of reprieve from this privacy concern for holders by revoking and reissuing effectively the same verifiable credential on a relatively brief timeline. For example, an issuer could automatically reissue a verifiable credential every three months and assign a new status entry index when the reissuance occurs to break any sort of long-term monitoring of a verifiable credential as it changes status.
This section is non-normative.
This specification provides a means by which multiple status messages can be provided for a particular entry in a status list. While this mechanism can provide more detailed information for a particular entry in the status list, that information can provide further correlation data.
For example, if each status message is associated with a step in a particular process, or more detailed information as to why a credential was revoked or suspended, then an attacker that observes the changes in the list might be able to correlate information about the population of entities in the list that could lead to privacy violations. Understanding how a population progresses through a business process, or what percentage of the population is likely to be associated with a certain status, provides additional information to an attacker. Given such information, a phishing operation could predict what the next step of a business process is and then preemptively contact an entity whose current status is known. Then, based on that information, they could attempt to phish more lucrative information from the target using data gleaned from the status list over time.
For these reasons, issuers are urged to evaluate the potential ramifications of publishing detailed status information about a particular entity, or a population, in a public manner.
This section is non-normative.
When a status list uses the status messages feature, it becomes possible for the issuer to increase the types of messages that are associated with the verifiable credentials it issues over time.
This feature creates a potential privacy violation where the subject or holder of the verifiable credential might be associated with additional status information that was not present when the original verifiable credential was issued. For example, initial status messages might convey "delayed" and "canceled", but additional status messages might be added by the issuer to convey "delayed due to non-payment" and "canceled due to illegal activity". This change would not be apparent to the subject or holder unless there was monitoring software operating on their behalf that would warn them that the issuer intends to expose additional information about their activity.
Holder software can provide features to holders that warn them about the level of holder and/or subject information exposure when using verifiable credentials that are associated with status messages, and warn them when the level of information exposure changes.
This section is non-normative.
There are a number of security considerations that implementers should be aware of when processing data described by this specification. Ignoring or not understanding the implications of this section can result in security vulnerabilities.
Readers are urged to familiarize themselves with the general security advice provided in the Security Considerations section of the Verifiable Credentials specification before reading this section.
While this section attempts to highlight a broad set of security considerations, it is not a complete list. Implementers are urged to seek the advice of security and cryptography professionals when implementing mission critical systems using the technology outlined in this specification.
This section is non-normative.
It is critical that implementers pay particular attention to the way that they encode and decode bitstrings. Failure to do so can result in checking the wrong bitstring index for a given credential, leading to a misinterpretation of its present state (e.g., mistaking a revoked status for an unrevoked status). As stated in Section 2.2 BitstringStatusListCredential , bitstrings are encoded such that the first (zeroth) index refers to the left-most bit of the bitstring array. The diagram below demonstrates the proper layout for an uncompressed bitstring.
For example, if a bitstring is 131,072 bits in size (16KB), the first index will be 0, and the last index will be 131,071.
This section is non-normative.
Readers are urged to familiarize themselves with the general accessibility advice provided in the Accessibility Considerations section of the Verifiable Credentials specification . No further advice is provided in this specification beyond the general advice for all verifiable credentials .
This section is non-normative.
Readers are urged to familiarize themselves with the general internationalization advice provided in the Internationalization Considerations section of the Verifiable Credentials specification . No further advice is provided in this specification beyond the general advice for all verifiable credentials .
This section is non-normative.
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://www.w3.org/ns/credentials/examples/v2"
],
"id": "https://example.com/credentials/23894672394",
"type": ["VerifiableCredential"],
"issuer": "did:example:12345",
"validFrom": "2021-04-05T14:27:42Z",
"credentialStatus": {
"id": "https://example.com/credentials/status/3#94567",
"type": "BitstringStatusListEntry",
"statusPurpose": "revocation",
"statusListIndex": "94567",
"statusListCredential": "https://example.com/credentials/status/3"
},
"credentialSubject": {
"id": "did:example:6789",
"type": "Person"
}
}
{ "@context": [ "https://www.w3.org/ns/credentials/v2", "https://www.w3.org/ns/credentials/examples/v2" ], "id": "https://example.com/credentials/status/3", "type": ["VerifiableCredential", "BitstringStatusListCredential"], "issuer": "did:example:12345", "validFrom": "2021-04-05T14:27:40Z", "credentialSubject": { "id": "https://example.com/status/3#list", "type": "BitstringStatusList", "statusPurpose": "revocation", "encodedList": "uH4sIAAAAAAAAA-3BMQEAAADCoPVPbQwfoAAAAAAAAAAAAAAAAAAAAIC3AYbSVKsAQAAA" } }
This specification enables an issuer to associate multiple status lists with a single verifiable credential .
{ "@context": [ "https://www.w3.org/ns/credentials/v2", "https://www.w3.org/ns/credentials/examples/v2" ], "id": "https://example.com/credentials/23894672394", "type": ["VerifiableCredential"], "issuer": "did:example:12345", "issuanceDate": "2021-04-05T14:27:42Z", // note the use of an array to represent the set of // status entries "credentialStatus": [{ "id": "https://example.com/credentials/status/3#94567", "type": "BitstringStatusListEntry", "statusPurpose": "revocation", "statusListIndex": "94567", "statusListCredential": "https://example.com/credentials/status/3" }, { "id": "https://example.com/credentials/status/4#12345", "type": "BitstringStatusListEntry", "statusPurpose": "suspension", "statusListIndex": "12345", "statusListCredential": "https://example.com/credentials/status/4" }], "credentialSubject": { "id": "did:example:6789", "type": "Person" } }
It is possible for a single status list to contain multiple types of status purposes. Doing so can make the retrieval of a list slightly more efficient than fetching multiple status lists.
The
"space
efficiency"
argument
for
this
feature
is
weak.
One
list
with
two
types
of
status
entries
must,
presumably,
be
twice
as
long
as
a
list
with
one
type
of
status
entries,
to
ensure
proper
privacy
protections.
One
privacy
benefit
of
doing
so
is
that
bit
flips
cannot
be
known
to
be
associated
with
a
particular
status
unless
one
is
also
in
control
of
the
VC
that
the
status
is
about.
Therefore,
mixing
"revocation"
and
"suspension"
in
a
single
list
that
is
twice
as
large
has
positive
privacy
implications.
The
"retrieval
efficiency"
argument
is
also
weak.
Performing
two
HTTP
retrievals
instead
of
one
is
probably
not
significant.
Performing
upwards
of
five
or
six,
on
a
list
that
is
five
or
six
times
larger,
might
result
in
fairly
meager
savings
over
modern
versions
of
HTTP
that
bundle
requests
over
a
single
channel
(such
as
HTTP/2
or
HTTP/3).
The
requests
themselves
would
save
a
handful
of
bytes
with
no
significant
improvement
in
retrieval
speed.
The
Working
Group
is
looking
for
feedback
from
implementers
and
is
considering
striking
this
feature
during
the
Candidate
Recommendation
period,
since
it
would
simplify
the
specification
for
implementations
to
not
have
to
support
sets
of
statusPurpose
values
in
the
status
list
credentials
(again,
a
meager
savings
in
space
efficiency
at
a
small
cost
to
retrieval
efficiency).
{ "@context": [ "https://www.w3.org/ns/credentials/v2", "https://www.w3.org/ns/credentials/examples/v2" ], "id": "https://example.com/credentials/23894672394", "type": ["VerifiableCredential"], "issuer": "did:example:12345", "issuanceDate": "2021-04-05T14:27:42Z", // note the use of a single list to store multiple // status entries "credentialStatus": [{ "id": "https://example.com/credentials/status/5#94567", "type": "BitstringStatusListEntry", "statusPurpose": "revocation", "statusListIndex": "94567", "statusListCredential": "https://example.com/credentials/status/5" }, { "id": "https://example.com/credentials/status/5#12345", "type": "BitstringStatusListEntry", "statusPurpose": "suspension", "statusListIndex": "12345", "statusListCredential": "https://example.com/credentials/status/5" }], "credentialSubject": { "id": "did:example:6789", "type": "Person" } }