issuer
, holder
, and verifier
. However, the base-technology (indylib
) haven’t been built for symmetry. Luckily we have our own protocol engine and the tools around it allow us to build SSI services as chatbots. We have implemented our own state machine engine to develop and run these chatbot machines.This post is a development story (or hands-on workshop) of how we can use an FSM chatbot to implement SSI Services to allow any SSI/DID owner to be an issuer. Let’s start with the result and see what the state machine looks like. As you can see below, it’s simple, elegant, and, most importantly, easy to reason.
Issuing Service Chatbot
As you can see from the diagram there are two main paths. One for the issuer
role
and one for the rcvr
role. But the most interesting thing is that how simple the
machine is. As said, it’s very easy to reason and understand. And that’s the one of powers
these machines. The second one comes from the computational model of FSMs in
general, we could proof that they’re correct.
Note that since our original FSM engine release we have extended our model with transient state transitions or pseudostates, but our UML renderer doesn’t highlight them yet. We’ll publish an other blog post with new features of our FSM engine later.
The Hyperledger Indy-based SSI system is implemented with a CL signature scheme for ZKPs. That system needs the concept of Credential Definition stored in its creator’s wallet. The Credential Definition has an ID, which is quite similar to DID in the Indy-based AnonCreds system. The CredDefID is public. Everyone who knows it can request proof based on it or request to present a proof based on it.
But the CredDefID brings us some problems:
There are other problems, but the rest are based on the same core problem.
We’ll solve problem number 2 by using a notary-type service. We started with one service and implemented a reference chatbot to issue credentials on behalf of a logical issuer, aka seller. We also have implemented our version of a public DID. With these two, we have solved the problem quite elegantly.
In some ways, yes, but the result isn’t more centralized than the suggested trust registries for other or similar problems in the SSI field. In a certain way, this model adds self-sovereignty because now everyone can issue, and everyone can build these issuing services for their use cases.
Before we continue, here’s a list of documents and places that are helpful when playing with these:
Note that the blog post is written from self-learning material point of view. Preferably, you should read and execute the commands it guides you to do simultaneously.
Note, for now, we assume that the reader uses the local setup of the agency. It makes it easier to follow the core agent’s real-time logs.
Even though you have probably cloned the repo. But if not, please do it now:
git clone https://github.com/findy-network/findy-agent-cli
Follow the material in the repo’s readme files or the workshop material
mentioned at the beginning to get your findy-agent-cli
CLI tool working, i.e.,
communicating with your agency.
alias cli=findy-agent-cli
source ./scripts/sa-compl.sh
Document for now on assumes that CLI tool is named to
cli
.
If you create new wallets directly with the CLI tool, make sure that auto-accept
mode is ON for the agent. The check it after the cli agent ping
works:
cli agent mode-cmd -r
Tip, if you have problems with CLI commands check your
FCLI_
prefixed envs.
The result should be AUTO_ACCEPT. Note that allocation scripts do this automatically.
Chatbots work even when auto-accept isn’t ON. They can written to make decisions to decline or acknowledge presented proofs, for example.
It would be best to have at least three wallets and their agents up and running.
Inside the findy-agent-cli
repo, you have scrpits/fullstack
directory. Let’s
name it a tool root for the rest of the documentation. For example:
export MY_ROOT=`pwd`
Follow the workshop documentation on how to allocate new agents with their wallets.
Allocate the following agents (actual commands and the script calls follow):
issuing
will be the issuing serviceseller
, will be a seller, aka logical issuerbuyer
will be a buyer.verifier
will be a verifier for the VC. (Usage is out scoped from this document.)Here’s an example of how you could
issuing
),issuing
, seller
, and buyer
where
the last is done in this phase just for testing the environment. During the
service integration (e.g. marketplace app) to the app invitation or command
to connect with cd "$MY_ROOT"
make-play-agent.sh issuing seller buyer verifier
cd play/issuing
ln -s ../../fsm/issuing-service-f-fsm.yaml
ln -s ../../fsm/issuing-service-b-fsm.yaml
open `cli bot uml issuing-service-f-fsm.yaml` # UML rendering
source ./new-schema
source ./new-cred-def
./invitation | ../seller/connect
./invitation | ../buyer/connect
Optionally store a public DID of the Issuing Service Chatbot:
export PUB_DID=$(./pub-did print)
Note! Leave this terminal open and do not enter new commands to it yet.
Note!
source ./new-cred-def
initializesFCLI_CRED_DEF_ID
environment variable. Theissuing-service-f-fsm.yaml
file references to this variable, i.e. it’s mandatory, or you could hard-code the credential definition value to yourissuing-service-f-fsm.yaml
.
A
and B
(see the workshop material on how to init
envs) to work as a seller
, leave them to be.A
and B
(see the workshop material on how to init
envs) to work as a buyer
, leave them to be.issuing
terminal and start the chatbot:cli bot start --service-fsm issuing-service-b-fsm.yaml issuing-service-f-fsm.yaml -v=1
seller
terminal A
and enter a command: cli bot read
.
This is a read-only terminal window for the chatbot’s responses.seller
terminal B
and enter cli bot chat
. This is a
write-only terminal window to send chat messages.role
buyer
terminal A
and enter cli bot read
. This is a read-only
terminal window for the chatbot’s responses.buyer
terminal B
and enter cli bot chat
. This is a write-only
terminal window to send chat messages.role
nowBuyer
’s A
terminal (cli bot read
command running); the results should be
that the credential is issued for the Buyer
.B
terminals and enter some text to move FSM instances to the start-again
state.Tip, when you started the Issuing Service Chatbot with
-v=1
you could monitor it’s state transitions in real-time.
Notes about the current implementation:
basic_message
reply, which usually starts with ACK
string. See
the YAML
file for more information. The reply messages aren’t drawn to the
sequence diagram below to keep it as simple as possible.open `cli bot uml issuing-service-f-fsm.yaml` # give correct FSM file
cd play/issuing # or where your bot is
export PUB_DID=$(./pub-did print)
PUB_DID
to your app’s configuration. It’s where Issuing Service
Chatbot can be found when needed. Note, PUB_DID
is a URL which returns a
new invitation on every load. You can treat is as a URL template:http://localhost:8080/dyn?did=8NCqkhnNjeTwMmK68DHDPx&label=<you_ad_number>
You can enter your case specific data like ad number to the label
arg.basic_message
.issuer
string as a
basic_message
to the Issuer FSM instance.basic_message
.basic_message
.sessionID
to the chatbot, i.e., joins the same session.rcvr
word to the chatbot to make explicit role
selection. (We could leave this out in some version of FSM implementation
and rely only on the order of the messages, but this allows us to understand
better and keep things open for future extensions.)receiver_arriwed
string to the Backend FSM.rcvr_arriwed
to the Issuer FSM as a
basic_message
.basic_messages
You have been blown away by how easy it is to implement these FSM-based chatbots, haven’t you? The Issuing Service is only one example of the potential of the FSM chatbots. We are excited to see what else you end up building. When doing so, please send your questions, comments, and feedback to our team. Let’s make this better—together.