Credential Exchanges

Manage credential exchanges using Aries protocols

A credential exchange, represented by AIPCredentialExchange, is an encapsulation of the cloud agent's progress in either issuing or receiving a credential over an established DIDComm connection.

Credential Exchange Roles & States

An AIPCredentialExchange has a role (known as myRole) and a state associated with it.

Role

The role indicates which role the cloud agent plays in the credential exchange protocol. The role is fixed for the lifetime of the credential exchange.

Role is either:

ISSUER or HOLDER

State

The state indicates the current state of the cloud agent in the credential exchange protocol. The state transitions over time in a forward direction and cannot transition to previous states.

State transitions to success:

OFFER -> REQUEST -> ISSUED -> DONE

PROPOSAL -> OFFER -> REQUEST -> ISSUED -> DONE

Summary

The following table provides a description of each role and each role+state combination.

Role
State
Description

ISSUER

The cloud agent is acting as the credential issuer.

PROPOSAL

The connection proposed that the cloud agent issue it a credential.

OFFER

The cloud agent sent a credential offer. If this state was preceded by PROPOSAL, then the offered credential may be based on the connection's proposal.

REQUEST

The connection requested that the cloud agent issue the offered credential.

ISSUED

The cloud agent issued the offered credential to the connection.

DONE

Terminal state for a successful credential exchange. The credential was issued.

ABANDONED

Terminal state for an unsuccessful credential exchange. The credential was not issued.

HOLDER

The cloud agent is acting as the credential holder, and the connection is acting as the credential issuer. Technically, the cloud agent only holds the credential once the credential exchange reaches the DONE state.

PROPOSAL

The cloud agent proposed that the connection issue it a credential.

OFFER

The cloud agent received a credential offer. If this state was preceded by PROPOSAL, then the offered credential may be based on the cloud agent's proposal.

REQUEST

The cloud agent requested that the connection issue the offered credential.

ISSUED

The connection issued the offered credential to the cloud agent.

DONE

Terminal state for a successful credential exchange. A Credential was created.

ABANDONED

Terminal state for an unsuccessful credential exchange. A Credential was not created.

Supported credential formats

The cloud agent supports credential exchanges for both Anoncreds Verifiable Credentials and W3C Verifiable Credentials. The credential format for the specific credential exchange is specified using the format nested object.

Offer a credential

The cloud agent creates a new AIPCredentialExchange with role ISSUER and sends a credential offer to the specified connectionId. The format input object must be filled with the details of the credential to offer.

mutation MyMutation {
  sendAipCredentialOffer(
    connectionId: "001fe530-3562-41d6-a631-3df9c7ae1f38"
    offer: {
      format: {
        # INSERT DETAILS OF THE CREDENTIAL TO OFFER
      }
      autoAcceptRequest: true
    }
  ) {
    id
    myRole
    state
    connectionId
  }
}

If instead the cloud agent receives a credential offer, a new AIPCredentialExchange is created with role HOLDER.

Anoncreds credentials

In order to offer and issue an Anoncreds credential, a credDefId must be provided. This value must reference a credential definition which is already written to the ledger.

View received credential offers

View credential exchanges in any state, with pagination and filtering options. Returns a nextToken which can be passed into the same query in order to fetch subsequent pages.

As an example, the filter options can be used to find received credential offers, even from a specific connection.

query MyQuery {
  aipCredentialExchanges(
    page: {
      nextToken: null
    }
    filter: {
      myCredExRole: HOLDER
      credExStates: [OFFER]
      connectionIds: ["001fe530-3562-41d6-a631-3df9c7ae1f38"]
    }
  ) {
    items {
      id
      myRole
      state
      messages {
        offer {
          comment
          format {
            __typename
            ... on AnoncredsCredOffer {
              credDefId
              schemaId
              attributeValues {
                name
                value
              }
            }
            ... on W3CCredNegotiation {
              credentialJson
            }
          }
        }
      }
      connectionId
    }
    nextToken
  }
}

Alternatively, view a single credential exchange, referenced by its unique ID.

query MyQuery {
  aipCredentialExchange(
    credExId: "225d12f5-f5fa-43d0-ba83-bf602f729fd6"
  ) {
    id
    myRole
    state
    connectionId
  }
}

Accept a credential offer

The cloud agent accepts the offer by requesting the offered credential from the connection. The input param credExId must match the ID of an AIPCredentialExchange which has the HOLDER role and is in the OFFER state. When the cloud agent finally receives the issued credential, the credential will be automatically stored as a new Credential.

mutation MyMutation {
  acceptAipCredentialOffer(
    credExId: "225d12f5-f5fa-43d0-ba83-bf602f729fd6"
    acceptOffer: {}
  ) {
    id
    myRole
    state
    connectionId
  }
}

Issue a credential

The cloud agent accepts a request for a credential by issuing the credential to the connection. The input param credExId must match the ID of an AIPCredentialExchange which has the ISSUER role and is in the REQUEST state.

mutation MyMutation {
  acceptAipCredentialRequest(
    credExId: "33c3cfe6-3377-44eb-a357-bce11b2f9c17"
    acceptRequest: {}
  ) {
    id
    myRole
    state
    connectionId
  }
}

Delete a credential exchange

Delete a credential exchange. If the credential exchange is not in the DONE state, then this operation will also send a "problem report" to the associated connection to inform them that the cloud agent has abandoned the credential exchange. Note that if the credential exchange has role HOLDER and is in the DONE state, the exchange will have resulted in a new Credential, which is not deleted by this operation.

mutation MyMutation {
  deleteAipCredentialExchange(
    credExId: "225d12f5-f5fa-43d0-ba83-bf602f729fd6"
  )
}

Last updated