Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(prism-agent): implement AnonCreds issuance flow #693

Merged
merged 156 commits into from
Oct 9, 2023
Merged
Show file tree
Hide file tree
Changes from 151 commits
Commits
Show all changes
156 commits
Select commit Hold shift + click to select a range
3c0b845
refactor: wallet seed model
Jul 24, 2023
16d857b
refactor: inject wallet context globally
Jul 24, 2023
21a9490
refactor: default wallet in layer
Jul 24, 2023
de77953
refactor: refactor background jobs
Jul 25, 2023
e1f4e54
refactor: isolate JdbcDIDSecretStorage
Jul 25, 2023
3ad30a0
refactor: non secret storage interface update
Jul 25, 2023
5bcdff9
refactor: jdbc non secret isolation
Jul 25, 2023
ed52954
refactor: isolate vault path
Jul 25, 2023
ff1f9ae
fix: conflicting db constraints
Jul 25, 2023
769d8e9
chore: configurable global tmp wallet
Jul 25, 2023
6e00501
feat: vault to store wallet seed
Jul 25, 2023
66fd933
fix: configurable wallet seed storage
Jul 25, 2023
835fa51
tests: fix failing tests
Jul 26, 2023
2fa69fe
[wip] fix test wallet ctx
Jul 26, 2023
ed03bb8
[wip] wallet-api test compiles
Jul 26, 2023
2fc7c17
tests: make ManagedDIDServiceSpec passes
Jul 26, 2023
d3659cd
tests: make all wallet-api tests pass
Jul 26, 2023
e17940a
fix: remove hardcoded timestamp
Jul 26, 2023
efcbb91
fix: make tests work
Jul 27, 2023
68c538e
Merge branch 'main' into feat/mt-walletapi-isolation
Aug 2, 2023
dc4a106
fix: use uuid for WalletId (#610)
Aug 2, 2023
5d50355
Merge branch 'main' into feat/mt-walletapi-isolation
Aug 3, 2023
33a58c4
chore: resolve merge conflict
Aug 7, 2023
2abf7a8
Merge branch 'main' into feat/mt-walletapi-isolation
Aug 9, 2023
ceb7827
feat(prism-agent): enable RLS for wallet-api (#621)
Aug 9, 2023
85c0bc3
test: support multi-tenant tests on wallet-api (#623)
Aug 11, 2023
8ac9e97
Merge branch 'main' into feat/mt-walletapi-isolation
Aug 15, 2023
4273d85
[WIP] feat: Did wallet mapping
mineme0110 Aug 16, 2023
5f88de8
[WIP] feat: Did wallet mapping
mineme0110 Aug 16, 2023
7405969
scalafmt error fix
mineme0110 Aug 17, 2023
cd2e598
feat(pollux): enable pollux wallet data isolation (#637)
Aug 22, 2023
982c387
Merge branch 'main' into feat/mt-walletapi-isolation
Aug 22, 2023
9bce64c
test(pollux): add tests related to pollux data isolation (#645)
Aug 24, 2023
d07507e
feat: entity api + admin authentication + api-token authentication (w…
yshyn-iohk Aug 24, 2023
17904fa
feat(connect): integrate data isolation in connect module (#647)
bvoiturier Aug 24, 2023
ffdcb5f
feat: authentication dal tests, ATL-5176. Signed-off-by: Yurii Shynbu…
yshyn-iohk Aug 24, 2023
3dbc5a9
Merge branch 'main' into feat/mt-walletapi-isolation
Aug 25, 2023
b6b41fe
feat(prism-agent): add wallet CRUD endpoint (#651)
Aug 28, 2023
9f3cd8c
Merge branch 'main' into feat/mt-walletapi-isolation
Aug 28, 2023
f79ed6e
chore: resolve merge conflict
Aug 28, 2023
905eb07
fix: make all unit tests pass
Aug 28, 2023
551e6c2
feat(prism-agent): integrate multi-tenancy (PeerDID to Wallet mapping…
bvoiturier Aug 29, 2023
7232385
Feat/mt api key auth (#659)
yshyn-iohk Aug 30, 2023
30a1ee7
fix(prism-agent): refine wallet management api (#660)
Aug 30, 2023
9e8facc
feat(prism-agent): fix db constraints with walletId (#661)
bvoiturier Aug 30, 2023
24f3c41
chore(prism-agent): fix DB records ordering on select for connect/iss…
bvoiturier Aug 30, 2023
c4d5caf
fix(prism-agent): finalize multi-tenancy behvavior (#663)
Aug 30, 2023
316af4d
feat: test api-key authentication logic. Signed-off-by: Yurii Shynbui…
yshyn-iohk Aug 31, 2023
d82750c
feat: mutli-tenancy api management endpoints. Signed-off-by: Yurii Sh…
yshyn-iohk Aug 31, 2023
5231e1a
fix(prism-agent): some fixes and refactoring (#672)
bvoiturier Aug 31, 2023
c89dead
fix: add api-key endpoints to the agent. Signed-off-by: Yurii Shynbui…
yshyn-iohk Aug 31, 2023
d19e0ee
fix(prism-agent): add foreign key on entity to wallet table (#673)
bvoiturier Aug 31, 2023
f10fc04
fix: add authentication schemes and fix health-check (#674)
yshyn-iohk Aug 31, 2023
4538c89
feat(prism-agent): support multi-tenant event notification (#688)
Sep 6, 2023
1c5058c
[WIP] feat: new IssuedCredentialFormat for anoncred
FabioPinheiro Sep 6, 2023
1025f8f
fix(prism-agent): refine default wallet and webhook configuration beh…
Sep 7, 2023
4e2473f
feat(pollux): add CredentialFormat enum and column to the issue crede…
bvoiturier Sep 7, 2023
99bfb66
feat(mercury): add JWT and AnonCreds DIDComm attachment format string
bvoiturier Sep 7, 2023
524ac61
feat(prism-agent): handle credential format in background job
bvoiturier Sep 7, 2023
28d43ef
feat(pollux): integrate new credential format concept in issuer crede…
bvoiturier Sep 7, 2023
59429d7
feat(prism-agent): set static JWT credential format in issue controll…
bvoiturier Sep 7, 2023
99f028e
feat(pollux): introduce new AnonCreds 'credential definition id' colu…
bvoiturier Sep 7, 2023
bb976e1
feat(prism-agent): handle new credential definition id DB field
bvoiturier Sep 7, 2023
bc0c11a
feat: sync with the main branch + CredentialDefinition adoption for M…
yshyn-iohk Sep 7, 2023
fccd733
chore(pollux): rename maybeSchemaId field
bvoiturier Sep 7, 2023
e9ab703
Merge branch 'feat/mt-walletapi-isolation' into feat/new-anoncred-end…
bvoiturier Sep 7, 2023
4c22079
fix(pollux): fix migration scripts
bvoiturier Sep 8, 2023
5a539cd
fix(pollux): use UUID and not String as credentialDefinitionId
bvoiturier Sep 8, 2023
b8b06f0
tests(prism-agent): fix unit tests
bvoiturier Sep 8, 2023
a19fc65
chore(pollux): disable query logger in credential JDBC repo
bvoiturier Sep 8, 2023
48b90d0
feat(prism-agent): add VC format and credDefId to REST model
bvoiturier Sep 8, 2023
d96d3e1
fix: protocol issue credential for version 3.0 (#700)
FabioPinheiro Sep 11, 2023
359d255
Make pollux compile
FabioPinheiro Sep 11, 2023
2ed2a45
Merge branch 'main' into feat/new-anoncred-endpoints
bvoiturier Sep 11, 2023
41713df
fix(pollux): post-merge fix
bvoiturier Sep 11, 2023
1b2f1f9
Merge remote-tracking branch 'origin/feat/new-anoncred-endpoints' int…
bvoiturier Sep 11, 2023
c168cb9
fix(prism-agent): fix compilation errors following mercury changes
bvoiturier Sep 12, 2023
eec8524
Fix compilation on the tests
FabioPinheiro Sep 12, 2023
50b8fac
fix(pollux): remove post-merge conflicting migration scripts
bvoiturier Sep 12, 2023
92cdc94
feat(prism-agent): make credentialFormat field optional and default t…
bvoiturier Sep 12, 2023
ae6c980
chore(prism-agent): log any defect occurring during incoming DIDComm …
bvoiturier Sep 12, 2023
488cd71
fix(mercury): map 'format' field when converting between mercury <> d…
bvoiturier Sep 12, 2023
3a37120
Cleanup; Add MissingCredentialFormat and UnsupportedCredentialFormat
FabioPinheiro Sep 12, 2023
03db288
Minor fixes and cleanup
FabioPinheiro Sep 12, 2023
30c2611
feat(prism-agent): implement AnonCreds offer reception and return for…
bvoiturier Sep 13, 2023
8cc09ed
fix(prism-agent): align tags for all credential definition endpoints
bvoiturier Sep 13, 2023
276ed1c
run scalafmt
FabioPinheiro Sep 13, 2023
ffe71f2
Add method schemaId to CredentialOffer
FabioPinheiro Sep 13, 2023
01a9a4c
Add method credDefId to CredentialOffer
FabioPinheiro Sep 13, 2023
568b606
feat(prism-agent): add an endpoint to fetch the inner AnonCreds defin…
bvoiturier Sep 13, 2023
80c60da
feat(prism-agent): make subjectId optional for AnonCreds when accepti…
bvoiturier Sep 15, 2023
6d284af
feat(prism-agent): implement VC offer acceptance and request generati…
bvoiturier Sep 15, 2023
d6595d0
feat(prism-agent): implement request acceptance and AnonCreds generat…
bvoiturier Sep 15, 2023
5d04ceb
chore(pollux): add AnonCreds lib bridge to 'process_credential' method
bvoiturier Sep 15, 2023
c3e3441
feat(pollux): implement AnonCreds reception/storage by holder + add s…
bvoiturier Sep 15, 2023
d5b1685
Merge branch 'main' into feat/new-anoncred-endpoints
bvoiturier Sep 15, 2023
1404b60
chore(prism-agent): allow docker-compose PostgreSQL port to be specif…
bvoiturier Sep 15, 2023
5c2db02
Fix bug in anoncred's LinkSecret
FabioPinheiro Sep 18, 2023
9c67765
Fix compilation warnings
FabioPinheiro Sep 18, 2023
6e1b1e5
feat(prism-agent): introduce new 'restServiceUrl' agent config param …
bvoiturier Sep 18, 2023
767ea34
fix(prism-agent): temporarily disable FK and RLS policy on peer_did_r…
bvoiturier Sep 19, 2023
ca4c3c7
chore(prism-agent): rename 'jwtCredential' field to 'credential' for …
bvoiturier Sep 19, 2023
3f93bd5
feat(prism-agent): inject 'REST_SERVICE_URL' env variable dynamically…
bvoiturier Sep 19, 2023
8768fe5
Implement CredentialFormat for the PresentationService
FabioPinheiro Sep 19, 2023
77f4c3f
feat(prism-agent): require 'issuingDID' param for JWT only
bvoiturier Sep 19, 2023
17b019a
chore(pollux): split JWT and AnonCreds offer creation logic for more …
bvoiturier Sep 19, 2023
c69dbef
Merge branch 'main' into feat/new-anoncred-endpoints
bvoiturier Sep 19, 2023
d0c3600
fix(prism-agent): handle connection not found appropriately
bvoiturier Sep 19, 2023
9098d2e
chore(pollux): rename method for clarity
bvoiturier Sep 19, 2023
59bf439
chore(pollux): get rid of code related to VC batch publication to DLT
bvoiturier Sep 19, 2023
ac47086
chore(pollux): get rid of code related to VC batch publication to DLT
bvoiturier Sep 19, 2023
318f1d6
fix(mercury): fix 'issue credential protocol' unit tests
bvoiturier Sep 20, 2023
f420142
fix(pollux): make 'schemaId' optional for JWT credential offer
bvoiturier Sep 20, 2023
5be1036
tests(prism-agent): fix issue controller unit test
bvoiturier Sep 20, 2023
dd44061
Merge branch 'main' into feat/new-anoncred-endpoints
bvoiturier Sep 20, 2023
674922f
feat(pollux): integrate new generic secret storage to store the cred…
bvoiturier Sep 20, 2023
01e064b
Revert "fix(prism-agent): temporarily disable FK and RLS policy on pe…
bvoiturier Sep 20, 2023
35138da
feat(pollux): validate AnonCreds claims against schema when creating …
bvoiturier Sep 21, 2023
088769c
feat(pollux): add JSON encoder/decoder for AnonCreds CreateRequestMet…
bvoiturier Sep 21, 2023
c8dfc93
feat(pollux): expose getCredDefId() from underlying Uniffi Credential…
bvoiturier Sep 21, 2023
b954953
feat(pollux): support AnonCreds credential request metadata storage
bvoiturier Sep 21, 2023
95d0171
feat(pollux): implement AnonCreds credential 'processing' using reque…
bvoiturier Sep 21, 2023
827a490
feat(prism-agent): temporarily inject a default link secret generated…
bvoiturier Sep 21, 2023
ab4a8a5
test(pollux): fix issue unit tests
bvoiturier Sep 22, 2023
3ed139d
chore(prism-agent): refactor background jobs and split between Connec…
bvoiturier Sep 22, 2023
bd1f311
chore(prism-agent): rename DIDPublicationBackgrounJobs to DIDStateSyn…
bvoiturier Sep 22, 2023
9a355ed
New module VC and minor buf fixes
FabioPinheiro Sep 21, 2023
d561321
Fix PresentationServiceSpec and remove some ???
FabioPinheiro Sep 25, 2023
ecc68be
Add columns for amoncred for presentation exchange
FabioPinheiro Sep 25, 2023
05796e1
chore(prism-agent): make DIDCOMM_SERVICE_URL env variable in docker-c…
bvoiturier Sep 25, 2023
17df5f2
Remove lib me.vican.jorge:dijon:0.6.0
FabioPinheiro Sep 26, 2023
dfa2f10
Run scalafmt
FabioPinheiro Sep 26, 2023
e19f257
Merge branch 'main' into feat/new-anoncred-endpoints
bvoiturier Sep 27, 2023
06ccfdb
test(castor): introduce MockDIDService and test data generation methods
bvoiturier Sep 28, 2023
b948dcc
chore(prism-agent): move business logic from background jobs to crede…
bvoiturier Sep 28, 2023
6ee46a4
Merge branch 'main' into feat/new-anoncred-endpoints
bvoiturier Sep 29, 2023
2a244cb
fix: generified generic secret storage (#741)
CryptoKnightIOG Sep 29, 2023
8f72616
chore(pollux): move CredentialDefinitionId URL creation logic from se…
bvoiturier Oct 2, 2023
7f1943c
Merge branch 'main' into feat/new-anoncred-endpoints
bvoiturier Oct 2, 2023
ffe7982
fix(prism-agent): align request's credentialFormat field between issu…
bvoiturier Oct 3, 2023
6c8e017
Merge branch 'main' into feat/new-anoncred-endpoints
bvoiturier Oct 3, 2023
aa34c4c
feat: store link secret (#744)
CryptoKnightIOG Oct 3, 2023
1a3540d
chore(pollux): add unit tests utility methods
bvoiturier Oct 3, 2023
43046e4
test(pollux): clean-up
bvoiturier Oct 4, 2023
b041671
test(pollux): test the complete AnonCreds issuance flow
bvoiturier Oct 4, 2023
e6f3751
test(prism-agent): declare 'credentialFormat' field in e2e tests
bvoiturier Oct 4, 2023
d72c2ce
test(prism-agent): fix e2e tests
bvoiturier Oct 4, 2023
0ca85f0
Update anoncreds-jvm-1.0-SNAPSHOT.jar
FabioPinheiro Oct 4, 2023
9bcf0df
Merge branch 'main' into feat/new-anoncred-endpoints
bvoiturier Oct 5, 2023
1716734
Merge branch 'main' into feat/new-anoncred-endpoints
bvoiturier Oct 5, 2023
77e1f55
docs: add AnonCreds samples to the issue tutorial + sequence diagram
bvoiturier Oct 5, 2023
8679554
test(pollux): fix PoCNewLib failing unit test
bvoiturier Oct 6, 2023
7a3d427
docs: fix URLs to credential definitions doc
bvoiturier Oct 9, 2023
0045018
infra(prism-agent): remove duplicated APISIX route declaration
bvoiturier Oct 9, 2023
d75a676
Reverte to use as the format name
FabioPinheiro Oct 9, 2023
6a744e8
docs: add credential definition docs (#748)
CryptoKnightIOG Oct 9, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 20 additions & 11 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import sbtbuildinfo.BuildInfoPlugin.autoImport.*
import org.scoverage.coveralls.Imports.CoverallsKeys.*
import sbtbuildinfo.BuildInfoPlugin.autoImport.*

inThisBuild(
Seq(
Expand Down Expand Up @@ -302,6 +302,10 @@ lazy val D_EventNotification = new {
val baseDependencies: Seq[ModuleID] = zioDependencies
}

lazy val D_Pollux_AnonCreds = new {
val baseDependencies: Seq[ModuleID] = Seq(D.zio, D.zioJson)
}

lazy val D_PrismAgent = new {

// Added here to make prism-crypto works.
Expand Down Expand Up @@ -508,6 +512,11 @@ lazy val protocolPresentProof = project
.settings(libraryDependencies += D.munitZio)
.dependsOn(models)

lazy val vc = project
.in(file("mercury/mercury-library/vc"))
.settings(name := "mercury-verifiable-credentials")
.dependsOn(protocolIssueCredential, protocolPresentProof) //TODO merge those two modules into this one

lazy val protocolTrustPing = project
.in(file("mercury/mercury-library/protocol-trust-ping"))
.settings(name := "mercury-protocol-trust-ping")
Expand Down Expand Up @@ -554,6 +563,7 @@ lazy val agent = project // maybe merge into models
protocolLogin,
protocolIssueCredential,
protocolPresentProof,
vc,
protocolConnection,
protocolReportProblem,
protocolTrustPing,
Expand Down Expand Up @@ -664,7 +674,7 @@ lazy val polluxCore = project
.dependsOn(irisClient)
.dependsOn(prismAgentWalletAPI)
.dependsOn(polluxVcJWT)
.dependsOn(protocolIssueCredential, protocolPresentProof, resolver, agentDidcommx, eventNotification, polluxAnoncreds)
.dependsOn(vc, resolver, agentDidcommx, eventNotification, polluxAnoncreds)

lazy val polluxDoobie = project
.in(file("pollux/lib/sql-doobie"))
Expand All @@ -687,20 +697,16 @@ lazy val polluxAnoncreds = project
.enablePlugins(JavaAppPackaging)
.settings(
name := "pollux-anoncreds",
Compile / unmanagedJars += baseDirectory.value / "anoncreds-java-1.0-SNAPSHOT.jar",
Compile / unmanagedJars += baseDirectory.value / "anoncreds-jvm-1.0-SNAPSHOT.jar",
Compile / unmanagedResourceDirectories ++= Seq(
baseDirectory.value / "native-lib" / "NATIVE"
),
libraryDependencies ++= D_Pollux_AnonCreds.baseDependencies
)

lazy val polluxAnoncredsTest = project
.in(file("pollux/lib/anoncredsTest"))
.settings(
libraryDependencies ++= Seq(
"org.scalatest" %% "scalatest" % "3.2.15" % Test,
("me.vican.jorge" %% "dijon" % "0.6.0" % Test).cross(CrossVersion.for3Use2_13)
),
)
.settings(libraryDependencies ++= Seq("org.scalatest" %% "scalatest" % "3.2.15" % Test))
.dependsOn(polluxAnoncreds % "compile->test")

// #####################
Expand Down Expand Up @@ -752,7 +758,9 @@ lazy val prismAgentWalletAPI = project
.settings(prismAgentConnectCommonSettings)
.settings(
name := "prism-agent-wallet-api",
libraryDependencies ++= D_PrismAgent.keyManagementDependencies ++ D_PrismAgent.postgresDependencies ++ Seq(D.zioMock)
libraryDependencies ++= D_PrismAgent.keyManagementDependencies ++ D_PrismAgent.postgresDependencies ++ Seq(
D.zioMock
)
)
.dependsOn(
agentDidcommx,
Expand Down Expand Up @@ -818,6 +826,7 @@ lazy val aggregatedProjects: Seq[ProjectReference] = Seq(
protocolRouting,
protocolIssueCredential,
protocolPresentProof,
vc,
protocolTrustPing,
resolver,
agent,
Expand All @@ -828,7 +837,7 @@ lazy val aggregatedProjects: Seq[ProjectReference] = Seq(
polluxCore,
polluxDoobie,
polluxAnoncreds,
// polluxAnoncredsTest, REMOVE THIS FOR NOW
polluxAnoncredsTest,
connectCore,
connectDoobie,
prismAgentWalletAPI,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ object ConnectionRepositorySpecSuite {

private def connectionRecord = ConnectionRecord(
UUID.randomUUID,
Instant.ofEpochSecond(Instant.now.getEpochSecond),
Instant.now,
None,
UUID.randomUUID().toString,
None,
Expand Down
Binary file modified docs/docusaurus/credentials/anoncreds-issue-flow.png
yshyn-iohk marked this conversation as resolved.
Show resolved Hide resolved
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 18 additions & 22 deletions docs/docusaurus/credentials/anoncreds-issue-flow.puml
Original file line number Diff line number Diff line change
Expand Up @@ -2,79 +2,75 @@
title Issue flow - AnonCreds

actor Holder as holder
participant VDR
participant "Holder PRISM Agent" as holderAgent
participant VDR
participant "Issuer PRISM Agent" as issuerAgent
actor Issuer as issuer

note over holderAgent, issuerAgent #aqua
It is assumed that a connection already exists between the holder and the issuer, and that they both have an existing Prism DID.
It is also assumed that AnonCreds related setup is completed (credential definition object published and holder has link secret generated).
It is assumed that a connection already exists between the holder and the issuer.
It is also assumed that the AnonCreds related setup is completed (Link Secret + Schema + Credential Definition created).
end note
|||
== Create and send credential offer ==
|||
issuer -> issuerAgent: Create new credential offer\n""POST /issue-credentials/credential-offers""\n""{connectionId, claims, <s:red>issuingDID</s>}""\n<color:green>""{schemaId, credDefId, key_correctness_proof, nonce}""</color>
note right: AnonCreds specific inputs could be \nprovided externally by the \nIssuer's App, or we can add some \nhiger level abstraction either to \nagent or manage.
issuer -> issuerAgent: Create new credential offer\n""POST /issue-credentials/credential-offers""\n""{format, connectionId, claims, credDefId}""
issuerAgent -> VDR: Fetch JSON Schema
issuerAgent -> issuerAgent: Verify provided claims against schema
issuerAgent -> issuerAgent: Create issue credential state record
issuerAgent --> issuer: Issue credential record {id, state}
note over issuerAgent: state=OfferPending
|||

== Send credential offer over DIDComm ==
|||
issuerAgent -> holderAgent: ""CredentialOffer"" message (includes domain/challenge)
issuerAgent -> holderAgent: ""CredentialOffer"" message
holderAgent -> holderAgent: Create issue credential state record
holderAgent --> issuerAgent: OK
note over holderAgent: state=OfferReceived
/ note over issuerAgent: state=OfferSent
|||

== Verify received credential offer (AC) ==
|||
holderAgent -> VDR: Retrieve Schema
holderAgent -> VDR: Retrieve Credential Definition
holderAgent -> holderAgent: Verify received credential offer
|||

== Review and accept credential offer ==
|||
holder -> holderAgent: Retrieve credential records\n""GET /issue-credentials/records""
holderAgent --> holder: record list
|||
holder -> holderAgent: Accept credential offer\n""POST /issue-credentials/records/{id}/accept-offer""\n""{subjectId=did:prism:xxx}""
note right #pink: Here the holder specifies the subject DID\nto which the credential should be issued \n**IS THIS RELEVANT TO AC???**\n(could be used as entropy/prover_did field)
holder -> holderAgent: Accept credential offer\n""POST /issue-credentials/records/{id}/accept-offer""\n""{}""
holderAgent --> holder: OK
note over holderAgent: state=RequestPending
|||

== Generate and send credential request ==
|||
holderAgent -[#red]> holderAgent: <color:red>Sign the domain/challenge received from</color>\n<color:red>the issuer with subject Prism DID</color> (**not used in AnonCreds**)
holderAgent -> holderAgent: Create credential request <color:green>(input: offer, CD, link secret, entropy/did)</color>
holderAgent -> VDR: Fetch Credential Definition
holderAgent -> holderAgent: Load Link Secret
holderAgent -> holderAgent: Create credential request (input: link secret, cred def, offer)
holderAgent -> holderAgent: Store request metadata
note over holderAgent: state=RequestGenerated
|||
holderAgent -> issuerAgent: RequestCredential message (with DID ownership proof)
holderAgent -> issuerAgent: RequestCredential message (includes blinded link secret)
issuerAgent --> holderAgent: OK
note over holderAgent: state=RequestSent
/ note over issuerAgent: state=RequestReceived
|||

== Generate and send credential ==
|||
issuerAgent -[#green]>issuerAgent: <color:green>Verify credential request</color>
alt automaticIssuance=true
issuerAgent -> issuerAgent: Automatically approve credential request
else automaticIssuance=false
issuer -> issuerAgent: Explicitly approve credential request\n""POST /issue-credentials/records/{id}/issue-credential""
end
note over issuerAgent: state=CredentialPending
|||
issuerAgent -> issuerAgent: Generate credential signed with <s:red>Issuing Prism DID and issued to Subject Prism DID</s>\n<color:green>CredDef keys and issued to the Holder's link_secret</color>
issuerAgent -> issuerAgent: Generate credential signed with credential definition keys\nand issued to the Holder's blinded link secret
note over issuerAgent: state=CredentialGenerated
|||
issuerAgent -> holderAgent: ""IssueCredential"" message (includes <s:red>JWT</s><color:green>AnonCreds</color> credential)
holderAgent -> holderAgent: Verify and store credential
issuerAgent -> holderAgent: ""IssueCredential"" message (includes AnonCreds credential)
holderAgent -> VDR: Fetch Credential Definition
holderAgent -> holderAgent: process/verify credential (input: credential, request metadata, link secret, cred def)
holderAgent -> holderAgent: Store credential
holderAgent --> issuerAgent: OK
note over issuerAgent: state=CredentialSent
/ note over holderAgent: state=CredentialReceived
Expand Down
Binary file modified docs/docusaurus/credentials/issue-flow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 6 additions & 2 deletions docs/docusaurus/credentials/issue-flow.puml
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,20 @@ title Issue flow

actor Holder as holder
participant "Holder PRISM Agent" as holderAgent
participant VDR
participant "Issuer PRISM Agent" as issuerAgent
actor Issuer as issuer

note over holderAgent, issuerAgent #aqua
It is assumed that a connection already exists between the holder and the issuer, and that they both have an existing Prism DID.
It is assumed that a connection already exists between the holder and the issuer.
It is also assumed that they both have an existing Prism DID.
end note
|||
== Create and send credential offer ==
|||
issuer -> issuerAgent: Create new credential offer\n""POST /issue-credentials/credential-offers""\n""{connectionId, claims, issuingDID}""
issuer -> issuerAgent: Create new credential offer\n""POST /issue-credentials/credential-offers""\n""{format, connectionId, claims, issuingDID, schemaId?}""
issuerAgent -> VDR: Fetch JSON Schema
issuerAgent -> issuerAgent: Verify provided claims against schema
issuerAgent -> issuerAgent: Create issue credential state record
issuerAgent --> issuer: Issue credential record {id, state}
note over issuerAgent: state=OfferPending
Expand Down
105 changes: 98 additions & 7 deletions docs/docusaurus/credentials/issue.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# Issue Credentials

In Atala PRISM, the [Issue Credentials Protocol](/docs/concepts/glossary#issue-credentials-protocol) allows you to create, retrieve, and manage issued [verifiable credentials (VCs)](/docs/concepts/glossary#verifiable-credentials) between a VC issuer and a VC holder.
Expand All @@ -16,11 +19,24 @@ The Issuer and Holder interact with the PRISM Agent API to perform the operation

Before using the Issuing Credentials protocol, the following conditions must be present:

<Tabs groupId="vc-formats">
<TabItem value="jwt" label="JWT">

1. Issuer and Holder PRISM Agents up and running
2. A connection must be established between the Issuer and Holder PRISM Agents (see [Connections](../connections/connection.md))
3. The Issuer must have a published PRISM DID, and the [DID document](/docs/concepts/glossary#did-document) must have at least one `assertionMethod` key for issuing credentials (see [Create DID](../dids/create.md) and [Publish DID](../dids/publish.md))
4. The Holder must have a PRISM DID, and the DID document must have at least one `authentication` key for presenting the proof.

</TabItem>
<TabItem value="anoncreds" label="AnonCreds">

1. Issuer and Holder PRISM Agents up and running
2. A connection must be established between the Issuer and Holder PRISM Agents (see [Connections](../connections/connection.md))
3. The Issuer must have created an AnonCreds Credential Definition as described [here](../credential-definitions/credential-definitions.md).

</TabItem>
</Tabs>

## Overview

The protocol described is a VC issuance process between two Atala PRISM Agents, the Issuer and the Holder.
Expand Down Expand Up @@ -61,18 +77,21 @@ This section describes the Issuer role's available interactions with the PRISM A
To start the process, the issuer needs to create a credential offer.
To do this, make a `POST` request to the [`/issue-credentials/credential-offers`](/agent-api/#tag/Issue-Credentials-Protocol/operation/createCredentialOffer) endpoint with a JSON payload that includes the following information:

<Tabs groupId="vc-formats">
<TabItem value="jwt" label="JWT">

1. `claims`: The data stored in a verifiable credential. Claims get expressed in a key-value format. The claims contain the data that the issuer attests to, such as name, address, date of birth, and so on.
2. `issuingDID`: The DID referring to the issuer to issue this credential from
3. `connectionId`: The unique ID of the connection between the holder and the issuer to offer this credential over.
4. `schemaId`: An optional field that, if specified, contains a valid URL to an existing VC schema.
The PRISM agent must be able to dereference the specified URL (i.e. fetch the VC schema content from it), in order to validate the provided claims against it.
When not specified, the claims fields is not validated and can be any valid JSON object.
Please refer to the [Create VC schema](../schemas/create.md) doc for details on how to create a VC schema.

:::note
4. `schemaId`: An optional field that, if specified, contains a valid URL to an existing VC schema.
The PRISM agent must be able to dereference the specified URL (i.e. fetch the VC schema content from it), in order to validate the provided claims against it.
When not specified, the claims fields is not validated and can be any valid JSON object.
Please refer to the [Create VC schema](../schemas/create.md) doc for details on how to create a VC schema.
5. `credentialFormat`: The format of the credential that will be issued - `JWT` in this case. When not specified, the default value is `JWT`.

The issuingDID and connectionId properties come from completing the pre-requisite steps of listed above

:::note
The `issuingDID` and `connectionId` properties come from completing the pre-requisite steps listed above
:::

Once the request initiates, a new credential record for the issuer gets created with a unique ID. The state of this record is now `OfferPending`.
Expand All @@ -93,12 +112,53 @@ curl -X 'POST' \
"drivingLicenseID": "12345",
"drivingClass": 3
},
"credentialFormat": "JWT",
"issuingDID": "did:prism:9f847f8bbb66c112f71d08ab39930d468ccbfe1e0e1d002be53d46c431212c26",
"connectionId": "9d075518-f97e-4f11-9d10-d7348a7a0fda",
"schemaId": "http://localhost:8080/prism-agent/schema-registry/schemas/3f86a73f-5b78-39c7-af77-0c16123fa9c2"
}'
```

</TabItem>
<TabItem value="anoncreds" label="AnonCreds">

1. `claims`: The data stored in a verifiable credential. AnonCreds claims get expressed in a flat, "string -> string", key-value pair format. The claims contain the data that the issuer attests to, such as name, address, date of birth, and so on.
2. `connectionId`: The unique ID of the connection between the holder and the issuer to offer this credential over.
3. `credentialDefinitionId`: The unique ID of the [credential definition](../credential-definitions/credential-definitions.md) that has been created by the issuer as a prerequisite. Please refer to the [Create AnonCreds Credential Definition](../credential-definitions/credential-definitions.md) doc for details on how to create a credential definition.
4. `credentialFormat`: The format of the credential that will be issued - `AnonCreds` in this case.

:::note
The `connectionId` and `credentialDefinitionId` properties come from completing the pre-requisite steps listed above
:::

Once the request initiates, a new credential record for the issuer gets created with a unique ID. The state of this record is now `OfferPending`.

```shell
# Issuer POST request to create a new credential offer
curl -X 'POST' \
'http://localhost:8080/prism-agent/issue-credentials/credential-offers' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-H "apikey: $API_KEY" \
-d '{
"claims": {
"emailAddress": "[email protected]",
"givenName": "Alice",
"familyName": "Wonderland",
"dateOfIssuance": "2020-11-13T20:20:39+00:00",
"drivingLicenseID": "12345",
"drivingClass": "3"
},
"credentialFormat": "AnonCreds",
"connectionId": "9d075518-f97e-4f11-9d10-d7348a7a0fda",
"credentialDefinitionId": "5d737816-8fe8-3492-bfe3-1b3e2b67220b"
}'
```

</TabItem>
</Tabs>


### Sending the Offer to the Holder

The next step for the Issuer is to send the offer to the holder using DIDComm.
Expand Down Expand Up @@ -165,6 +225,9 @@ curl "http://localhost:8090/prism-agent/issue-credentials/records" \

To accept the offer, the Holder can make a `POST` request to the [`/issue-credentials/records/{recordId}/accept-offer`](/agent-api/#tag/Issue-Credentials-Protocol/operation/acceptCredentialOffer) endpoint with a JSON payload that includes the following information:

<Tabs groupId="vc-formats">
<TabItem value="jwt" label="JWT">

1. `holder_record_id`: The unique identifier of the issue credential record known by the holder PRISM Agent.
2. `subjectId`: This field represents the unique identifier for the subject of the verifiable credential. It is a short-form PRISM [DID](/docs/concepts/glossary#decentralized-identifier) string, such as `did:prism:subjectIdentifier`.

Expand All @@ -179,6 +242,23 @@ curl -X POST "http://localhost:8090/prism-agent/issue-credentials/records/$holde
}'
```

</TabItem>
<TabItem value="anoncreds" labal="AnonCreds">

1. `holder_record_id`: The unique identifier of the issue credential record known by the holder PRISM Agent.

```shell
# Holder POST request to accept the credential offer
curl -X POST "http://localhost:8090/prism-agent/issue-credentials/records/$holder_record_id/accept-offer" \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-H "apikey: $API_KEY" \
-d '{}'
```

</TabItem>
</Tabs>

This request will change the state of the record to `RequestPending`.

### Receiving the VC Credential
Expand Down Expand Up @@ -206,4 +286,15 @@ stateDiagram-v2

The following diagram shows the end-to-end flow for an issuer to issue a VC to a holder.

<Tabs groupId="vc-formats">
<TabItem value="jwt" label="JWT">

![](issue-flow.png)

</TabItem>
<TabItem value="anoncreds" label="AnonCreds">

![](anoncreds-issue-flow.png)

</TabItem>
</Tabs>
Loading
Loading