# June 13, 2023 - AnonCreds Project Report
- Significant refactors
- Cleaning up which components are responsible for what
- Refined records used to track anoncreds objects in issuer
- MVP Revocation completed
- Items completed:
- Marking credential for revocation
- Publishing pending revocation
- Presenting and verifying revocable credentials
- What's next
- Automated registry setup
- Plan in place; implementation thus far has been building to this point
- Should be relatively quick to execute but additional refactors and refinements anticipated
- Genericize revocation registry recovery?
- Catching ledger up with wallet state
- Adapt original Indy anoncreds interface?
- Schema, Cred def, revocation?
- What else is required to smoothly transition?
- Retain both systems?
- Test updates
- Cleaning Up
#### Links
PR to ACA-Py: https://github.com/hyperledger/aries-cloudagent-python/pull/2191
Active branch: https://github.com/Indicio-tech/aries-cloudagent-python/tree/feature/anoncreds-revocation-again
# May 30, 2023 - AnonCreds Project Report
- Updated anoncreds-rs build
- Tails file handling now uses tails hash as the file name
- Updates to indy-tails-server: https://github.com/Indicio-tech/indy-tails-server/tree/fix/tails-file-hash-update
- Basic checks, investigating further validation on the uploaded file
- "MVP" Revocation nearly complete
- Issuance and presentation completed
- Working on publishing revocation updates
- Focus for this week:
- Finishing off publishing revocation updates
- Automated registry setup
- Unit test updates
- Cleaning up
#### Links
PR to ACA-Py: https://github.com/hyperledger/aries-cloudagent-python/pull/2191
Active branch: https://github.com/Indicio-tech/aries-cloudagent-python/tree/feature/anoncreds-revocation-again
# May 2, 2023 - AnonCreds Project Report
- Short on resources during the month of April; more resources to address it now
- Biggest focus area remains to be Revocation support
- This week:
- Updating to more recent builds of anoncreds-rs
- Tails file handling changes (more discussion below)
- Reassessing existing revocation components to determine what to reuse and what to deprecate
- We have diagrams. Lots of diagrams.
- MVP Revocation using AnonCreds interface
- Isolating the core operations
- No automation, no batching
- Answering questions
- Batching updates to revocation list
- Level of backwards compatibility
- Assessing changes in what needs to be stored (generic vs indy, revocation list vs deltas)
- Next week and beyond:
- Consolidating diagrams, design doc into docs for the repo
- AnonCreds method plugin author guide
- Updating unit and integration tests
- Adapt/deprecate Admin APIs for publishing AnonCreds objects for Indy
- Complete integration with Issue Credential and Present Proof
### Tails File Handling
**The problem:**
- Indy Tails Server expects revocation registry ID
- AnonCreds Interface must know tails location in order to publish
- Revocation registry ID not known until after publishing
**Solutions?**
- Relax expectations of tails server
- Simpler, reusable by other methods
- Just accept a file by hash, do basic hash validation on the contents of the file
- No AnonCreds registry communication at all
- AnonCreds Method plugins responsible for tails file upload
- Indy method could continue to use Indy Tails Server unmodified (rev reg ID known prior to publishing so it can behave the same as before)
- Each method has its own tails server?
- Make Indy Tails Server more generic?
- Problem: If we want same level of validation as currently exists, tails server would need a universal resolver for AnonCreds objects. Complexity increases.
**Current conclusion:** relax tails server, make tails file upload generic
### Batching Updates to Revocation Lists
**Question:** Whose responsibility is it to batch revocation updates? Plugin or ACA-Py?
- It is a bit early in the lifecycle of the AnonCreds as a legder-agnostic protocol to be too sure about exact behavior of revocation for all methods. It's possible some methods will be like Indy; Indy has a fee structure around transactions that incentivizes collecting changes and then publishing only after reaching a certain threshold or on a regular schedule. Other methods may also desire to batch to reduce costs. **_Batching is probably widely desirable._**
- ACA-Py just provides the handles for implementing this kind of a schedule or threshold matching and is not opinionated about when or how often this occurs. **_ACA-Py's implementation for batching is decently generic._**
- Other methods may be wildly different. Or **_other methods may have more sophisticated batching needs._**
- If ACA-Py implements a default batching scheme, that doesn't necessarily restrict whether or not the plugin could implement its own. **_ACA-Py default batching and Method-specific batching can coexist._**
- Also, Stephen made the point that batching is as much a business decision as it is a network optimization decision.
**Current conclusion:** still targeting an MVP where we will not batch updates but expect that the final interface will provide a batching strategy (expected to be the same as currently implemented) that method plugins can bypass if needed.
# April 4, 2023 - AnonCreds Project Report
## Acknowledgments
- Credit to Adam Burdett and Char Howland for doing the lion's share of the work
- Animo and others working on anoncreds-rs project and for a lot of the interface design
## Progress
- Pluggable Interface for AnonCreds Methods
- Essentially replaces use of the BaseLedger for AnonCreds object resolution and registration
- Inspired by our past work on DID Resolution
- Each plugin implements a `supports` method that takes an Identifier and returns whether it supports it or not
- `AnonCredsRegistry` acts as an aggregate interface.
```plantuml
package anoncreds {
class AnonCredsIssuer {
+ create_schema()
+ create_and_store_credential_definition()
+ create_credential_offer()
+ create_credential()
+ revoke_credentials()
+ create_and_store_revocation_registry()
+ merge_revocation_registry_deltas()
}
class AnonCredsHolder {
+ create_credential_request()
+ store_credential()
+ get_credential()
+ create_presentation()
+ create_revocation_state()
}
class AnonCredsVerifier {
+ verify_presentation()
}
abstract class BaseAnonCredsRegistrar {
async def register_schema() -> SchemaResult
async def register_credential_definition() -> CredDefResult
async def register_revocation_registry_definition() -> RevRegDefResult
async def register_revocation_status_list() -> RevStatusListResult
}
abstract class BaseAnonCredsResolver {
async def get_schema() -> GetSchemaResult
async def get_credential_definition() -> GetCredDefResult
async def get_revocation_registry_definition() -> GetRevRegDefResult
async def get_revocation_status_list() -> GetRevStatusListResult
}
class AnonCredsRegistry {
async def _registrar_for_identifier()
async def _resolver_for_identifier()
{method} ...
}
}
together {
class DidIndyRegistry
class LegacyIndyRegistry
class DidWebRegistry
}
LegacyIndyRegistry ..|> BaseAnonCredsRegistrar
LegacyIndyRegistry ..|> BaseAnonCredsResolver
DidIndyRegistry ..|> BaseAnonCredsRegistrar
DidIndyRegistry ..|> BaseAnonCredsResolver
DidWebRegistry ..|> BaseAnonCredsRegistrar
DidWebRegistry ..|> BaseAnonCredsResolver
BaseAnonCredsRegistrar <.. AnonCredsRegistry
BaseAnonCredsResolver <.. AnonCredsRegistry
AnonCredsRegistry <.. AnonCredsHolder
AnonCredsRegistry <.. AnonCredsIssuer
AnonCredsRegistry <.. AnonCredsVerifier
```
```json
// Example result object for SchemaResult
{
"job_id": "string",
"schema_state": {
"state": "string",
"schema_id": "string",
"schema": {
"attrNames": ["string"],
"name": "string",
"version": "string",
"issuerId": "string"
}
},
"registration_metadata": {},
"schema_metadata": {
// For indy, schema_metadata will contain the seqNo
"seqNo": "12345"
}
}
```
- Adjusted the Credential Issuance and Presentation flows to use AnonCreds Interface
- Cred Defs resolved through `AnonCredsRegistry`
- Revocation lists resolved through `AnonCredsRegistry` (theoretically...)
- Credential offers and requests prepared through `anoncreds-rs`, accepting the new models for cred defs, others
- Revocation state generated through new models (theoretically...)
- Admin API for creating AnonCreds Objects
- Schema and Credential Definitions completed
- Revocation Registry Definitions and Revocation Lists in progress
## Challenges
```plantuml
package "indy" {
abstract class IndyIssuer {
+ create_schema()
+ create_and_store_credential_definition()
+ create_credential_offer()
+ create_credential()
+ revoke_credentials()
+ create_and_store_revocation_registry()
+ merge_revocation_registry_deltas()
}
abstract class IndyHolder {
+ create_credential_request()
+ store_credential()
+ get_credential()
+ create_presentation()
+ create_revocation_state()
}
abstract class IndyVerifier {
+ verify_presentation()
}
class IndyCredxVerifier {
}
class IndyCredxIssuer {
}
class IndyCredxHolder {
}
class IndySdkVerifier {
}
class IndySdkIssuer {
}
class IndySdkHolder {
}
}
IndyCredxHolder --|> IndyHolder
IndyCredxIssuer --|> IndyIssuer
IndyCredxVerifier --|> IndyVerifier
IndySdkHolder --|> IndyHolder
IndySdkIssuer --|> IndyIssuer
IndySdkVerifier --|> IndyVerifier
' ## Dependent stuff ##
together {
abstract class BaseLedger {
+ create_and_send_schema()
+ create_and_send_credential_definition()
+ send_revoc_reg_def()
+ send_revoc_reg_entry()
}
class IndyPresExchHandler {
+ return_presentation()
+ verify_pres()
}
class PresentationManager {
+ verify_presentation()
}
' Issue Credential V2
class IndyCredFormatHandler {
+ create_ofer()
+ create_request()
+ issue_credential()
+ store_credential()
}
' Issue Credential V1
class CredentialManager {
+ create_offer()
+ create_request()
+ issue_credential()
+ store_credential()
}
together {
class RevocationManager {
+ revoke_credential()
+ publish_pending_revocations()
}
class IssuerRevRegRecord {
+ generate_registry()
+ send_def()
+ send_entry()
}
entity "revocation/routes.py" as rev_routes {
+ on_revocation_registry_init_event()
}
class IndyRevocation {
+ init_issuer_registry()
+ handle_full_registry()
}
entity "credential_definitions/routes.py" as cred_def_routes {
+ on_cred_def_event()
}
}
}
BaseLedger -up-> IndyIssuer
IndyCredFormatHandler -up-> IndyIssuer
IndyCredFormatHandler -up-> IndyHolder
IndyCredFormatHandler -down-> IndyRevocation
CredentialManager -up-> IndyIssuer
CredentialManager -up-> IndyHolder
IndyPresExchHandler -up-> IndyHolder
IndyPresExchHandler -up-> IndyVerifier
PresentationManager -up-> IndyVerifier
RevocationManager -up-> IndyIssuer
RevocationManager -left-> IssuerRevRegRecord
IssuerRevRegRecord -up-> IndyIssuer
IssuerRevRegRecord -up-> BaseLedger
rev_routes -up-> IssuerRevRegRecord
IndyRevocation -left-> rev_routes
cred_def_routes -left-> IndyRevocation
```
- Some prior held core assumptions have been broken
- Identifiers for objects known before registration -> Identifiers for objects are only guaranteed to be known after reaching `finished` state.
- Revocation registry definitions and revocation status lists are closely tied together
- Revocation status lists must have the revocation registry definition ID in order to create the list
- Identifiers are not known until after registration of objects
- Therefore, revocation status lists must be registered strictly after the revocation registry definition has been finished.
- Much of the logic surrounding revocation is split across many locations
- Event handlers
- Present Proof
- Admin API Routes
## Additional Discussion Points
- Endorsement