Skip to content

Commit

Permalink
Merge pull request #2343 from swcurran/rev-overview
Browse files Browse the repository at this point in the history
Add more context to the ACA-Py Revocation handling documentation
  • Loading branch information
swcurran authored Jul 24, 2023
2 parents 7c01704 + 795a21b commit cb88963
Showing 1 changed file with 101 additions and 7 deletions.
108 changes: 101 additions & 7 deletions docs/GettingStartedAriesDev/CredentialRevocation.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,100 @@
# Credential Revocation

These are the ACA-py steps and APIs involved to support credential revocation.

Run ACA-Py with tails server support enabled. You will need to have the URL of an running instance of https://github.com/bcgov/indy-tails-server.
# Credential Revocation in ACA-Py

## Overview

Revocation is perhaps the most difficult aspect of verifiable credentials to
manage. This is true in AnonCreds, particularly in the management of AnonCreds
revocation registries (RevRegs). Through experience in deploying use cases with
ACA-Py we have found that it is very difficult for the controller (the
application code) to manage revocation registries, and as such, we have changed
the implementation in ACA-Py to ensure that it is handling almost all the work
in revoking credentials. The only thing the controller writer has to do is track
the minimum things necessary to the business rules around revocation, such as
whose credentials should be revoked, and how close to real-time should
revocations be published?

Here is a summary of all of the AnonCreds revocation activities performed
by issuers. After this, we'll provide a (much shorter) list of what an ACA-Py
issuer controller has to do. For those interested, there is a more [complete
overview of AnonCreds revocation], including all of the roles, and some details
of the cryptography behind the approach:

- Issuers indicate that a credential will support revocation when creating the
credential definition (CredDef).
- Issuers create a Revocation Registry definition object of a given size
(MaxSize -- the number of credentials that can use the RevReg) and publish it
to the ledger (or more precisely, the verifiable data registry). In doing
that, a Tails file is also created and published somewhere on the Internet,
accessible to all Holders.
- Issuers create and publish an initial Revocation Registry Entry that defines
the state of all credentials within the RevReg, either all active or all
revoked. It's a really bad idea to create a RevReg starting with "all
revoked", so don't do that.
- Issuers issue credentials and note the "revocation ID" of each credential. The
"revocation Id" is a compound key consisting of the RevRegId from which the
credential was issued, and the index within that registry of that credential.
An index (from 1 to Max Size of the registry -- or perhaps 0 to Max Size - 1)
can only be associated with one issued credential.
- At some point, a RevReg is all used up (full), and the Issuer must create another
one. Ideally, this does not cause an extra delay in the process of issuing credentials.
- At some point, the Issuer revokes the credential of a holder, using the
revocation Id of the relevant credential.
- At some point, either in conjunction with each revocation, or for a batch of
revocations, the Issuer publishes the RevReg(s) associated with a CredDef to
the ledger. If there are multiple revocations spread across multiple RevRegs,
there may be multiple writes to the ledger.

[complete overview of AnonCreds revocation]: https://github.com/hyperledger/indy-hipe/blob/main/text/0011-cred-revocation/README.md

Since managing RevRegs is really hard for an ACA-Py controller, we have tried to
minimize what an ACA-Py Issuer controller has to do, leaving everything else to be
handled by ACA-Py. Of the items in the previous list, here is what an ACA-Py
issuer controller does:

- Issuers flag that revocation will be used when creating the CredDef and the
desired size of the RevReg. ACA-Py takes case of creating the initial
RevReg(s) without further action by the controller.
- Two RevRegs are initially created, so there is no delay when one fills up,
and another is needed. In ongoing operations, when one RevReg fills up, the
other active RevReg is used, and a new RevReg is created.
- On creation of each RevReg, its corresponding tails file is published by
ACA-Py.
- On Issuance, the controller receives the logical “revocation ID" (combination
of RevRegId+Index) of the issued credential to track.
- On Revocation, the controller passes in the logical “revocation ID" of the
credential to be revoked, including a “notify holder” flag. ACA-Py records the
revocation as pending and, if asked, sends a notification to the holder using
a DIDComm message ([Aries RFC 0183: Revocation Notification]).
- The Issuer requests that the revocations for a CredDefId be published. ACA-Py
figures out what RevRegs contain pending revocation and so need to be
published, and publishes each.

That is the minimum amount of tracking the controller must do while still being
able to execute the business rules around revoking credentials.

[Aries RFC 0183: Revocation Notification]: https://github.com/hyperledger/aries-rfcs/blob/main/features/0183-revocation-notification/README.md

From experience, we’ve added to two extra features to deal with unexpected
conditions:

- When using an Indy (or similar) ledger, if the local copy of a RevReg gets out
of sync with the ledger copy (perhaps due to a failed ledger write), the
Framework can create an update transaction to “fix” the issue. This is needed
for a revocation state using deltas-type solution (like Indy), but not for a
ledger that publishes revocation states containing the entire state of each
credential.
- From time to time there may be a need to [“rotate” a
RevReg](#revocation-registry-rotation) — to mark existing, active RevRegs as
“decommissioned”, and create new ones in their place. We’ve added an endpoint
(api call) for that.

## Using ACA-Py Revocation

The following are the ACA-Py steps and APIs involved in handling credential revocation.

To try these out, use the ACA-Py Alice/Faber demo with tails server support
enabled. You will need to have the URL of an running instance of
[https://github.com/bcgov/indy-tails-server](https://github.com/bcgov/indy-tails-server).

Include the command line parameter `--tails-server-base-url <indy-tails-server url>`

Expand Down Expand Up @@ -60,7 +152,7 @@ Include the command line parameter `--tails-server-base-url <indy-tails-server u
If publish=false, you must use `​/issue-credential​/publish-revocations` to publish
pending revocations in batches. Revocation are not written to ledger until this is called.

3. When asking for proof, specify the timespan when the credential is NOT revoked
3. When asking for proof, specify the time span when the credential is NOT revoked
```
POST /present-proof/send-request
{
Expand Down Expand Up @@ -154,9 +246,11 @@ thread ID and comment is emitted to registered webhook urls.

## Manually Creating Revocation Registries

> NOTE: This capability is deprecated and will likely be removed entirely in an upcoming release of ACA-Py.
The process for creating revocation registries is completely automated - when you create a Credential Definition with revocation enabled, a revocation registry is automatically created (in fact 2 registries are created), and when a registry fills up, a new one is automatically created.

However the Aca-Py admin api supports endpoints to explicitely create a new revocation registry, if you desire.
However the ACA-Py admin api supports endpoints to explicitly create a new revocation registry, if you desire.

There are several endpoints that must be called, and they must be called in this order:

Expand Down

0 comments on commit cb88963

Please sign in to comment.