Skip to content

Commit 5dcd287

Browse files
committed
Improved documentation regarding TAA and Fully-Qualified support
Signed-off-by: artem.ivanov <[email protected]>
1 parent 90ca178 commit 5dcd287

File tree

15 files changed

+344
-31
lines changed

15 files changed

+344
-31
lines changed

docs/configuration.md

+10-19
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ This document contains information on how Indy-SDK components can be configured.
1414
* [Error Handling](#error-handling)
1515
* [Runtime](#runtime)
1616
* [Transaction Endorser](#eransaction-endorser)
17+
* [Transaction Author Agreement](#transaction-author-agreement)
18+
* [Fully-Qualified Identifiers](#fully-qualified-Identifiers)
19+
1720
* [Indy-CLI](#indy-cLI)
1821
* [Options](#options)
1922
* [Config](#config)
@@ -160,6 +163,12 @@ Instead, I will have a relationship with an endorser who will endorse my transac
160163
1. Transaction author sends the request to the Endorser (out of scope).
161164
1. Transaction Endorser signs the request (as of now `indy_multi_sign_request` must be called, not `indy_sign_request`) and submits it to the ledger.
162165
166+
#### Transaction Author Agreement
167+
See [document](./how-tos/transaction-author-agreement.md)
168+
169+
#### Fully-Qualified Identifiers
170+
See [document](./how-tos/fully-qualified-did-support.md)
171+
163172
## Indy-CLI
164173
There is a Command Line Interface (CLI) built over Libindy which provides a set of commands to:
165174
* Manage wallets
@@ -213,22 +222,4 @@ An example of a batch script:
213222
```
214223
215224
#### Transaction Author Agreement
216-
CLI uses session-based approach to work with Transaction Author Agreement.
217-
218-
##### TAA acceptance Workflow
219-
1. On CLI start: Pass a config JSON file containing a label of mechanism how a user is going to accept a transaction author agreement.
220-
`indy-cli --config <path-to-config-json-file>` where config looks like:
221-
```
222-
{
223-
"taaAcceptanceMechanism": "Click Agreement",
224-
.....
225-
}
226-
```
227-
The list of available acceptance mechanisms can be received by sending `get_acceptance_mechanisms` request to ledger.
228-
1. On `pool connect` command execution: User will be asked if he would like to accept TAA.
229-
User either can accept it or skip and accept it later by `pool show-taa` command.
230-
231-
Note that accepting TAA one time on `pool connect` or `pool show-taa` is a CLI-specific behavior that actually caches value for future uses.
232-
Actual TAA check will be performed on write requests sending only.
233-
234-
1. On write request sending to Ledger: TAA will be appended to requests.
225+
See [document](./how-tos/transaction-author-agreement.md)
+162
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
## Fully-Qualified identifiers
2+
3+
General format of fully-qualified identifier is `<prefix>:<method>:<value>`.
4+
* Prefix: specifies entity type:
5+
* `did` - DID
6+
* `schema` - Schema Id
7+
* `creddef` - Credential Definition Id
8+
* `revreg` - Revocation registry Id
9+
* Method: specifies the network this entity belongs to.
10+
* Value: the main part of identifier.
11+
12+
### Libindy
13+
14+
##### Creation
15+
16+
* use `indy_create_and_store_my_did` function with specifying of `method_name` field inside `did_info` parameter to create fully qualified DID.
17+
```
18+
(did, verkey) = indy_create_and_store_my_did(..., '{"method_name": "indy"}')
19+
```
20+
21+
* use `indy_qualify_did` function to update DID stored in the wallet to make it fully qualified, or to do other DID maintenance.
22+
This functions also updates all DID related entities stored in the wallet to point on new identifier.
23+
```
24+
fully_qualified_did = indy_qualify_did(did)
25+
```
26+
27+
Every time you use fully-qualified DID to create a dependent entity like `Schema`, `Credential Definition` or `Revocation Registry Definition` they will have fully qualified form also.
28+
29+
#### Anoncreds workflow
30+
31+
As we have released Fully-Qualified identifiers, we can work with both identifier formats in a compatible way.
32+
There are some cases when Fully-Qualified entity must be converted to Unqualified form.
33+
You can use `indy_to_unqualified` function for these cases.
34+
35+
This function can accept the following entities:
36+
* DID
37+
* SchemaId
38+
* CredentialDefinitionId
39+
* RevocationRegistryId
40+
* Schema
41+
* CredentialDefinition
42+
* RevocationRegistryDefinition
43+
* CredentialOffer
44+
* CredentialRequest
45+
* ProofRequest
46+
47+
Examples:
48+
* DID:
49+
```
50+
indy_to_unqualified("did:sov:NcYxiDXkpYi6ov5FcYDi1e") == "NcYxiDXkpYi6ov5FcYDi1e"
51+
```
52+
* SchemaId:
53+
```
54+
indy
55+
```
56+
* CredentialDefinitionId:
57+
```
58+
indy_to_unqualified("creddef:sov:did:sov:NcYxiDXkpYi6ov5FcYDi1e:3:CL:schema:sov:did:sov:NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0:tag") == "NcYxiDXkpYi6ov5FcYDi1e:3:CL:NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0:tag"
59+
```
60+
61+
62+
Let's consider Credential Issuance and Proof Presentation for different cases.
63+
64+
* FQ - fully-qualified
65+
* U - unqualified
66+
67+
##### Credential Issuance
68+
69+
* Issuer (FQ) - Holder (U)
70+
* Issuer creates DID in the fully qualified way.
71+
Schema and CredentialDefinition created based on this DID will be fully-qualified also.
72+
There are two cases here:
73+
* Issuer use Ledger to publish related transactions - these entities will be unqualified automatically. So, Prover and Verifier will get unqualified form from the Ledger.
74+
* Issuer don't use Ledger - he must call `indy_to_unqualified` with `cred_offer_json` to get unqualified form.
75+
76+
* Issuer creates Credential Offer for Holder using fully-qualified Credential Definition Id.
77+
The next step Issuer must call `indy_to_unqualified` with `cred_offer_json` to get unqualified form of Credential Offer.
78+
Issuer must send this unqualified form to Holder and must use it later on credential creation.
79+
80+
* The next steps from Issuer and Holder do as usual.
81+
Credential will contain unqualified identifiers.
82+
Holder can make unqualified Proofs.
83+
84+
* Issuer (FQ) - Holder (FQ)
85+
* All steps Issuer and Holder do as usual.
86+
All identifiers will be in fully-qualified form.
87+
Credential will contain fully-qualified identifiers.
88+
Holder can make as unqualified as fully-qualified Proofs depend on Proof Request.
89+
90+
* Issuer (U) - Holder (U)
91+
* All steps Issuer and Holder do as usual.
92+
All identifiers will be in unqualified form.
93+
Credential will contain unqualified identifiers.
94+
Holder can make unqualified Proofs.
95+
96+
* Issuer (U) - Holder (FQ)
97+
* All steps Issuer and Holder do as usual.
98+
Holder can handle unqualified identifiers as well.
99+
All identifiers will be in unqualified form.
100+
Credential will contain unqualified identifiers.
101+
Holder can make unqualified Proofs.
102+
103+
##### Proof Presentation
104+
105+
Proof Requests supports versioning (`ver` field).
106+
This field specifies whether proof must be full qualified or not.
107+
This also specifies whether proof request restrictions are full qualified or not:
108+
- omit or set "1.0" to use unqualified identifiers.
109+
- set "2.0" to use fully qualified identifiers.
110+
111+
* All steps Issuer and Holder do as usual.
112+
113+
114+
115+
* Verifier (FQ) - Prover (U)
116+
* Verifier should set `ver` field as '1.0' or omit it on Proof Request.
117+
* if restrictions are fully-qualified Verifier must call `indy_to_unqualified` function with `proof_request_json` to get unqualified form.
118+
* if there are no restrictions or they are in unqualified form -- no additional steps are needed.
119+
120+
* There are no changes from Prover side on Proof preparation.
121+
122+
* Verifier -- proof verification -- must use *_id's (`schema_id`, `cred_def_id`, `rev_reg_id`) listed in `proof[identifiers]` as the keys for corresponding `schemas_json`, `credential_defs_json`, `rev_reg_defs_json`, `rev_regs_json` objects.
123+
124+
* Verifier (FQ) - Prover (FQ)
125+
* Verifier can use as fully-qualified as unqualified format on ProofRequest preparation (set corresponded `ver`).
126+
- omit or set "1.0" to get unqualified Proof
127+
- "2.0" to get fully-qualified Proof
128+
129+
* There are no changes from Prover side on Proof preparation.
130+
131+
* Verifier -- proof verification -- must use *_id's (`schema_id`, `cred_def_id`, `rev_reg_id`) listed in `proof[identifiers]` as the keys for corresponding `schemas_json`, `credential_defs_json`, `rev_reg_defs_json`, `rev_regs_json` objects.
132+
133+
* Verifier (U) - Prover (FQ)
134+
* Verifier should set `ver` field as '1.0' or omit it on Proof Request preparation.
135+
136+
* There are no changes from Prover side on Proof preparation. Generated Proof will be in unqualified form.
137+
138+
* All steps Verifier and Prover do as usual.
139+
140+
* Verifier (U) - Prover (U)
141+
* All steps Verifier and Prover do as usual.
142+
All identifiers will be if unqualified form.
143+
144+
##### Ledger API limitations
145+
* You can create ledger requests with passing both Fully-Qualified and Unqualified entities. Out requests will be in unqualified form.
146+
* All Ledger API parsers return entities in unqualified form.
147+
* Cashing API return result in the same form as used ID.
148+
149+
150+
### Indy-CLI
151+
152+
##### Creation
153+
Use `did new` command with passing `method` parameter to create fully-qualified DID.
154+
155+
Example: `did new method=indy`
156+
157+
### Libvcx
158+
159+
##### Agent provisioning
160+
1. Prepare provisioning config json. Append `did_method` field to this config.
161+
2. Call `vcx_provision_agent` function with this config json. As result all generated DIDs will be in fully-qualified form.
162+
3. Credential Issuance and Proof Presentation related entities will be generated automatically based on the type of remote DID.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
## Transaction Author Agreement
2+
3+
Due to legal nuances Indy network should support flow to receive explicit confirmation from any transaction author that he accepts the following reality. The ledger is public and immutable and by writing data to the ledger the user will not be able to exercise the right to be forgotten, so no personal data should be published to the ledger. For some instances this flow may be must have, but not required for other instances at all. So this functionality should be implemented on Indy side as optional.
4+
5+
Actors and Terms:
6+
* Transaction Author (TA) - Any person who would like to write any data to the ledger
7+
* Transaction Author Agreement (TAA) - The text of agreement between network users and government
8+
* Acceptance mechanism list (AML) - Description of the ways how the user may accept TAA
9+
10+
IndySDK provides API to:
11+
* Build request for setting TAA and AML on the Ledger.
12+
* Build request for getting TAA and AML set on the Ledger.
13+
* Append TAA acceptance data to request before signing and submitting of them to the Ledger.
14+
15+
16+
### Liibndy
17+
18+
##### Trustee set up AML and TAA on the Ledger
19+
1. Set AML on the Ledger:
20+
```
21+
acceptance_mechanisms_request = build_acceptance_mechanisms_request(.., '{"example label":"example description"}', "1.0", ...)
22+
sign_and_submit_request(.., acceptance_mechanisms_request)
23+
```
24+
2. Set TAA on the Ledger:
25+
```
26+
txn_author_agreement_request = build_txn_author_agreement_request(.., "example TAA text", "1.0", ...)
27+
sign_and_submit_request(.., txn_author_agreement_request)
28+
```
29+
30+
3. Use empty text to reset TAA on the ledger.
31+
32+
Please NOTE that AML should be set first.
33+
34+
35+
##### User get AML and TAA set on the Ledger
36+
1. Get AML set on the Ledger:
37+
```
38+
get_acceptance_mechanisms_request = build_get_acceptance_mechanisms_request(.., current_timestamp, ...)
39+
response = submit_request(.., get_acceptance_mechanisms_request)
40+
aml = response["result"]["data"]["aml"]
41+
```
42+
Result data is a map where keys are AML labels and values are their descriptions.
43+
You should choose one label for future usage.
44+
45+
In our case:
46+
- AML looks: `{"example label":"example description"}`.
47+
- We will use `example label` label later to append TAA data to request.
48+
49+
2. Get TAA set on the Ledger:
50+
```
51+
get_txn_author_agreement_request = build_get_txn_author_agreement_request(..)
52+
response = submit_request(.., txn_author_agreement_request)
53+
text = response["result"]["data"]["text"] // example TAA text
54+
version = response["result"]["data"]["version"] //1.0
55+
```
56+
57+
We will use `text` and `version` later to append TAA data to request.
58+
Otherwise you can calculate `digest` as sha256 hash on concatenated strings: `version` || `text`.
59+
In our case `digest` is sha256(`1.0example TAA text`)
60+
61+
##### User send write transactions to the Ledger
62+
```
63+
nym_req = indy_build_nym_request(...)
64+
time_of_acceptance = get_current_timestamp
65+
nym_req = indy_append_txn_author_agreement_acceptance_to_request(nym_req, "example TAA text", "1.0", null, "example label", time_of_acceptance)
66+
indy_sign_and_submit_request(.., nym_req)
67+
```
68+
69+
**Note**: The flow for sending of Payment transaction is different because plugin does signing internal.
70+
You must pass TAA data as part of `extra` parameter.
71+
```
72+
extra = indy_prepare_payment_extra_with_acceptance_data(..., "example TAA text", "1.0", null, "example label", time_of_acceptance)
73+
payment_req = indy_build_payment_req(..., extra)
74+
submit_request(.., payment_req)
75+
```
76+
77+
### Indy-CLI
78+
79+
CLI uses session-based approach to work with Transaction Author Agreement.
80+
81+
##### TAA setup workflow
82+
* `ledger txn-acceptance-mechanisms` - send TAA Acceptance Mechanisms to the Ledger
83+
84+
Example: `ledger txn-acceptance-mechanisms aml={"Click Agreement":"some description"} version=1`
85+
86+
* `ledger txn-author-agreement` - send Transaction Author Agreement to the Ledger.
87+
88+
Example: `ledger txn-author-agreement text="Indy transaction agreement" version=1`
89+
90+
##### TAA acceptance workflow
91+
1. On CLI start: Pass a config JSON file containing a label of mechanism how a user is going to accept a transaction author agreement.
92+
`indy-cli --config <path-to-config-json-file>` where config looks like:
93+
```
94+
{
95+
"taaAcceptanceMechanism": "Click Agreement",
96+
.....
97+
}
98+
```
99+
The list of available acceptance mechanisms can be received by sending `get_acceptance_mechanisms` request to ledger.
100+
1. On `pool connect` command execution: User will be asked if he would like to accept TAA.
101+
User either can accept it or skip and accept it later by `pool show-taa` command.
102+
103+
Note that accepting TAA one time on `pool connect` or `pool show-taa` is a CLI-specific behavior that actually caches value for future uses.
104+
Actual TAA check will be performed on write requests sending only.
105+
106+
1. On write request sending to Ledger: TAA will be appended to requests.
107+
108+
### Libvcx
109+
110+
VCX stores TAA data into internal settings which defines library behaviour and use it write transaction sending.
111+
112+
There are two ways of setting TAA:
113+
114+
1. using `vcx_init_with_config` function.
115+
This function is some kind of entry point which initializes library.
116+
It accepts `config` as a parameter, does it processing and stores some values into the internal state for future needs.
117+
So, you can append the TAA data to this config:
118+
```
119+
{
120+
....,
121+
"author_agreement": "{
122+
\"taaDigest\": \"string\",
123+
\"acceptanceMechanismType\":\ "string\",
124+
\"timeOfAcceptance\": u64}"
125+
},
126+
...
127+
}
128+
```
129+
This TAA data will be used for sending write transactions to Ledger.
130+
You either can specify `taaDigest` or combination of `text: "string"` and `version: "string"` fields.
131+
132+
Please NOTE that vcx config values must be represented as strings.
133+
134+
2. using `vcx_set_active_txn_author_agreement_meta` function at any time after initialization
135+
This function set transaction author agreement data as active (or change) which will be used for sending write transactions to Ledger.
136+
137+
138+
Use `vcx_get_ledger_author_agreement` function to get author agreement and acceptance mechanisms set on the Ledger.

libindy/include/indy_ledger.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -1226,7 +1226,9 @@ extern "C" {
12261226
/// text and version - (optional) raw data about TAA from ledger.
12271227
/// These parameters should be passed together.
12281228
/// These parameters are required if taa_digest parameter is omitted.
1229-
/// taa_digest - (optional) hash on text and version. This parameter is required if text and version parameters are omitted.
1229+
/// taa_digest - (optional) digest on text and version.
1230+
/// Digest is sha256 hash calculated on concatenated strings: version || text.
1231+
/// This parameter is required if text and version parameters are omitted.
12301232
/// mechanism - mechanism how user has accepted the TAA
12311233
/// time - UTC timestamp when user has accepted the TAA. Note that the time portion will be discarded to avoid a privacy risk.
12321234
///

libindy/src/api/ledger.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -2191,7 +2191,9 @@ pub extern fn indy_build_get_acceptance_mechanisms_request(command_handle: Comma
21912191
/// text and version - (optional) raw data about TAA from ledger.
21922192
/// These parameters should be passed together.
21932193
/// These parameters are required if taa_digest parameter is omitted.
2194-
/// taa_digest - (optional) digest on text and version. This parameter is required if text and version parameters are omitted.
2194+
/// taa_digest - (optional) digest on text and version.
2195+
/// Digest is sha256 hash calculated on concatenated strings: version || text.
2196+
/// This parameter is required if text and version parameters are omitted.
21952197
/// mechanism - mechanism how user has accepted the TAA
21962198
/// time - UTC timestamp when user has accepted the TAA. Note that the time portion will be discarded to avoid a privacy risk.
21972199
/// cb: Callback that takes command result as parameter.

libindy/src/api/payments.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -897,7 +897,9 @@ pub extern fn indy_parse_payment_response(command_handle: CommandHandle,
897897
/// text and version - (optional) raw data about TAA from ledger.
898898
/// These parameters should be passed together.
899899
/// These parameters are required if taa_digest parameter is omitted.
900-
/// taa_digest - (optional) digest on text and version. This parameter is required if text and version parameters are omitted.
900+
/// taa_digest - (optional) digest on text and version.
901+
/// Digest is sha256 hash calculated on concatenated strings: version || text.
902+
/// This parameter is required if text and version parameters are omitted.
901903
/// mechanism - mechanism how user has accepted the TAA
902904
/// time - UTC timestamp when user has accepted the TAA
903905
/// cb: Callback that takes command result as parameter.

wrappers/ios/libindy-pod/Indy/Wrapper/IndyLedger.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -804,7 +804,9 @@
804804
@param version (Optional) version of TAA from ledger.
805805
text and version should be passed together.
806806
text and version are required if taaDigest parameter is omitted.
807-
@param taaDigest (Optional) hash on text and version. This parameter is required if text and version parameters are omitted.
807+
@param taaDigest (Optional) digest on text and version.
808+
Digest is sha256 hash calculated on concatenated strings: version || text.
809+
This parameter is required if text and version parameters are omitted.
808810
@param accMechType mechanism how user has accepted the TAA
809811
@param timeOfAcceptance UTC timestamp when user has accepted the TAA. Note that the time portion will be discarded to avoid a privacy risk.
810812

0 commit comments

Comments
 (0)