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.

Alice's request to the server succeeds, but Bob's request fails

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.

Alice blesses Bob as a friend

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`

Bob's request to the server succeeds

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:

Summary

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 to alice, and among them find the blessing named alice: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 to alice, and among them find the blessing named alice: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.