2. An Example

The script example.py in the scripts directory shows how you could use Pisces to perform access control on an object. The example is a bank account object, with methods deposit, withdraw, checkBalance, and setBalance.

The example scenario involves several different keyholders. This scenario isn't meant to be an exact model of the real world or a suggestion for how to model a bank's trust relationships; rather, it demonstrates the various ways in which keys and certificates can be used. The Pisces distribution contains keys and certificates in the test/example directory. The text below explains the commands used to create them.

The bank has a key that is on the access control list for bank accounts; it is also used to delegate permission to bank employees and account holders. The bank grant the following permissions to keyholders:

The auditor has permission to check the balance of the account. The adjuster has permission to set the balance of the account. The account holder has permission to check the balance of the account and deposit and withdraw money.

The account holder delegates her permissions to these keyholders:

The spouse has all the permissions that the account holder has. The employer has permissions to deposit money.

The permissions are represent as a SPKI tag set.

The following commands show how to create each of the keys described above. We start by creating a default key. The other keys will each be issued with names relative to the default key. Also note that the --unsafe argument is used.

spkitool.py -d ../test/example create -b 512 --unsafe --default
spkitool.py -d ../test/example create -b 512 --unsafe bank
spkitool.py -d ../test/example create -b 512 --unsafe auditor
spkitool.py -d ../test/example create -b 512 --unsafe adjuster
spkitool.py -d ../test/example create -b 512 --unsafe account_holder
spkitool.py -d ../test/example create -b 512 --unsafe spouse        
spkitool.py -d ../test/example create -b 512 --unsafe employer

Now that all the keys are created, the list command will show the hashes for each of them.

spkitool.py -d ../test/example list             
PRIVATE KEYS
(hash md5 |kcMoJXXqOptLRRZfy4iWqA==|) default
(hash md5 |j5r4iybdTiCY5W/OEMVykQ==|)
(hash md5 |C7ZoGtjRIpwpiMj3CrwFBw==|)
(hash md5 |+39QQ2EKpFCcJvM3X3W2tA==|)
(hash md5 |1NECGruVdAzXN5cpsH0Bdw==|)
(hash md5 |I5kaokdnKniSiXLoUh2y/A==|)
(hash md5 |UUWuzINnGXAxIl4H1OLFpw==|)

NAMES
Names issued by key (hash md5 |kcMoJXXqOptLRRZfy4iWqA==|)
"auditor": (hash md5 |j5r4iybdTiCY5W/OEMVykQ==|)
"employer": (hash md5 |+39QQ2EKpFCcJvM3X3W2tA==|)
"adjuster": (hash md5 |1NECGruVdAzXN5cpsH0Bdw==|)
"bank": (hash md5 |I5kaokdnKniSiXLoUh2y/A==|)
"spouse": (hash md5 |UUWuzINnGXAxIl4H1OLFpw==|)
"account_holder": (hash md5 |C7ZoGtjRIpwpiMj3CrwFBw==|)

PUBLIC KEYS
(hash md5 |j5r4iybdTiCY5W/OEMVykQ==|)
(hash md5 |kcMoJXXqOptLRRZfy4iWqA==|)
(hash md5 |C7ZoGtjRIpwpiMj3CrwFBw==|)
(hash md5 |+39QQ2EKpFCcJvM3X3W2tA==|)
(hash md5 |1NECGruVdAzXN5cpsH0Bdw==|)
(hash md5 |I5kaokdnKniSiXLoUh2y/A==|)
(hash md5 |UUWuzINnGXAxIl4H1OLFpw==|)

Now we need to create a collection of certificates that authorize the keyholders to act on the bank account. We'll start with the access control list for the account:

spkitool.py -d ../test/example acl --subject bank -p '(*)' --db \
    ../test/example/acl

The access control list, which is newly created, looks like this:

debugdb.py ../test/example/acl 
../test/example/acl
(entry 
   (hash md5 |I5kaokdnKniSiXLoUh2y/A==|)
   (tag 
      (*)))

spkitool.py -d ../test/example cert --issuer bank --subject auditor \
    --after now --permission '(* set checkBalance)' 
spkitool.py -d ../test/example cert --issuer bank --subject adjuster \
    --after now --permission '(* set setBalance)' 
spkitool.py -d ../test/example cert --issuer bank --subject account_holder \
    --after now --before 2002-04-01_00:00:00 \
    --permission '(* set checkBalance deposit withdraw)' 
spkitool.py -d ../test/example cert --issuer account_holder \
    --subject spouse --after now --permission '(*)' 
spkitool.py -d ../test/example cert --issuer account_holder \
    --subject employer --after now --permission '(* set deposit)'

Now all the permissions should be in place. The test/example directory contains a pickled bank account object in account.pyp. The example.py script has rather complicated calling conventions. There is a lot of state necessary for checking permissions - the ACL, the certs and keys, and the key of the caller; each of these items is passed on the command line. The principal making the caller is specified with the -p name option and the method being invoked is specified with the -m method_name option.

python example.py -d ../test/example -o ../test/example/account.pyp \
    -a ../test/example/acl -k ../test/example/keys \
    -p account_holder -m checkBalance
python example.py -d ../test/example -o ../test/example/account.pyp \
    -a ../test/example/acl -k ../test/example/keys \
    -p adjuster -m checkBalance
python example.py -d ../test/example -o ../test/example/account.pyp \
    -a ../test/example/acl -k ../test/example/keys \
    -p employer -m deposit 100