veyron/security: Provide a common implementation of the BlessingStore
and BlessingRoots interfaces.

This commit moves the BlessingStore and BlessingRoots implementation
from veyron/runtimes/google/rt to veyron/security and provides
simple factory functions for creating a Principal implementation
that uses these (canonical) BlessingStore and BlessingRoots implementations.

As a result, a couple of silly BlessingStore and BlessingRoot implementations
that were used only in tests are now deleted.

Change-Id: Icb0cfe98351b82a59951e1cd1b795007de92abbd
diff --git a/runtimes/google/ipc/full_test.go b/runtimes/google/ipc/full_test.go
index b6c29e8..0997553 100644
--- a/runtimes/google/ipc/full_test.go
+++ b/runtimes/google/ipc/full_test.go
@@ -672,6 +672,8 @@
 	pserver.AddToRoots(bRandom)
 	// And the client needs to recognize the server's blessing to decide which of its own blessings to share.
 	pclient.AddToRoots(pserver.BlessingStore().Default())
+	// sectest.NewPrincipal sets up a principal that shares blessings with all servers, undo that.
+	pclient.BlessingStore().Set(nil, security.AllPrincipals)
 
 	type v []interface{}
 	type testcase struct {
diff --git a/runtimes/google/ipc/stream/sectest/sectest.go b/runtimes/google/ipc/stream/sectest/sectest.go
index 9bbf025..8740531 100644
--- a/runtimes/google/ipc/stream/sectest/sectest.go
+++ b/runtimes/google/ipc/stream/sectest/sectest.go
@@ -1,13 +1,9 @@
 // Package sectest provides test utility functions for security-related operations for tests within veyron.io/veyron/veyron/runtimes/google/ipc/stream.
-//
-// TODO(ashankar,ataly): Figure out what to do with the BlessingStore implementation and move it to
-// veyron.io/veyron/veyron2/security/sectest. In the mean time this package provides just enough hacky
-// functionality to work for unittests in veyron.io/veyron/veyron/runtimes/google/ipc/....
 package sectest
 
 import (
+	vsecurity "veyron.io/veyron/veyron/security"
 	"veyron.io/veyron/veyron2/security"
-	"veyron.io/veyron/veyron2/security/sectest"
 )
 
 // NewPrincipal creates a new security.Principal.
@@ -15,17 +11,10 @@
 // It also creates self-certified blessings for defaultBlessings and
 // sets them up as BlessingStore().Default() (if any are provided).
 func NewPrincipal(defaultBlessings ...string) security.Principal {
-	_, key, err := sectest.NewKey()
+	p, err := vsecurity.NewPrincipal()
 	if err != nil {
 		panic(err)
 	}
-	signer := security.NewInMemoryECDSASigner(key)
-	store := &blessingStore{m: make(map[string]security.Blessings), k: signer.PublicKey()}
-	p, err := security.CreatePrincipal(signer, store, sectest.NewBlessingRoots())
-	if err != nil {
-		panic(err)
-	}
-
 	var def security.Blessings
 	for _, blessing := range defaultBlessings {
 		b, err := p.BlessSelf(blessing)
@@ -40,52 +29,12 @@
 		if err := p.BlessingStore().SetDefault(def); err != nil {
 			panic(err)
 		}
+		if _, err := p.BlessingStore().Set(def, security.AllPrincipals); err != nil {
+			panic(err)
+		}
 		if err := p.AddToRoots(def); err != nil {
 			panic(err)
 		}
 	}
 	return p
 }
-
-// security.BlessingStore implementation that holds one default and can mark other
-// blessings to be shared with a specific peer.
-//
-// TODO(ashankar,ataly): Remove this and use a reference implementation from veyron/runtimes/google/rt, which
-// should move to veyron/security?
-type blessingStore struct {
-	d security.Blessings
-	m map[string]security.Blessings
-	k security.PublicKey
-}
-
-func (bs *blessingStore) Set(blessings security.Blessings, peer security.BlessingPattern) (security.Blessings, error) {
-	old := bs.m[string(peer)]
-	bs.m[string(peer)] = blessings
-	return old, nil
-}
-
-func (bs *blessingStore) ForPeer(peers ...string) security.Blessings {
-	var ret []security.Blessings
-	for _, p := range peers {
-		if b := bs.m[p]; b != nil {
-			ret = append(ret, b)
-		}
-	}
-	if len(ret) > 0 {
-		b, err := security.UnionOfBlessings(ret...)
-		if err != nil {
-			panic(err)
-		}
-		return b
-	}
-	// TODO(ashankar,ataly): This violates the contract in the BlessingStore API comments.
-	return bs.d
-}
-
-func (bs *blessingStore) SetDefault(b security.Blessings) error {
-	bs.d = b
-	return nil
-}
-
-func (bs *blessingStore) Default() security.Blessings   { return bs.d }
-func (bs *blessingStore) PublicKey() security.PublicKey { return bs.k }
diff --git a/runtimes/google/ipc/stream/vc/vc_test.go b/runtimes/google/ipc/stream/vc/vc_test.go
index 4e19629..e380374 100644
--- a/runtimes/google/ipc/stream/vc/vc_test.go
+++ b/runtimes/google/ipc/stream/vc/vc_test.go
@@ -138,6 +138,7 @@
 	if err != nil {
 		t.Fatal(err)
 	}
+	client.BlessingStore().Set(nil, security.AllPrincipals)
 	client.BlessingStore().Set(forServer1, security.BlessingPattern("server1"))
 	client.BlessingStore().Set(forServer2, security.BlessingPattern("server2"))
 
diff --git a/runtimes/google/rt/blessingroots_test.go b/runtimes/google/rt/blessingroots_test.go
deleted file mode 100644
index 53b99de..0000000
--- a/runtimes/google/rt/blessingroots_test.go
+++ /dev/null
@@ -1,119 +0,0 @@
-package rt
-
-import (
-	"crypto/ecdsa"
-	"crypto/elliptic"
-	"crypto/rand"
-	"fmt"
-	"io/ioutil"
-	"os"
-	"testing"
-
-	"veyron.io/veyron/veyron2/security"
-)
-
-type s []string
-
-type rootsTester struct {
-	k1, k2, k3 security.PublicKey
-}
-
-func (t *rootsTester) testAdd(br security.BlessingRoots) error {
-	testdata := []struct {
-		root    security.PublicKey
-		pattern security.BlessingPattern
-	}{
-		{t.k1, "veyron/..."},
-		{t.k2, "google/foo/..."},
-		{t.k1, "google"},
-	}
-	for _, d := range testdata {
-		if err := br.Add(d.root, d.pattern); err != nil {
-			return fmt.Errorf("%v.Add(%v, %q) failed: %s", br, d.root, d.pattern, err)
-		}
-	}
-	return nil
-}
-
-func (t *rootsTester) testRecognized(br security.BlessingRoots) error {
-	testdata := []struct {
-		root          security.PublicKey
-		recognized    []string
-		notRecognized []string
-	}{
-		{t.k1, s{"veyron", "veyron/foo", "veyron/foo/bar", "google"}, s{"google/foo", "foo", "foo/bar"}},
-		{t.k2, s{"google", "google/foo", "google/foo/bar"}, s{"google/bar", "veyron", "veyron/foo", "foo", "foo/bar"}},
-		{t.k3, s{}, s{"veyron", "veyron/foo", "veyron/bar", "google", "google/foo", "google/bar", "foo", "foo/bar"}},
-	}
-	for _, d := range testdata {
-		for _, b := range d.recognized {
-			if err := br.Recognized(d.root, b); err != nil {
-				return fmt.Errorf("%v.Recognized(%v, %q): got: %v, want nil", br, d.root, b, err)
-			}
-		}
-		for _, b := range d.notRecognized {
-			if err := matchesError(br.Recognized(d.root, b), "not a recognized root"); err != nil {
-				return fmt.Errorf("%v.Recognized(%v, %q): %v", br, d.root, b, err)
-			}
-		}
-	}
-	return nil
-}
-
-func mkKey() security.PublicKey {
-	s, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
-	if err != nil {
-		panic(err)
-	}
-	return security.NewECDSAPublicKey(&s.PublicKey)
-}
-
-func TestInMemoryBlessingRoots(t *testing.T) {
-	br := newInMemoryBlessingRoots()
-	rootsTester := rootsTester{mkKey(), mkKey(), mkKey()}
-	if err := rootsTester.testAdd(br); err != nil {
-		t.Error(err)
-	}
-	if err := rootsTester.testRecognized(br); err != nil {
-		t.Error(err)
-	}
-}
-
-func TestPersistingBlessingRoots(t *testing.T) {
-	newTempDir := func(name string) string {
-		dir, err := ioutil.TempDir("", name)
-		if err != nil {
-			t.Fatal(err)
-		}
-		return dir
-	}
-
-	rootsTester := rootsTester{mkKey(), mkKey(), mkKey()}
-
-	// Create a new persisting BlessingRoots and add key k1 as an authority over
-	// blessings matching "veyron/...".
-	dir := newTempDir("blessingstore")
-	defer os.RemoveAll(dir)
-	signer := newPrincipal(t)
-	br, err := newPersistingBlessingRoots(dir, signer)
-	if err != nil {
-		t.Fatalf("newPersistingBlessingRoots failed: %s", err)
-	}
-
-	if err := rootsTester.testAdd(br); err != nil {
-		t.Error(err)
-	}
-	if err := rootsTester.testRecognized(br); err != nil {
-		t.Error(err)
-	}
-
-	// Test that all mutations are appropriately reflected in a BlessingRoots
-	// constructed from same directory and signer.
-	br, err = newPersistingBlessingRoots(dir, signer)
-	if err != nil {
-		t.Fatalf("newPersistingBlessingRoots failed: %s", err)
-	}
-	if err := rootsTester.testRecognized(br); err != nil {
-		t.Error(err)
-	}
-}
diff --git a/runtimes/google/rt/blessingstore_test.go b/runtimes/google/rt/blessingstore_test.go
deleted file mode 100644
index 3e78688..0000000
--- a/runtimes/google/rt/blessingstore_test.go
+++ /dev/null
@@ -1,247 +0,0 @@
-package rt
-
-import (
-	"fmt"
-	"io/ioutil"
-	"os"
-	"reflect"
-	"testing"
-
-	"veyron.io/veyron/veyron2/security"
-)
-
-type storeTester struct {
-	t                                         *testing.T
-	bForAll, bForGoogle, bForVeyron, bDefault security.Blessings
-}
-
-func (t *storeTester) testSet(s security.BlessingStore) error {
-	var (
-		p      = newPrincipal(t.t)
-		bOther = blessSelf(t.t, p, "irrelevant")
-	)
-	testdata := []struct {
-		blessings security.Blessings
-		pattern   security.BlessingPattern
-		wantErr   string
-	}{
-		{t.bForAll, "...", ""},
-		{t.bForGoogle, "google/...", ""},
-		{t.bForVeyron, "veyron", ""},
-		{bOther, "...", "public key does not match"},
-		{t.bForAll, "", "invalid BlessingPattern"},
-		{t.bForAll, "foo...", "invalid BlessingPattern"},
-		{t.bForAll, "...foo", "invalid BlessingPattern"},
-		{t.bForAll, "foo/.../bar", "invalid BlessingPattern"},
-	}
-	for _, d := range testdata {
-		_, err := s.Set(d.blessings, d.pattern)
-		if merr := matchesError(err, d.wantErr); merr != nil {
-			return fmt.Errorf("Set(%v, %q): %v", d.blessings, p, merr)
-		}
-	}
-	return nil
-}
-
-func (t *storeTester) testSetDefault(s security.BlessingStore, currentDefault security.Blessings) error {
-	if got := s.Default(); !reflect.DeepEqual(got, currentDefault) {
-		return fmt.Errorf("Default(): got: %v, want: %v", got, currentDefault)
-	}
-	testdata := []struct {
-		blessings security.Blessings
-		wantErr   string
-	}{
-		{t.bDefault, ""},
-		{blessSelf(t.t, newPrincipal(t.t), "irrelevant"), "public key does not match"},
-	}
-	for _, d := range testdata {
-		if err := matchesError(s.SetDefault(d.blessings), d.wantErr); err != nil {
-			return fmt.Errorf("SetDefault(%v): %v", d.blessings, err)
-		}
-		if got, want := s.Default(), t.bDefault; !reflect.DeepEqual(got, want) {
-			return fmt.Errorf("Default(): got: %v, want: %v", got, want)
-		}
-	}
-	return nil
-}
-
-func (t *storeTester) testForPeer(s security.BlessingStore) error {
-	testdata := []struct {
-		peers     []string
-		blessings security.Blessings
-	}{
-		{nil, t.bForAll},
-		{[]string{"foo"}, t.bForAll},
-		{[]string{"google"}, unionOfBlessings(t.t, t.bForAll, t.bForGoogle)},
-		{[]string{"veyron"}, unionOfBlessings(t.t, t.bForAll, t.bForVeyron)},
-		{[]string{"google/foo"}, unionOfBlessings(t.t, t.bForAll, t.bForGoogle)},
-		{[]string{"veyron/baz"}, t.bForAll},
-		{[]string{"google/foo/bar"}, unionOfBlessings(t.t, t.bForAll, t.bForGoogle)},
-		{[]string{"veyron/foo", "google"}, unionOfBlessings(t.t, t.bForAll, t.bForGoogle)},
-		{[]string{"veyron", "google"}, unionOfBlessings(t.t, t.bForAll, t.bForGoogle, t.bForVeyron)},
-	}
-	for _, d := range testdata {
-		if got, want := s.ForPeer(d.peers...), d.blessings; !reflect.DeepEqual(got, want) {
-			return fmt.Errorf("ForPeer(%v): got: %v, want: %v", d.peers, got, want)
-		}
-	}
-	return nil
-}
-
-func newStoreTester(t *testing.T) (*storeTester, security.PublicKey) {
-	var (
-		// root principals
-		v      = newPrincipal(t)
-		g      = newPrincipal(t)
-		veyron = blessSelf(t, v, "veyron")
-		google = blessSelf(t, g, "google")
-
-		// test principal
-		p    = newPrincipal(t)
-		pkey = p.PublicKey()
-	)
-	s := &storeTester{
-		t:          t,
-		bForAll:    bless(t, v, pkey, veyron, "alice"),
-		bForGoogle: bless(t, g, pkey, google, "alice"),
-		bDefault:   bless(t, g, pkey, google, "aliceDefault"),
-	}
-	s.bForVeyron = unionOfBlessings(t, s.bForAll, s.bForGoogle)
-	return s, pkey
-}
-
-func TestInMemoryBlessingStore(t *testing.T) {
-	tester, pkey := newStoreTester(t)
-	s := newInMemoryBlessingStore(pkey)
-	if err := tester.testSet(s); err != nil {
-		t.Error(err)
-	}
-	if err := tester.testForPeer(s); err != nil {
-		t.Error(err)
-	}
-	if err := tester.testSetDefault(s, tester.bForAll); err != nil {
-		t.Error(err)
-	}
-}
-
-func TestPersistingBlessingStore(t *testing.T) {
-	newTempDir := func(name string) string {
-		dir, err := ioutil.TempDir("", name)
-		if err != nil {
-			t.Fatal(err)
-		}
-		return dir
-	}
-
-	tester, pkey := newStoreTester(t)
-
-	// Create a new persisting BlessingStore.
-	dir := newTempDir("blessingstore")
-	defer os.RemoveAll(dir)
-	signer := newPrincipal(t)
-	s, err := newPersistingBlessingStore(pkey, dir, signer)
-	if err != nil {
-		t.Fatalf("newPersistingBlessingStore failed: %v", err)
-	}
-
-	if err := tester.testSet(s); err != nil {
-		t.Error(err)
-	}
-	if err := tester.testForPeer(s); err != nil {
-		t.Error(err)
-	}
-	if err := tester.testSetDefault(s, tester.bForAll); err != nil {
-		t.Error(err)
-	}
-	// Test that all mutations are appropriately reflected in a BlessingStore constructed
-	// from same public key, directory and signer.
-	s, err = newPersistingBlessingStore(pkey, dir, signer)
-	if err != nil {
-		t.Fatalf("newPersistingBlessingStore failed: %v", err)
-	}
-	if err := tester.testForPeer(s); err != nil {
-		t.Error(err)
-	}
-	if got, want := s.Default(), tester.bDefault; !reflect.DeepEqual(got, want) {
-		t.Fatalf("Default(): got: %v, want: %v", got, want)
-	}
-}
-
-func TestBlessingStoreSetOverridesOldSetting(t *testing.T) {
-	var (
-		p     = newPrincipal(t)
-		alice = blessSelf(t, p, "alice")
-		bob   = blessSelf(t, p, "bob")
-		s     = newInMemoryBlessingStore(p.PublicKey())
-	)
-	// Set(alice, "alice")
-	// Set(bob, "alice/...")
-	// So, {alice, bob} is shared with "alice", whilst {bob} is shared with "alice/tv"
-	if _, err := s.Set(alice, "alice"); err != nil {
-		t.Fatal(err)
-	}
-	if _, err := s.Set(bob, "alice/..."); err != nil {
-		t.Fatal(err)
-	}
-	if got, want := s.ForPeer("alice"), unionOfBlessings(t, alice, bob); !reflect.DeepEqual(got, want) {
-		t.Errorf("Got %v, want %v", got, want)
-	}
-	if got, want := s.ForPeer("alice/friend"), bob; !reflect.DeepEqual(got, want) {
-		t.Errorf("Got %v, want %v", got, want)
-	}
-
-	// Clear out the blessing associated with "alice".
-	// Now, bob should be shared with both alice and alice/friend.
-	if _, err := s.Set(nil, "alice"); err != nil {
-		t.Fatal(err)
-	}
-	if got, want := s.ForPeer("alice"), bob; !reflect.DeepEqual(got, want) {
-		t.Errorf("Got %v, want %v", got, want)
-	}
-	if got, want := s.ForPeer("alice/friend"), bob; !reflect.DeepEqual(got, want) {
-		t.Errorf("Got %v, want %v", got, want)
-	}
-
-	// Clearing out an association that doesn't exist should have no effect.
-	if _, err := s.Set(nil, "alice/enemy"); err != nil {
-		t.Fatal(err)
-	}
-	if got, want := s.ForPeer("alice"), bob; !reflect.DeepEqual(got, want) {
-		t.Errorf("Got %v, want %v", got, want)
-	}
-	if got, want := s.ForPeer("alice/friend"), bob; !reflect.DeepEqual(got, want) {
-		t.Errorf("Got %v, want %v", got, want)
-	}
-
-	// Clear everything
-	if _, err := s.Set(nil, "alice/..."); err != nil {
-		t.Fatal(err)
-	}
-	if got := s.ForPeer("alice"); got != nil {
-		t.Errorf("Got %v, want nil", got)
-	}
-	if got := s.ForPeer("alice/friend"); got != nil {
-		t.Errorf("Got %v, want nil", got)
-	}
-}
-
-func TestBlessingStoreSetReturnsOldValue(t *testing.T) {
-	var (
-		p     = newPrincipal(t)
-		alice = blessSelf(t, p, "alice")
-		bob   = blessSelf(t, p, "bob")
-		s     = newInMemoryBlessingStore(p.PublicKey())
-	)
-	if old, err := s.Set(alice, "..."); old != nil || err != nil {
-		t.Errorf("Got (%v, %v)", old, err)
-	}
-	if old, err := s.Set(alice, "..."); !reflect.DeepEqual(old, alice) || err != nil {
-		t.Errorf("Got (%v, %v) want (%v, nil)", old, err, alice)
-	}
-	if old, err := s.Set(bob, "..."); !reflect.DeepEqual(old, alice) || err != nil {
-		t.Errorf("Got (%v, %v) want (%v, nil)", old, err, alice)
-	}
-	if old, err := s.Set(nil, "..."); !reflect.DeepEqual(old, bob) || err != nil {
-		t.Errorf("Got (%v, %v) want (%v, nil)", old, err, bob)
-	}
-}
diff --git a/runtimes/google/rt/rt_test.go b/runtimes/google/rt/rt_test.go
index f9a9cf6..4faaf1c 100644
--- a/runtimes/google/rt/rt_test.go
+++ b/runtimes/google/rt/rt_test.go
@@ -156,6 +156,6 @@
 	// Test that the same principal gets initialized on creating a new runtime
 	// from the same credentials directory.
 	if got := newRT().Principal(); !reflect.DeepEqual(got, p) {
-		t.Fatalf("Initialized Principal: %v, expected: %v", got, p)
+		t.Fatalf("Initialized Principal: %v, expected: %v", got.PublicKey(), p.PublicKey())
 	}
 }
diff --git a/runtimes/google/rt/security.go b/runtimes/google/rt/security.go
index 8d3110e..0370941 100644
--- a/runtimes/google/rt/security.go
+++ b/runtimes/google/rt/security.go
@@ -1,13 +1,9 @@
 package rt
 
 import (
-	"crypto/ecdsa"
-	"crypto/elliptic"
-	"crypto/rand"
 	"fmt"
 	"os"
 	"os/user"
-	"path"
 	"strconv"
 
 	isecurity "veyron.io/veyron/veyron/runtimes/google/security"
@@ -19,12 +15,9 @@
 	"veyron.io/veyron/veyron2/vlog"
 )
 
-const (
-	privateKeyFile = "privatekey.pem"
-	// Environment variable pointing to a directory where information about a principal
-	// (private key, blessing store, blessing roots etc.) is stored.
-	VeyronCredentialsEnvVar = "VEYRON_CREDENTIALS"
-)
+// Environment variable pointing to a directory where information about a principal
+// (private key, blessing store, blessing roots etc.) is stored.
+const VeyronCredentialsEnvVar = "VEYRON_CREDENTIALS"
 
 func (rt *vrt) Principal() security.Principal {
 	return rt.principal
@@ -49,77 +42,45 @@
 	if err := rt.initPrincipal(); err != nil {
 		return fmt.Errorf("principal initialization failed: %v", err)
 	}
-	if err := rt.initDefaultBlessings(); err != nil {
-		return fmt.Errorf("default blessing initialization failed: %v", err)
-	}
 	return nil
 }
 
 func (rt *vrt) initPrincipal() error {
 	// TODO(ataly, ashankar): Check if agent environment variables are
 	// specified and if so initialize principal from agent.
+	var err error
 	if dir := os.Getenv(VeyronCredentialsEnvVar); len(dir) > 0 {
 		// TODO(ataly, ashankar): If multiple runtimes are getting
 		// initialized at the same time from the same VEYRON_CREDENTIALS
 		// we will need some kind of locking for the credential files.
-		return rt.initPrincipalFromCredentials(dir)
-	}
-	return rt.initTemporaryPrincipal()
-}
-
-func (rt *vrt) initDefaultBlessings() error {
-	if rt.principal.BlessingStore().Default() != nil {
+		var existed bool
+		if rt.principal, existed, err = vsecurity.NewPersistentPrincipal(dir); err != nil {
+			return err
+		}
+		if !existed {
+			return initDefaultBlessings(rt.principal)
+		}
 		return nil
 	}
-	blessing, err := rt.principal.BlessSelf(defaultBlessingName())
-	if err != nil {
+	if rt.principal, err = vsecurity.NewPrincipal(); err != nil {
 		return err
 	}
-	if err := rt.principal.BlessingStore().SetDefault(blessing); err != nil {
-		return err
-	}
-	if _, err := rt.principal.BlessingStore().Set(blessing, security.AllPrincipals); err != nil {
-		return err
-	}
-	if err := rt.principal.AddToRoots(blessing); err != nil {
-		return err
-	}
-	return nil
+	return initDefaultBlessings(rt.principal)
 }
 
-func (rt *vrt) initPrincipalFromCredentials(dir string) error {
-	if finfo, err := os.Stat(dir); err == nil {
-		if !finfo.IsDir() {
-			return fmt.Errorf("%q is not a directory", dir)
-		}
-	} else if err := os.MkdirAll(dir, 0700); err != nil {
-		return fmt.Errorf("failed to create %q: %v", dir, err)
-	}
-	key, err := initKey(dir)
-	if err != nil {
-		return fmt.Errorf("could not initialize private key from credentials directory %v: %v", dir, err)
-	}
-
-	signer := security.NewInMemoryECDSASigner(key)
-	store, roots, err := initStoreAndRootsFromCredentials(dir, signer)
-	if err != nil {
-		return fmt.Errorf("could not initialize BlessingStore and BlessingRoots from credentials directory %v: %v", dir, err)
-	}
-
-	if rt.principal, err = security.CreatePrincipal(signer, store, roots); err != nil {
-		return fmt.Errorf("could not create Principal object: %v", err)
-	}
-	return nil
-}
-
-func (rt *vrt) initTemporaryPrincipal() error {
-	key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+func initDefaultBlessings(p security.Principal) error {
+	blessing, err := p.BlessSelf(defaultBlessingName())
 	if err != nil {
 		return err
 	}
-	signer := security.NewInMemoryECDSASigner(key)
-	if rt.principal, err = security.CreatePrincipal(signer, newInMemoryBlessingStore(signer.PublicKey()), newInMemoryBlessingRoots()); err != nil {
-		return fmt.Errorf("could not create Principal object: %v", err)
+	if err := p.BlessingStore().SetDefault(blessing); err != nil {
+		return err
+	}
+	if _, err := p.BlessingStore().Set(blessing, security.AllPrincipals); err != nil {
+		return err
+	}
+	if err := p.AddToRoots(blessing); err != nil {
+		return err
 	}
 	return nil
 }
@@ -231,49 +192,3 @@
 	}
 	return isecurity.NewPrivateID("selfSigned", signer)
 }
-
-func initKey(dir string) (*ecdsa.PrivateKey, error) {
-	keyPath := path.Join(dir, privateKeyFile)
-	if f, err := os.Open(keyPath); err == nil {
-		defer f.Close()
-		v, err := vsecurity.LoadPEMKey(f, nil)
-		if err != nil {
-			return nil, fmt.Errorf("failed to load PEM data from %q: %v", keyPath, v)
-		}
-		key, ok := v.(*ecdsa.PrivateKey)
-		if !ok {
-			return nil, fmt.Errorf("%q contains a %T, not an ECDSA private key", keyPath, v)
-		}
-		return key, nil
-	} else if !os.IsNotExist(err) {
-		return nil, fmt.Errorf("failed to read %q: %v", keyPath, err)
-	}
-
-	key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
-	if err != nil {
-		return nil, fmt.Errorf("failed to generate a private key: %v", err)
-	}
-
-	f, err := os.OpenFile(keyPath, os.O_WRONLY|os.O_CREATE, 0600)
-	if err != nil {
-		return nil, fmt.Errorf("failed to open %q for writing: %v", keyPath, err)
-	}
-	defer f.Close()
-	return key, vsecurity.SavePEMKey(f, key, nil)
-}
-
-func initStoreAndRootsFromCredentials(dir string, secsigner security.Signer) (security.BlessingStore, security.BlessingRoots, error) {
-	signer, err := security.CreatePrincipal(secsigner, nil, nil)
-	if err != nil {
-		return nil, nil, err
-	}
-	store, err := newPersistingBlessingStore(signer.PublicKey(), dir, signer)
-	if err != nil {
-		return nil, nil, err
-	}
-	roots, err := newPersistingBlessingRoots(dir, signer)
-	if err != nil {
-		return nil, nil, err
-	}
-	return store, roots, nil
-}
diff --git a/runtimes/google/rt/util_test.go b/runtimes/google/rt/util_test.go
deleted file mode 100644
index bff9d50..0000000
--- a/runtimes/google/rt/util_test.go
+++ /dev/null
@@ -1,62 +0,0 @@
-package rt
-
-import (
-	"crypto/ecdsa"
-	"crypto/elliptic"
-	"crypto/rand"
-	"fmt"
-	"strings"
-	"testing"
-
-	"veyron.io/veyron/veyron2/security"
-)
-
-func matchesError(got error, want string) error {
-	if (got == nil) && len(want) == 0 {
-		return nil
-	}
-	if got == nil {
-		return fmt.Errorf("Got nil error, wanted to match %q", want)
-	}
-	if !strings.Contains(got.Error(), want) {
-		return fmt.Errorf("Got error %q, wanted to match %q", got, want)
-	}
-	return nil
-}
-
-func newPrincipal(t *testing.T) security.Principal {
-	key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
-	if err != nil {
-		t.Fatalf("Failed to create private key for principal: %v", err)
-	}
-	signer := security.NewInMemoryECDSASigner(key)
-	p, err := security.CreatePrincipal(signer, newInMemoryBlessingStore(signer.PublicKey()), newInMemoryBlessingRoots())
-	if err != nil {
-		t.Fatalf("security.CreatePrincipal failed: %v", err)
-	}
-	return p
-}
-
-func blessSelf(t *testing.T, p security.Principal, name string) security.Blessings {
-	b, err := p.BlessSelf(name)
-	if err != nil {
-		t.Fatal(err)
-	}
-	return b
-}
-
-func bless(t *testing.T, p security.Principal, key security.PublicKey, with security.Blessings, extension string) security.Blessings {
-	b, err := p.Bless(key, with, extension, security.UnconstrainedUse())
-	if err != nil {
-		t.Fatal(err)
-	}
-	return b
-}
-
-func unionOfBlessings(t *testing.T, blessings ...security.Blessings) security.Blessings {
-	b, err := security.UnionOfBlessings(blessings...)
-	if err != nil {
-		t.Fatal(err)
-	}
-	return b
-}
diff --git a/security/acl_authorizer_test.go b/security/acl_authorizer_test.go
index 25615c1..d94964b 100644
--- a/security/acl_authorizer_test.go
+++ b/security/acl_authorizer_test.go
@@ -8,7 +8,6 @@
 
 	"veyron.io/veyron/veyron2/naming"
 	"veyron.io/veyron/veyron2/security"
-	"veyron.io/veyron/veyron2/security/sectest"
 )
 
 // context implements security.Context.
@@ -56,14 +55,6 @@
 	}
 }
 
-func bless(blesser, blessed security.Principal, with security.Blessings, extension string) security.Blessings {
-	b, err := blesser.Bless(blessed.PublicKey(), with, extension, security.UnconstrainedUse())
-	if err != nil {
-		panic(err)
-	}
-	return b
-}
-
 func testSelfRPCs(t *testing.T, authorizer security.Authorizer) {
 	_, file, line, _ := runtime.Caller(1)
 	var (
@@ -258,18 +249,3 @@
 	testNothingPermitted(t, authorizer)
 	testSelfRPCs(t, authorizer)
 }
-
-func newPrincipal(selfblessing string) (security.Principal, security.Blessings) {
-	p, err := sectest.NewPrincipal()
-	if err != nil {
-		panic(err)
-	}
-	b, err := p.BlessSelf(selfblessing)
-	if err != nil {
-		panic(err)
-	}
-	if err := p.AddToRoots(b); err != nil {
-		panic(err)
-	}
-	return p, b
-}
diff --git a/runtimes/google/rt/blessingroots.go b/security/blessingroots.go
similarity index 98%
rename from runtimes/google/rt/blessingroots.go
rename to security/blessingroots.go
index 62f3026..33bb145 100644
--- a/runtimes/google/rt/blessingroots.go
+++ b/security/blessingroots.go
@@ -1,4 +1,4 @@
-package rt
+package security
 
 import (
 	"crypto/sha256"
@@ -17,10 +17,10 @@
 
 // blessingRoots implements security.BlessingRoots.
 type blessingRoots struct {
-	store  map[string][]security.BlessingPattern // GUARDED_BY(mu)
 	dir    string
 	signer serialization.Signer
 	mu     sync.RWMutex
+	store  map[string][]security.BlessingPattern // GUARDED_BY(mu)
 }
 
 func storeMapKey(root security.PublicKey) (string, error) {
diff --git a/security/blessingroots_test.go b/security/blessingroots_test.go
new file mode 100644
index 0000000..c346126
--- /dev/null
+++ b/security/blessingroots_test.go
@@ -0,0 +1,121 @@
+package security
+
+import (
+	"fmt"
+	"io/ioutil"
+	"os"
+	"testing"
+
+	"veyron.io/veyron/veyron2/security"
+)
+
+type rootsTester [3]security.PublicKey
+
+func newRootsTester() *rootsTester {
+	var tester rootsTester
+	var err error
+	for idx := range tester {
+		if tester[idx], _, err = newKey(); err != nil {
+			panic(err)
+		}
+	}
+	return &tester
+}
+
+func (t *rootsTester) add(br security.BlessingRoots) error {
+	testdata := []struct {
+		root    security.PublicKey
+		pattern security.BlessingPattern
+	}{
+		{t[0], "veyron/..."},
+		{t[1], "google/foo/..."},
+		{t[0], "google"},
+	}
+	for _, d := range testdata {
+		if err := br.Add(d.root, d.pattern); err != nil {
+			return fmt.Errorf("Add(%v, %q) failed: %s", d.root, d.pattern, err)
+		}
+	}
+	return nil
+}
+
+func (t *rootsTester) testRecognized(br security.BlessingRoots) error {
+	testdata := []struct {
+		root          security.PublicKey
+		recognized    []string
+		notRecognized []string
+	}{
+		{
+			root:          t[0],
+			recognized:    []string{"veyron", "veyron/foo", "veyron/foo/bar", "google"},
+			notRecognized: []string{"google/foo", "foo", "foo/bar"},
+		},
+		{
+			root:          t[1],
+			recognized:    []string{"google", "google/foo", "google/foo/bar"},
+			notRecognized: []string{"google/bar", "veyron", "veyron/foo", "foo", "foo/bar"},
+		},
+		{
+			root:          t[2],
+			recognized:    []string{},
+			notRecognized: []string{"veyron", "veyron/foo", "veyron/bar", "google", "google/foo", "google/bar", "foo", "foo/bar"},
+		},
+	}
+	for _, d := range testdata {
+		for _, b := range d.recognized {
+			if err := br.Recognized(d.root, b); err != nil {
+				return fmt.Errorf("Recognized(%v, %q): got: %v, want nil", d.root, b, err)
+			}
+		}
+		for _, b := range d.notRecognized {
+			if err := matchesError(br.Recognized(d.root, b), "not a recognized root"); err != nil {
+				return fmt.Errorf("Recognized(%v, %q): %v", d.root, b, err)
+			}
+		}
+	}
+	return nil
+}
+
+func TestBlessingRoots(t *testing.T) {
+	p, err := NewPrincipal()
+	if err != nil {
+		t.Fatal(err)
+	}
+	tester := newRootsTester()
+	if err := tester.add(p.Roots()); err != nil {
+		t.Fatal(err)
+	}
+	if err := tester.testRecognized(p.Roots()); err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestBlessingRootsPersistence(t *testing.T) {
+	dir, err := ioutil.TempDir("", "TestBlessingRootsPersistence")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
+	tester := newRootsTester()
+	p, existed, err := NewPersistentPrincipal(dir)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if existed {
+		t.Fatalf("%q already has a principal", dir)
+	}
+	if err := tester.add(p.Roots()); err != nil {
+		t.Error(err)
+	}
+	if err := tester.testRecognized(p.Roots()); err != nil {
+		t.Error(err)
+	}
+	// Recreate the principal (and thus BlessingRoots)
+	p2, _, err := NewPersistentPrincipal(dir)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if err := tester.testRecognized(p2.Roots()); err != nil {
+		t.Error(err)
+	}
+}
diff --git a/runtimes/google/rt/blessingstore.go b/security/blessingstore.go
similarity index 89%
rename from runtimes/google/rt/blessingstore.go
rename to security/blessingstore.go
index 2e87449..54b1b0b 100644
--- a/runtimes/google/rt/blessingstore.go
+++ b/security/blessingstore.go
@@ -1,4 +1,4 @@
-package rt
+package security
 
 import (
 	"errors"
@@ -32,11 +32,11 @@
 
 // blessingStore implements security.BlessingStore.
 type blessingStore struct {
-	state     persistentState // GUARDED_BY(mu)
 	publicKey security.PublicKey
 	dir       string
 	signer    serialization.Signer
 	mu        sync.RWMutex
+	state     persistentState // GUARDED_BY(mu)
 }
 
 func (s *blessingStore) Set(blessings security.Blessings, forPeers security.BlessingPattern) (security.Blessings, error) {
@@ -132,20 +132,20 @@
 }
 
 // newPersistingBlessingStore returns a security.BlessingStore for a principal
-// with the provided PublicKey that signs and persists all updates to the
-// specified directory. Signing is carried out using the provided signer.
+// that persists all updates to the specified directory and uses the provided
+// signer to ensure integrity of data read from the filesystem.
 //
 // The returned BlessingStore is initialized from the existing data present in
 // the directory. The data is verified to have been written by a persisting
-// BlessingStore object constructed from the same PublicKey and signer.
+// BlessingStore object constructed from the same signer.
 //
 // Any errors obtained in reading or verifying the data are returned.
-func newPersistingBlessingStore(publicKey security.PublicKey, directory string, signer serialization.Signer) (security.BlessingStore, error) {
+func newPersistingBlessingStore(directory string, signer serialization.Signer) (security.BlessingStore, error) {
 	if directory == "" || signer == nil {
 		return nil, errors.New("directory or signer is not specified")
 	}
 	s := &blessingStore{
-		publicKey: publicKey,
+		publicKey: signer.PublicKey(),
 		state:     persistentState{Store: make(map[security.BlessingPattern]security.Blessings)},
 		dir:       directory,
 		signer:    signer,
@@ -156,8 +156,8 @@
 	}
 
 	for _, b := range s.state.Store {
-		if !reflect.DeepEqual(b.PublicKey(), publicKey) {
-			return nil, fmt.Errorf("directory contains Blessings: %v that are not for the provided PublicKey: %v", b, publicKey)
+		if !reflect.DeepEqual(b.PublicKey(), s.publicKey) {
+			return nil, fmt.Errorf("directory contains Blessings: %v that are not for the provided PublicKey: %v", b, s.publicKey)
 		}
 	}
 	return s, nil
diff --git a/security/blessingstore_test.go b/security/blessingstore_test.go
new file mode 100644
index 0000000..c7152bb
--- /dev/null
+++ b/security/blessingstore_test.go
@@ -0,0 +1,255 @@
+package security
+
+import (
+	"fmt"
+	"io/ioutil"
+	"os"
+	"reflect"
+	"testing"
+
+	"veyron.io/veyron/veyron2/security"
+)
+
+type storeTester struct {
+	forAll, forFoo, forBar, def security.Blessings
+	other                       security.Blessings // Blessings bound to a different principal.
+}
+
+func (t *storeTester) testSet(s security.BlessingStore) error {
+	testdata := []struct {
+		blessings security.Blessings
+		pattern   security.BlessingPattern
+		wantErr   string
+	}{
+		{t.forAll, "...", ""},
+		{t.forFoo, "foo/...", ""},
+		{t.forBar, "bar", ""},
+		{t.other, "...", "public key does not match"},
+		{t.forAll, "", "invalid BlessingPattern"},
+		{t.forAll, "foo...", "invalid BlessingPattern"},
+		{t.forAll, "...foo", "invalid BlessingPattern"},
+		{t.forAll, "foo/.../bar", "invalid BlessingPattern"},
+	}
+	for _, d := range testdata {
+		_, err := s.Set(d.blessings, d.pattern)
+		if merr := matchesError(err, d.wantErr); merr != nil {
+			return fmt.Errorf("Set(%v, %q): %v", d.blessings, d.pattern, merr)
+		}
+	}
+	return nil
+}
+
+func (t *storeTester) testSetDefault(s security.BlessingStore, currentDefault security.Blessings) error {
+	if got := s.Default(); !reflect.DeepEqual(got, currentDefault) {
+		return fmt.Errorf("Default(): got: %v, want: %v", got, currentDefault)
+	}
+	if err := s.SetDefault(t.def); err != nil {
+		return fmt.Errorf("SetDefault(%v): %v", t.def, err)
+	}
+	if got, want := s.Default(), t.def; !reflect.DeepEqual(got, want) {
+		return fmt.Errorf("Default returned %v, want %v", got, want)
+	}
+	// Changing default to an invalid blessing should not affect the existing default.
+	if err := matchesError(s.SetDefault(t.other), "public key does not match"); err != nil {
+		return err
+	}
+	if got, want := s.Default(), t.def; !reflect.DeepEqual(got, want) {
+		return fmt.Errorf("Default returned %v, want %v", got, want)
+	}
+	return nil
+}
+
+func (t *storeTester) testForPeer(s security.BlessingStore) error {
+	testdata := []struct {
+		peers     []string
+		blessings security.Blessings
+	}{
+		{nil, t.forAll},
+		{[]string{"baz"}, t.forAll},
+		{[]string{"foo"}, unionOfBlessings(t.forAll, t.forFoo)},
+		{[]string{"bar"}, unionOfBlessings(t.forAll, t.forBar)},
+		{[]string{"foo/foo"}, unionOfBlessings(t.forAll, t.forFoo)},
+		{[]string{"bar/baz"}, t.forAll},
+		{[]string{"foo/foo/bar"}, unionOfBlessings(t.forAll, t.forFoo)},
+		{[]string{"bar/foo", "foo"}, unionOfBlessings(t.forAll, t.forFoo)},
+		{[]string{"bar", "foo"}, unionOfBlessings(t.forAll, t.forFoo, t.forBar)},
+	}
+	for _, d := range testdata {
+		if got, want := s.ForPeer(d.peers...), d.blessings; !reflect.DeepEqual(got, want) {
+			return fmt.Errorf("ForPeer(%v): got: %v, want: %v", d.peers, got, want)
+		}
+	}
+	return nil
+}
+
+func newStoreTester(blessed security.Principal) *storeTester {
+	var (
+		blessing = func(root, extension string) security.Blessings {
+			blesser, err := NewPrincipal()
+			if err != nil {
+				panic(err)
+			}
+			blessing, err := blesser.Bless(blessed.PublicKey(), blessSelf(blesser, root), extension, security.UnconstrainedUse())
+			if err != nil {
+				panic(err)
+			}
+			return blessing
+		}
+	)
+	pother, err := NewPrincipal()
+	if err != nil {
+		panic(err)
+	}
+
+	s := &storeTester{}
+	s.forAll = blessing("bar", "alice")
+	s.forFoo = blessing("foo", "alice")
+	s.forBar = unionOfBlessings(s.forAll, s.forFoo)
+	s.def = blessing("default", "alice")
+	s.other = blessSelf(pother, "other")
+	return s
+}
+
+func TestBlessingStore(t *testing.T) {
+	p, err := NewPrincipal()
+	if err != nil {
+		t.Fatal(err)
+	}
+	tester := newStoreTester(p)
+	s := p.BlessingStore()
+	if err := tester.testSet(s); err != nil {
+		t.Error(err)
+	}
+	if err := tester.testForPeer(s); err != nil {
+		t.Error(err)
+	}
+	if err := tester.testSetDefault(s, tester.forAll); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestBlessingStorePersistence(t *testing.T) {
+	dir, err := ioutil.TempDir("", "TestPersistingBlessingStore")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
+	p, existed, err := NewPersistentPrincipal(dir)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if existed {
+		t.Errorf("%q already has a principal in it", dir)
+	}
+	tester := newStoreTester(p)
+	s := p.BlessingStore()
+
+	if err := tester.testSet(s); err != nil {
+		t.Error(err)
+	}
+	if err := tester.testForPeer(s); err != nil {
+		t.Error(err)
+	}
+	if err := tester.testSetDefault(s, tester.forAll); err != nil {
+		t.Error(err)
+	}
+
+	// Recreate the BlessingStore from the directory.
+	p2, _, err := NewPersistentPrincipal(dir)
+	if err != nil {
+		t.Fatal(err)
+	}
+	s = p2.BlessingStore()
+	if err := tester.testForPeer(s); err != nil {
+		t.Error(err)
+	}
+	if got, want := s.Default(), tester.def; !reflect.DeepEqual(got, want) {
+		t.Fatalf("Default(): got: %v, want: %v", got, want)
+	}
+}
+
+func TestBlessingStoreSetOverridesOldSetting(t *testing.T) {
+	p, err := NewPrincipal()
+	if err != nil {
+		t.Fatal(err)
+	}
+	var (
+		alice = blessSelf(p, "alice")
+		bob   = blessSelf(p, "bob")
+		s     = p.BlessingStore()
+	)
+	// Set(alice, "alice")
+	// Set(bob, "alice/...")
+	// So, {alice, bob} is shared with "alice", whilst {bob} is shared with "alice/tv"
+	if _, err := s.Set(alice, "alice"); err != nil {
+		t.Fatal(err)
+	}
+	if _, err := s.Set(bob, "alice/..."); err != nil {
+		t.Fatal(err)
+	}
+	if got, want := s.ForPeer("alice"), unionOfBlessings(alice, bob); !reflect.DeepEqual(got, want) {
+		t.Errorf("Got %v, want %v", got, want)
+	}
+	if got, want := s.ForPeer("alice/friend"), bob; !reflect.DeepEqual(got, want) {
+		t.Errorf("Got %v, want %v", got, want)
+	}
+
+	// Clear out the blessing associated with "alice".
+	// Now, bob should be shared with both alice and alice/friend.
+	if _, err := s.Set(nil, "alice"); err != nil {
+		t.Fatal(err)
+	}
+	if got, want := s.ForPeer("alice"), bob; !reflect.DeepEqual(got, want) {
+		t.Errorf("Got %v, want %v", got, want)
+	}
+	if got, want := s.ForPeer("alice/friend"), bob; !reflect.DeepEqual(got, want) {
+		t.Errorf("Got %v, want %v", got, want)
+	}
+
+	// Clearing out an association that doesn't exist should have no effect.
+	if _, err := s.Set(nil, "alice/enemy"); err != nil {
+		t.Fatal(err)
+	}
+	if got, want := s.ForPeer("alice"), bob; !reflect.DeepEqual(got, want) {
+		t.Errorf("Got %v, want %v", got, want)
+	}
+	if got, want := s.ForPeer("alice/friend"), bob; !reflect.DeepEqual(got, want) {
+		t.Errorf("Got %v, want %v", got, want)
+	}
+
+	// Clear everything
+	if _, err := s.Set(nil, "alice/..."); err != nil {
+		t.Fatal(err)
+	}
+	if got := s.ForPeer("alice"); got != nil {
+		t.Errorf("Got %v, want nil", got)
+	}
+	if got := s.ForPeer("alice/friend"); got != nil {
+		t.Errorf("Got %v, want nil", got)
+	}
+}
+
+func TestBlessingStoreSetReturnsOldValue(t *testing.T) {
+	p, err := NewPrincipal()
+	if err != nil {
+		t.Fatal(err)
+	}
+	var (
+		alice = blessSelf(p, "alice")
+		bob   = blessSelf(p, "bob")
+		s     = p.BlessingStore()
+	)
+
+	if old, err := s.Set(alice, "..."); old != nil || err != nil {
+		t.Errorf("Got (%v, %v)", old, err)
+	}
+	if old, err := s.Set(alice, "..."); !reflect.DeepEqual(old, alice) || err != nil {
+		t.Errorf("Got (%v, %v) want (%v, nil)", old, err, alice)
+	}
+	if old, err := s.Set(bob, "..."); !reflect.DeepEqual(old, alice) || err != nil {
+		t.Errorf("Got (%v, %v) want (%v, nil)", old, err, alice)
+	}
+	if old, err := s.Set(nil, "..."); !reflect.DeepEqual(old, bob) || err != nil {
+		t.Errorf("Got (%v, %v) want (%v, nil)", old, err, bob)
+	}
+}
diff --git a/security/doc.go b/security/doc.go
new file mode 100644
index 0000000..14bd17c
--- /dev/null
+++ b/security/doc.go
@@ -0,0 +1,2 @@
+// Package security provides utility functions for creating/using veyron security primitives.
+package security
diff --git a/security/principal.go b/security/principal.go
new file mode 100644
index 0000000..3f5888e
--- /dev/null
+++ b/security/principal.go
@@ -0,0 +1,100 @@
+package security
+
+import (
+	"crypto/ecdsa"
+	"crypto/elliptic"
+	"crypto/rand"
+	"fmt"
+	"os"
+	"path"
+
+	"veyron.io/veyron/veyron2/security"
+)
+
+const privateKeyFile = "privatekey.pem"
+
+// newKey generates an ECDSA (public, private) key pair..
+func newKey() (security.PublicKey, *ecdsa.PrivateKey, error) {
+	priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+	if err != nil {
+		return nil, nil, err
+	}
+	return security.NewECDSAPublicKey(&priv.PublicKey), priv, nil
+}
+
+// NewPrincipal mints a new private key and generates a principal based on
+// this key, storing its BlessingRoots and BlessingStore in memory.
+func NewPrincipal() (security.Principal, error) {
+	pub, priv, err := newKey()
+	if err != nil {
+		return nil, err
+	}
+	return security.CreatePrincipal(security.NewInMemoryECDSASigner(priv), newInMemoryBlessingStore(pub), newInMemoryBlessingRoots())
+}
+
+// NewPersistentPrincipal reads state for a principal (private key, BlessingRoots, BlessingStore)
+// from the provided directory 'dir' and commits all state changes to the same directory.
+//
+// If the directory does not contain state, then a new private key is minted and all state of
+// the principal is committed to 'dir'. If the directory does not exist, it is created.
+//
+// Returns the security.Principal implementation, a boolean that is set to true iff the directory
+// already contained a principal and any errors in initialization.
+func NewPersistentPrincipal(dir string) (principal security.Principal, existed bool, err error) {
+	if finfo, err := os.Stat(dir); err == nil {
+		if !finfo.IsDir() {
+			return nil, false, fmt.Errorf("%q is not a directory", dir)
+		}
+	} else if err := os.MkdirAll(dir, 0700); err != nil {
+		return nil, false, fmt.Errorf("failed to create %q: %v", dir, err)
+	}
+	key, existed, err := initKey(dir)
+	if err != nil {
+		return nil, false, fmt.Errorf("could not initialize private key from credentials directory %v: %v", dir, err)
+	}
+	signer, err := security.CreatePrincipal(security.NewInMemoryECDSASigner(key), nil, nil)
+	if err != nil {
+		return nil, false, fmt.Errorf("failed to create serialization.Signer: %v", err)
+	}
+	roots, err := newPersistingBlessingRoots(dir, signer)
+	if err != nil {
+		return nil, false, fmt.Errorf("failed to load BlessingRoots from %q: %v", dir, err)
+	}
+	store, err := newPersistingBlessingStore(dir, signer)
+	if err != nil {
+		return nil, false, fmt.Errorf("failed to load BlessingStore from %q: %v", dir, err)
+	}
+	p, err := security.CreatePrincipal(security.NewInMemoryECDSASigner(key), store, roots)
+	return p, existed, err
+}
+
+func initKey(dir string) (*ecdsa.PrivateKey, bool, error) {
+	keyFile := path.Join(dir, privateKeyFile)
+	if f, err := os.Open(keyFile); err == nil {
+		defer f.Close()
+		v, err := LoadPEMKey(f, nil)
+		if err != nil {
+			return nil, false, fmt.Errorf("failed to load PEM data from %q: %v", keyFile, v)
+		}
+		key, ok := v.(*ecdsa.PrivateKey)
+		if !ok {
+			return nil, false, fmt.Errorf("%q contains a %T, not an ECDSA private key", keyFile, v)
+		}
+		return key, true, nil
+	} else if !os.IsNotExist(err) {
+		return nil, false, fmt.Errorf("failed to read %q: %v", keyFile, err)
+	}
+	_, key, err := newKey()
+	if err != nil {
+		return nil, false, fmt.Errorf("failed to generate a private key: %v", err)
+	}
+	f, err := os.OpenFile(keyFile, os.O_WRONLY|os.O_CREATE, 0600)
+	if err != nil {
+		return nil, false, fmt.Errorf("failed to open %q for writing: %v", keyFile, err)
+	}
+	defer f.Close()
+	if err := SavePEMKey(f, key, nil); err != nil {
+		return nil, false, fmt.Errorf("failed to save private key to %q: %v", keyFile, err)
+	}
+	return key, false, nil
+}
diff --git a/security/principal_test.go b/security/principal_test.go
new file mode 100644
index 0000000..a8ad464
--- /dev/null
+++ b/security/principal_test.go
@@ -0,0 +1,38 @@
+package security
+
+import (
+	"io/ioutil"
+	"os"
+	"testing"
+)
+
+func TestNewPersistentPrincipal(t *testing.T) {
+	// Persistence of the BlessingRoots and BlessingStore objects is
+	// tested in other files. Here just test the persistence of the key.
+	dir, err := ioutil.TempDir("", "TestNewPersistentPrincipal")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
+
+	p, existed, err := NewPersistentPrincipal(dir)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if existed {
+		t.Fatalf("%q already has data", existed)
+	}
+	message := []byte("this is a test message")
+	sig, err := p.Sign(message)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	p2, _, err := NewPersistentPrincipal(dir)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !sig.Verify(p2.PublicKey(), message) {
+		t.Errorf("p.PublicKey=%v, p2.PublicKey=%v", p.PublicKey(), p2.PublicKey())
+	}
+}
diff --git a/runtimes/google/rt/util.go b/security/storage.go
similarity index 98%
rename from runtimes/google/rt/util.go
rename to security/storage.go
index 83271be..0dd755b 100644
--- a/runtimes/google/rt/util.go
+++ b/security/storage.go
@@ -1,4 +1,4 @@
-package rt
+package security
 
 import (
 	"io/ioutil"
diff --git a/security/testutil_test.go b/security/testutil_test.go
new file mode 100644
index 0000000..f3c5606
--- /dev/null
+++ b/security/testutil_test.go
@@ -0,0 +1,75 @@
+package security
+
+import (
+	"fmt"
+	"strings"
+
+	"veyron.io/veyron/veyron2/security"
+)
+
+func matchesError(got error, want string) error {
+	if (got == nil) && len(want) == 0 {
+		return nil
+	}
+	if got == nil {
+		return fmt.Errorf("Got nil error, wanted to match %q", want)
+	}
+	if !strings.Contains(got.Error(), want) {
+		return fmt.Errorf("Got error %q, wanted to match %q", got, want)
+	}
+	return nil
+}
+
+func newPrincipal(selfblessings ...string) (security.Principal, security.Blessings) {
+	p, err := NewPrincipal()
+	if err != nil {
+		panic(err)
+	}
+	if len(selfblessings) == 0 {
+		return p, nil
+	}
+	var def security.Blessings
+	for _, str := range selfblessings {
+		b, err := p.BlessSelf(str)
+		if err != nil {
+			panic(err)
+		}
+		if def, err = security.UnionOfBlessings(def, b); err != nil {
+			panic(err)
+		}
+	}
+	if err := p.AddToRoots(def); err != nil {
+		panic(err)
+	}
+	if err := p.BlessingStore().SetDefault(def); err != nil {
+		panic(err)
+	}
+	if _, err := p.BlessingStore().Set(def, security.AllPrincipals); err != nil {
+		panic(err)
+	}
+	return p, def
+}
+
+func bless(blesser, blessed security.Principal, with security.Blessings, extension string) security.Blessings {
+	b, err := blesser.Bless(blessed.PublicKey(), with, extension, security.UnconstrainedUse())
+	if err != nil {
+		panic(err)
+	}
+	return b
+}
+
+func blessSelf(p security.Principal, name string) security.Blessings {
+	b, err := p.BlessSelf(name)
+	if err != nil {
+		panic(err)
+	}
+	return b
+}
+
+func unionOfBlessings(blessings ...security.Blessings) security.Blessings {
+	b, err := security.UnionOfBlessings(blessings...)
+	if err != nil {
+		panic(err)
+	}
+	return b
+}
diff --git a/services/identity/blesser/macaroon_test.go b/services/identity/blesser/macaroon_test.go
index 4c6a7d2..8ea499a 100644
--- a/services/identity/blesser/macaroon_test.go
+++ b/services/identity/blesser/macaroon_test.go
@@ -7,12 +7,12 @@
 	"testing"
 	"time"
 
+	vsecurity "veyron.io/veyron/veyron/security"
 	"veyron.io/veyron/veyron/services/identity"
 	"veyron.io/veyron/veyron/services/identity/util"
 
 	"veyron.io/veyron/veyron2/ipc"
 	"veyron.io/veyron/veyron2/security"
-	"veyron.io/veyron/veyron2/security/sectest"
 	"veyron.io/veyron/veyron2/vom"
 )
 
@@ -88,13 +88,9 @@
 func (c *serverCall) RemoteBlessings() security.Blessings { return c.remote }
 
 func newPrincipal(t *testing.T) security.Principal {
-	_, key, err := sectest.NewKey()
+	p, err := vsecurity.NewPrincipal()
 	if err != nil {
-		t.Fatal(err)
-	}
-	p, err := security.CreatePrincipal(security.NewInMemoryECDSASigner(key), nil, sectest.NewBlessingRoots())
-	if err != nil {
-		t.Fatal(err)
+		panic(err)
 	}
 	return p
 }