Principals and Blessings
Wherein Alice and her friend Bob take the stage to demonstrate inter-principal communication.
Prerequisites:
All tutorials require Vanadium installation, and must run in a bash shell.
Further, please download this script then source it:
source ~/Downloads/scenario-b-setup.sh
This command wipes tutorial files and defines shell environment variables. If you start a new terminal, and just want to re-establish the environment, see instructions here.
Principals
A principal in the Vanadium framework is simply a public and private key pair. It has a set of human-readable names bound to it using public-key certificate chains, called blessings. All Vanadium processes act on behalf of a principal and are authorized by other processes based on the blessing names bound to the principal.
For example a principal Alice may have the blessings alice
and
bob:houseguest
bound to it. A process running on behalf of Alice
may authenticate to others as either alice
or bob:houseguest
or both.
A principal and the set of blessings bound to it, are together referred to as credentials. The basics tutorial demonstrated that a client and server can talk to each other if they run with the same credentials.
To reiterate this, create two principals Alice and Bob with blessings
alice
and bob
bound to them respectively:
$V_BIN/principal create --with-passphrase=false --overwrite $V_TUT/cred/alice alice
$V_BIN/principal create --with-passphrase=false --overwrite $V_TUT/cred/bob bob
Run the server with Alice's credentials (i.e, authenticate as alice
):
kill_tut_process TUT_PID_SERVER
$V_TUT/bin/server \
--v23.credentials $V_TUT/cred/alice \
--endpoint-file-name $V_TUT/server.txt &
TUT_PID_SERVER=$!
then make a request as Alice:
$V_TUT/bin/client \
--v23.credentials $V_TUT/cred/alice \
--server `cat $V_TUT/server.txt`
then make a request as Bob (it should fail):
$V_TUT/bin/client \
--v23.credentials $V_TUT/cred/bob \
--server `cat $V_TUT/server.txt`
The reason the request from Alice succeeds and that from Bob fails is because of the Default Authorization Policy used by the server.
Default authorization policy
In the absence of any explicit indications by the developer, Vanadium services use the following default policy:
Servers authorize clients if the client's blessings are an extension of the server's, or the server's blessings are an extension of the client's.
For example, a server that presents the blessing alice:hometv
to
clients will authorize only clients that present either alice
, or alice:hometv
,
or alice:hometv:app
, etc. to the server.
In the sample run above, Alice the server recognizes Alice the client as herself (same principal and blessing), and therefore grants access under the default authorization policy.
Under the same policy, Alice's server rejects Bob's request, as neither alice
nor bob
is an extension of the other.
Blessings
Per the default authorization policy, Bob's request to Alice's server would
succeed if he had a blessing of the form alice:<something>
. Such a blessing
can be created by Alice by blessing Bob.
A principal can bless another principal by extending a subset
of its own blessings and create a blessing for the other principal.
This operation can be carried out by the principal
command:
$V_BIN/principal bless \
--v23.credentials $V_TUT/cred/alice \
--for=24h $V_TUT/cred/bob friend:bob | \
$V_BIN/principal \
--v23.credentials $V_TUT/cred/bob \
set forpeer - alice
In the first invocation of principal
, Alice creates a blessing for Bob
named alice:friend:bob
. A blessing can carry an expiry time (along with
other restrictions, explained in subsequent tutorials) after which it is
no longer valid.
The second invocation takes that blessing off the pipe and stores it for later use by Bob when talking to Alice's server.
Alice and Bob would typically be on different devices.
A blessing does not contain any private keys and is useful only to the one blessed, so it could be transferred via email without compromising its purpose.
Blessings are transferred via pipes in this tutorial for educational brevity. Later tutorials will show (with more coding details) how a blessing can directly accompany the request that the blessing authorizes.
Because Bob has stored the new blessing with his credentials, the same request from Bob that previously failed now succeeds:
$V_TUT/bin/client \
--v23.credentials $V_TUT/cred/bob \
--server `cat $V_TUT/server.txt`
We're done with the server now.
kill_tut_process TUT_PID_SERVER
Steps to authentication
In Vanadium, a remote procedure call is a multi-step process authentication based on blessings:
The client knocks on the door with an initial, ping-like request that reveals little to the not-yet trusted server.
The server responds with one or more blessings - the server is saying who it is. A blessing is an identity.
Above, the server sends its blessing
alice
. This allows the client to establish the server's identity before revealing any further information about the client's intent.Based on the received blessings, the client choses which (if any) of its blessings to reveal to the server, and sends them along with its service request.
Above, Bob's client sent back two blessings:
bob
andalice:friend:bob
. The former is always sent, and the latter is sent to any server identifying itself asalice
.If the server authorizes the request for the given blessings, it executes the service call and returns results.
Above, the blessing
alice:friend:bob
(originally generated by alice and stored by bob) has authorization, so Bob gets his fortune.
Summary
Alice and Bob have been established as principals.
Alice ran a server, which Bob couldn't talk to. Without changing anything about the runner server, Alice blessed Bob and Bob could talk to Alice's server.
The default authorization policy lets anyone that Alice blesses talk to her without restriction.
The
principal
program reports credentials dataprincipal dump
summarizes credentials.principal get
drills into credential details.principal dumpblessings
reports the detailed certificate chains that comprise blessings.
Appendix: Reporting credentials
Feel free to skim this, and refer back to it from later tutorials as the need arises.
This section reviews commands that display data from a principal's
credentials. The principal
subcommands shown here are handy to use
in all subsequent tutorials.
Alice
The dump
command summarizes a principal's credentials:
$V_BIN/principal \
--v23.credentials $V_TUT/cred/alice \
dump
This results in something like:
Public key : 0a:e3:61:0e:3e:ec:9c:ce:ed:04:c1:c6:58:78:28:a8
---------------- BlessingStore ----------------
Default blessings: alice
Peer pattern : Blessings
... : alice
---------------- BlessingRoots ----------------
Public key : Pattern
0a:e3:61:0e:3e:ec:9c:ce:ed:04:c1:c6:58:78:28:a8 : [alice]
This output and its individual components are described below.
Public key
The Public key
line shows the public half of Alice's public/private
key pair. Isolate it as follows:
$V_BIN/principal \
--v23.credentials $V_TUT/cred/alice \
get publickey --pretty
Blessings presented as server
The Default blessings
line shows the blessings that the principal
will use when it acts as a server responding to a client.
These blessings will be revealed to all clients of the server, regardless of the blessings presented by the client.
There can be more than one blessing; a principal can play multiple roles - phone, music player, email client, etc.
Examine them as follows:
$V_BIN/principal \
--v23.credentials $V_TUT/cred/alice \
get default -names
Blessings presented as a client
Below the headings Peer pattern | Blessings
are the blessings used
when the principal acts as a client, sending its credentials to a
server.
This is a peer map. The client takes the blessing that came from the server, matches it to patterns on the left, and responds to the server using the blessings on the right.
Examine the map as follows:
$V_BIN/principal \
--v23.credentials $V_TUT/cred/alice \
get peermap
The pattern ...
matches on all servers, so the name alice
(the
name associated with her self-blessing) is provided to all servers.
Recognized roots
The BlessingRoots
section displays all
root public keys recognized by this principal. The
blessing name patterns following a given public key are trusted if
they are presented by a principal with the given key.
Report just the recognized roots with:
$V_BIN/principal \
--v23.credentials $V_TUT/cred/alice \
get recognizedroots
There's only one key here because currently alice
only recognizes
herself.
Bob
The situation for Bob is slightly different:
$V_BIN/principal \
--v23.credentials $V_TUT/cred/bob \
dump
Example output:
Public key : 8e:03:13:7b:f1:57:28:11:87:f0:e8:90:3b:5c:5f:fe
---------------- BlessingStore ----------------
Default blessings: bob
Peer pattern : Blessings
... : bob
alice : alice:friend:bob
---------------- BlessingRoots ----------------
Public key : Pattern
0a:e3:61:0e:3e:ec:9c:ce:ed:04:c1:c6:58:78:28:a8 : [alice]
8e:03:13:7b:f1:57:28:11:87:f0:e8:90:3b:5c:5f:fe : [bob]
Public key
Critically, Bob has a different public key from Alice:
keyAlice=`$V_BIN/principal \
--v23.credentials $V_TUT/cred/alice \
get publickey --pretty`
keyBob=`$V_BIN/principal \
--v23.credentials $V_TUT/cred/bob \
get publickey --pretty`
echo -e "alice $keyAlice\n bob $keyBob"
Blessings presented as server
Bob will report himself to clients as bob
:
$V_BIN/principal \
--v23.credentials $V_TUT/cred/bob \
get default -names
Blessings presented as a client
Bob's peer map shows that he has stored a blessing alice:friend:bob
that is sent only to servers that have identified themselves as
alice
.
$V_BIN/principal \
--v23.credentials $V_TUT/cred/bob \
get peermap
Bob also sends his self-blessing bob
to everyone.
Recognized roots
Bob, as a side effect of accepting a blessing from Alice, remembers
Alice's public key and will trust a principal claiming to be
alice
only if it presents that public key.
$V_BIN/principal \
--v23.credentials $V_TUT/cred/bob \
get recognizedroots
On the other hand, Alice's principal at this point has no record of Bob's public key. Her server honors Bob's request because Bob presents a blessing rooted at her own public key.
Blessing details
The following command extracts the blessings Bob should use with Alice and prints them in detail:
$V_BIN/principal \
--v23.credentials $V_TUT/cred/bob \
get forpeer alice | \
$V_BIN/principal dumpblessings -
Example output:
Blessings : bob#alice:friend:bob
PublicKey : 8e:03:13:7b:f1:57:28:11:87:f0:e8:90:3b:5c:5f:fe
Certificate chains : 2
Chain #0 (1 certificates). Root certificate public key: 8e:03:13:7b:f1:57:28:11:87:f0:e8:90:3b:5c:5f:fe
Certificate #0: bob with 0 caveats
Chain #1 (2 certificates). Root certificate public key: 0a:e3:61:0e:3e:ec:9c:ce:ed:04:c1:c6:58:78:28:a8
Certificate #0: alice with 0 caveats
Certificate #1: friend:bob with 1 caveat
(0) security.unixTimeExpiryCaveat(1419279349 = 2014-12-22 12:15:49 -0800 PST)
Alice's public key is at the root of a
certificiate chain corresponding to the blessing
alice:friend:bob
.
Names
From the dumpblessings
output, isolate
blessing names (the names presented to a server) with
$V_BIN/principal \
--v23.credentials $V_TUT/cred/bob \
get forpeer -names alice
This shows that Bob will present bob
and alice:friend:bob
.
Root keys
Examine root keys with
$V_BIN/principal \
--v23.credentials $V_TUT/cred/bob \
get forpeer -rootkey=alice:friend:bob alice
That command answers the question
Find the blessings
bob
will present toalice
, and among them find the blessing namedalice:friend:bob
and report the public key of the principal it came from.
In this case, the output should match Alice's public key:
echo $keyAlice
Caveats
Examine caveats with
$V_BIN/principal \
--v23.credentials $V_TUT/cred/bob \
get forpeer -caveats=alice:friend:bob alice
That command answers the question
Find the blessings
bob
will present toalice
, and among them find the blessing namedalice:friend:bob
and report its caveats.
This shows that Bob's blessing from Alice will expire in about 24h.
That expiration was set using the --for
flag in the bless
command
above.
Caveats will be discussed in more depth in the caveats tutorial.