---
tags: Design, Concept
---
# Verifiable Credential Validity and Refresh
## Motivation
There are two main motivations for limiting the validity of verifiable credentials:
1. Claims may change
2. Credentials might get stolen
3. Fraudulent credentials have been issued
## General Approaches to limit validity
### Expiration
Attestations typically have an expiration date or a validity period.
- Physical Credentials (ID, Drivers licence) have typically validity periods of a few years
- x.509 certificates for private Public Key Infrastructure (PKI) often have validity periods of a few years (up to 20 years)
- x.509 certificates for the Web PKI have validity periods of months to a year
- JWT in OAuth and Open ID Connect have validity periods of minutes to hours
### Recovation
Revocation is a mechanism to invalidate an attestation within its validity period. Revocation creates additional complexity and is therefore typically only used in scenarios with long validity periods.
For example in OAuth there is no possibility to revoke a token if ressource server and authorization server do not communicate directly.
## Refresh
Credentials with a limited period of validity need a mechanism for reshreshing the credential, i.e. a (typically automated) re-issuance.
## Verifiable Credentials
### W3C Data Model
The core VC data model describes a few properties related to this
- [Expiration date](https://www.w3.org/TR/vc-data-model/#expiration)
- validFrom, validUntil (Already in the [Base Context](https://www.w3.org/2018/credentials/v1), but not well described in Spec 1.0)
- [Refresh](https://www.w3.org/TR/vc-data-model/#refreshing)
### Indy
The Indy community is much more inclided to use a ledger-based anonymous revocation mechanism. However, if you browse the [schemas on the Sovrin Main Net](https://indyscan.io/txs/SOVRIN_MAINNET/domain?page=1&pageSize=50&filterTxNames=[%22SCHEMA%22]&sortFromRecent=true), you'll find schemas with attributes like
- expiration_date
- issue_date
- expiry_date
- effective_date
This means, while in the W3C data model properties describing validity periods are defined independent of the claims, in Indy they need to be part of the schema like any other attribute. Furthermore, there is no check of validity on Indy/Aries level, but we would need to implement the validity check in terms of validity period in the application/business layer.
Furthermore, there are currently no Aries protocols/RFCs that are concerned with refreshing a credential.
## Application to Bank Account Credentials
Assume the following scenario consisting of three entities
- Bank
- Supplier
- Customer
The _supplier_ shares a bank account at _bank_ with the _customer_.
### Do we need revocation?
The first observation is that revocation is not really required in this scenario, because the legitimate holder of the credential (_supplier_) has no incentive to use an invalid credential. If there was an error in the credential the _supplier_ is strongly incentivized to tell all its customers that they should use the new one.
Revocation is only useful if an attacker could convince a bank to issue a fraudulent credential.
Note: Using indy based revocation would imply that the customer has to always ask the supplier to provide a proof of non-revocation each time the bank account needs to be use.
### Do we need a validity period?
A validity period acts as a safety measure, that data is updated occasionaly and legacy data can't be regarded as valid. However, as described above, the incentives for the holder/supplier and the verifier/customer are aligned to use the latest data.
We should also disentangle credential and presentation here:
```plantuml
@startuml
"Bank"->"Supplier": Credential
"Supplier"->"Customer": Presentation
@enduml
```
Including a validity period in the credential is not sufficient to transport an intent like the following:
> This bank account should be used for offer x or this bank account should be used starting from 01.01.2021
This intent/information is independent of a validity period in the original credential.
### Implementation in Business Partner Agent
In the following we concentrate on the validity period of the credential (although my feeling is that the other is actually more important)
#### Introduction of well-known validity period attributes in credential schemas
- Issuer/Bank: Schemas need properties that define the validity period (e.g. validFrom, validUntil)
- Holder/Supplier: There needs to be business logic to define when a credential should be refreshed
- Holder/Supplier: There needs to be business logic to define if refreshed credentials should be shared with business partners automatically
- Verifier/Customer: There needs to be business logic check validation period
- Verifier/Customer: There needs to business logic to define when a new presentation should be requested
Currently there is no relationship between a document and a verified credential (instances), and between different verifiable credentials. We'd need to fix this. See also [Refreshing](https://hackmd.io/zOPpWeZQQI-nYPAMrfWy2Q#Refreshinig)
#### Implications on demo flow with respect to request a bank account verification
Currently the bank account holder (Business Partner Agent) provides the credential content and the bank basically signs it.
However, it does not make sense that the holder defines the validity period of the credential, and those attributes should not be shown in the Document UI of the BPA.
##### Envisioned Scenario/Flow
Schema `bank_account_with_validity`
```
iban
bic
validFrom
validUntil
```
**High-level Request flow**
```plantuml
@startuml
BPA -> Issuer: Send proposal with empty validFrom/Until
Issuer -> Issuer: Validates proposal internally, sets validFrom/Until
Issuer -> BPA: Credential offer with validity
BPA-> Issuer: Request Credential with validity
Issuer -> BPA: Issue Credential with validity
@enduml
```
- Refresh flow could be simply a new (unrelated) request flow.
**Simple Demo flow with minimal required changes**
The simplest way to provide a demo are "just" a few changes in the frontend. In particular, this would require no changes on the issuer side.
* Don't show `validFrom` and `validTo` in documents
* Add predefined `validTo` and `validFrom` (e.g. now and 1 minute in the future) on the controller side of the UI.
* Add check in received presentations that validFrom < now < validUntil
* Add refresh/renew button to UI which triggers new request issuance flow
However there are few issues with this:
* In the wallet we would have two bank account credentials
* We need to define how the presentation flow should happen and which cases we'd need to cover.
* e.g. do we allow to send an expired presentation, such that validation can fail on the receiving side?
* Do we require to refresh a credential when its expired?
#### Refreshing
This is the protocol that happens between holder and issuer, i.e. supplier and bank.
Technically this is similar to the initial verification and could be manually or automated on the holder side.
Note: Aries is not aware of refreshing. On Aries level this is a new and unrelated VC. The relationship has to be defined in the BPA core layer, e.g. as shown [below](https://hackmd.io/zOPpWeZQQI-nYPAMrfWy2Q#Overview-of-entities-and-their-relationship).
#### Overview of entities and their relationship
This is just meant to be basis for discussion. This is not the data model currently implemented
```plantuml
@startuml
class Document {
id
label
schema/type
VerifiableCredential[] Verifications
}
class VerifiableCredential {
id
issuer
validFrom
validUntil
}
class Presentation {
(validFrom)
(validUntil)
VerifiableCredential
BusinessPartner
}
class BusinessPartner {
id
connection
}
class Issuer {
id
Schema[]
}
Issuer -- BusinessPartner: > is a
Document -- VerifiableCredential: < verifies
VerifiableCredential -- Issuer: < issues
Document -- Presentation: > is shared as
Presentation -- BusinessPartner: > is shared with
@enduml
```
## Conclusion
Inclusion of a validity period in a bank credential is in general a good idea, although not strongly required, since we only want to verify authenticity of the data.
Indy-based revocation seems not really necessary and would add complexity for holder/supplier and customer/verifier, because to gain value the customer/verifier would need to request a proof of non-revocation on a regular basis or whenever the information is needed.
Indy/Aries does not provide any functionality concerning validity period check or refreshing. We'd need to handle this on the application/business level.