veyron/...: Update a bunch of tests to use the new security model.

And remove some test utility functions that work with the old
security model.

And restore tests disabled in veyron/services/mgmt/node/impl/impl_test.go

Change-Id: I6f82f3002df13f56b045e133c6366be73e017d19
diff --git a/lib/signals/signals_test.go b/lib/signals/signals_test.go
index ade0df3..634e1d2 100644
--- a/lib/signals/signals_test.go
+++ b/lib/signals/signals_test.go
@@ -324,22 +324,20 @@
 
 // TestCleanRemoteShutdown verifies that remote shutdown works correctly.
 func TestCleanRemoteShutdown(t *testing.T) {
-	r := rt.Init()
+	r := rt.Init(veyron2.ForceNewSecurityModel{})
 	defer r.Cleanup()
 
 	sh := modules.NewShell()
 	sh.AddSubprocess("handleDefaults", "")
 	defer sh.Cleanup(os.Stderr, os.Stderr)
 
-	// This sets up the child's identity to be derived from the parent's (so
-	// that default authorization works for RPCs between the two).
-	// TODO(caprita): Consider making this boilerplate part of blackbox.
-	id := r.Identity()
-	idFile := security.SaveIdentityToFile(security.NewBlessedIdentity(id, "test"))
-	defer os.Remove(idFile)
+	// Set the child process up with a blessing from the parent so that
+	// the default authorization works for RPCs between the two.
+	childcreds := security.NewVeyronCredentials(r.Principal(), "child")
+	defer os.RemoveAll(childcreds)
 	configServer, configServiceName, ch := createConfigServer(t)
 	defer configServer.Stop()
-	sh.SetVar("VEYRON_IDENTITY", idFile)
+	sh.SetVar("VEYRON_CREDENTIALS", childcreds)
 	sh.SetVar(mgmt.ParentNodeManagerConfigKey, configServiceName)
 	h, err := sh.Start("handleDefaults")
 	if err != nil {
diff --git a/lib/testutil/security/util.go b/lib/testutil/security/util.go
index 9a45b2c..2bf1fdb 100644
--- a/lib/testutil/security/util.go
+++ b/lib/testutil/security/util.go
@@ -5,34 +5,55 @@
 import (
 	"io/ioutil"
 	"os"
-	"strconv"
-	"time"
 
-	"veyron.io/veyron/veyron/lib/testutil"
-	isecurity "veyron.io/veyron/veyron/runtimes/google/security"
 	vsecurity "veyron.io/veyron/veyron/security"
 
 	"veyron.io/veyron/veyron2/security"
 )
 
-// NewBlessedIdentity creates a new identity and blesses it using the provided blesser
-// under the provided name. This function is meant to be used for testing purposes only,
-// it panics if there is an error.
-func NewBlessedIdentity(blesser security.PrivateID, name string) security.PrivateID {
-	id, err := isecurity.NewPrivateID("test", nil)
+// NewVeyronCredentials generates a directory with a new principal
+// that can be used as a value for the VEYRON_CREDENTIALS environment
+// variable to initialize a Runtime.
+//
+// The principal created uses a blessing from 'parent', with the extension
+// 'name' as its default blessing.
+//
+// It returns the path to the directory created.
+func NewVeyronCredentials(parent security.Principal, name string) string {
+	dir, err := ioutil.TempDir("", "veyron_credentials")
 	if err != nil {
 		panic(err)
 	}
+	p, _, err := vsecurity.NewPersistentPrincipal(dir)
+	if err != nil {
+		panic(err)
+	}
+	blessings, err := parent.Bless(p.PublicKey(), parent.BlessingStore().Default(), name, security.UnconstrainedUse())
+	if err != nil {
+		panic(err)
+	}
+	SetDefaultBlessings(p, blessings)
+	return dir
+}
 
-	blessedID, err := blesser.Bless(id.PublicID(), name, 5*time.Minute, nil)
-	if err != nil {
+// SetDefaultBlessings updates the BlessingStore and BlessingRoots of p
+// so that:
+// (1) b is revealed to all clients that connect to Servers operated
+// by 'p' (BlessingStore.Default)
+// (2) b is revealed  to all servers that clients connect to on behalf
+// of p (BlessingStore.Set(..., security.AllPrincipals))
+// (3) p recognizes all blessings that have the same root certificate as b.
+// (AddToRoots)
+func SetDefaultBlessings(p security.Principal, b security.Blessings) {
+	if err := p.BlessingStore().SetDefault(b); err != nil {
 		panic(err)
 	}
-	derivedID, err := id.Derive(blessedID)
-	if err != nil {
+	if _, err := p.BlessingStore().Set(b, security.AllPrincipals); err != nil {
 		panic(err)
 	}
-	return derivedID
+	if err := p.AddToRoots(b); err != nil {
+		panic(err)
+	}
 }
 
 // SaveACLToFile saves the provided ACL in JSON format to a randomly created
@@ -51,23 +72,3 @@
 	}
 	return f.Name()
 }
-
-// SaveIdentityToFile saves the provided identity in Base64VOM format
-// to a randomly created temporary file, and returns the path to the file.
-// This function is meant to be used for testing purposes only, it panics
-// if there is an error. The caller must ensure that the created file
-// is removed once it is no longer needed.
-func SaveIdentityToFile(id security.PrivateID) string {
-	f, err := ioutil.TempFile("", strconv.Itoa(testutil.Rand.Int()))
-	if err != nil {
-		panic(err)
-	}
-	defer f.Close()
-	filePath := f.Name()
-
-	if err := vsecurity.SaveIdentity(f, id); err != nil {
-		os.Remove(filePath)
-		panic(err)
-	}
-	return filePath
-}
diff --git a/lib/testutil/security/util_test.go b/lib/testutil/security/util_test.go
index 5125d1e..ea9ee21 100644
--- a/lib/testutil/security/util_test.go
+++ b/lib/testutil/security/util_test.go
@@ -1,47 +1,37 @@
 package security
 
 import (
-	"fmt"
 	"os"
 	"reflect"
 	"testing"
 
-	isecurity "veyron.io/veyron/veyron/runtimes/google/security"
 	vsecurity "veyron.io/veyron/veyron/security"
 
 	"veyron.io/veyron/veyron2/rt"
 	"veyron.io/veyron/veyron2/security"
 )
 
-func TestNewBlessedIdentity(t *testing.T) {
+func TestNewVeyronCredentials(t *testing.T) {
 	r, err := rt.New()
 	if err != nil {
-		t.Fatalf("rt.New failed: %v", err)
+		t.Fatal(err)
 	}
 	defer r.Cleanup()
-	newID := func(name string) security.PrivateID {
-		id, err := r.NewIdentity(name)
-		if err != nil {
-			t.Fatalf("r.NewIdentity failed: %v", err)
-		}
-		isecurity.TrustIdentityProviders(id)
-		return id
+
+	parent := r.Principal()
+	childdir := NewVeyronCredentials(parent, "child")
+	_, existed, err := vsecurity.NewPersistentPrincipal(childdir)
+	if err != nil {
+		t.Fatal(err)
 	}
-	testdata := []struct {
-		blesser            security.PrivateID
-		blessingName, name string
-	}{
-		{blesser: newID("google"), blessingName: "alice", name: "PrivateID:google/alice"},
-		{blesser: newID("google"), blessingName: "bob", name: "PrivateID:google/bob"},
-		{blesser: newID("veyron"), blessingName: "alice", name: "PrivateID:veyron/alice"},
-		{blesser: newID("veyron"), blessingName: "bob", name: "PrivateID:veyron/bob"},
-		{blesser: NewBlessedIdentity(newID("google"), "alice"), blessingName: "tv", name: "PrivateID:google/alice/tv"},
+	if !existed {
+		t.Fatalf("Expected NewVeyronCredentials to have populated the directory %q", childdir)
 	}
-	for _, d := range testdata {
-		if got, want := fmt.Sprintf("%s", NewBlessedIdentity(d.blesser, d.blessingName)), d.name; got != want {
-			t.Errorf("NewBlessedIdentity(%q, %q): Got %q, want %q", d.blesser, d.blessingName, got, want)
-		}
-	}
+	// TODO(ashankar,ataly): Figure out what APIs should we use for more detailed testing
+	// of the child principal, for example:
+	// - Parent should recognize the child's default blessing
+	// - Child should recognize the parent's default blessing
+	// - Child's blessing name should be that of the parent with "/child" appended.
 }
 
 func TestSaveACLToFile(t *testing.T) {
@@ -76,31 +66,3 @@
 		t.Fatalf("Got ACL %v, but want %v", loadedACL, acl)
 	}
 }
-
-func TestSaveIdentityToFile(t *testing.T) {
-	r, err := rt.New()
-	if err != nil {
-		t.Fatalf("rt.New failed: %v", err)
-	}
-	defer r.Cleanup()
-	id, err := r.NewIdentity("test")
-	if err != nil {
-		t.Fatalf("r.NewIdentity failed: %v", err)
-	}
-
-	filePath := SaveIdentityToFile(id)
-	defer os.Remove(filePath)
-
-	f, err := os.Open(filePath)
-	if err != nil {
-		t.Fatalf("os.Open(%v) failed: %v", filePath, err)
-	}
-	defer f.Close()
-	loadedID, err := vsecurity.LoadIdentity(f)
-	if err != nil {
-		t.Fatalf("LoadIdentity failed: %v", err)
-	}
-	if !reflect.DeepEqual(loadedID, id) {
-		t.Fatalf("Got Identity %v, but want %v", loadedID, id)
-	}
-}
diff --git a/runtimes/google/rt/mgmt_test.go b/runtimes/google/rt/mgmt_test.go
index df084f2..e15eaa2 100644
--- a/runtimes/google/rt/mgmt_test.go
+++ b/runtimes/google/rt/mgmt_test.go
@@ -263,12 +263,11 @@
 	// refer to the global rt.R() function), but we take care to make sure
 	// that the "google" runtime we are trying to test in this package is
 	// the one being used.
-	r, _ := rt.New(veyron2.RuntimeOpt{veyron2.GoogleRuntimeName})
+	r, _ := rt.New(veyron2.RuntimeOpt{veyron2.GoogleRuntimeName}, veyron2.ForceNewSecurityModel{})
 	c := blackbox.HelperCommand(t, "app")
-	id := r.Identity()
-	idFile := security.SaveIdentityToFile(security.NewBlessedIdentity(id, "test"))
+	childcreds := security.NewVeyronCredentials(r.Principal(), "app")
 	configServer, configServiceName, ch := createConfigServer(t, r)
-	c.Cmd.Env = append(c.Cmd.Env, fmt.Sprintf("VEYRON_IDENTITY=%v", idFile),
+	c.Cmd.Env = append(c.Cmd.Env, fmt.Sprintf("VEYRON_CREDENTIALS=%v", childcreds),
 		fmt.Sprintf("%v=%v", mgmt.ParentNodeManagerConfigKey, configServiceName))
 	c.Cmd.Start()
 	appCycleName := <-ch
@@ -279,7 +278,7 @@
 	return r, c, appCycle, func() {
 		configServer.Stop()
 		c.Cleanup()
-		os.Remove(idFile)
+		os.RemoveAll(childcreds)
 		// Don't do r.Cleanup() since the runtime needs to be used by
 		// more than one test case.
 	}
diff --git a/services/mgmt/node/impl/impl_test.go b/services/mgmt/node/impl/impl_test.go
index 6d66f0f..ee410d8 100644
--- a/services/mgmt/node/impl/impl_test.go
+++ b/services/mgmt/node/impl/impl_test.go
@@ -1,10 +1,10 @@
 package impl_test
 
 import (
-	//	"bytes"
+	"bytes"
 	"crypto/md5"
 	"encoding/base64"
-	//	"encoding/hex"
+	"encoding/hex"
 	"encoding/json"
 	"fmt"
 	"io/ioutil"
@@ -19,13 +19,12 @@
 	"strings"
 	"syscall"
 	"testing"
-	"time"
 
 	"veyron.io/veyron/veyron/lib/exec"
 	"veyron.io/veyron/veyron/lib/signals"
 	"veyron.io/veyron/veyron/lib/testutil/blackbox"
-	// tsecurity "veyron.io/veyron/veyron/lib/testutil/security"
-	// vsecurity "veyron.io/veyron/veyron/security"
+	tsecurity "veyron.io/veyron/veyron/lib/testutil/security"
+	vsecurity "veyron.io/veyron/veyron/security"
 	"veyron.io/veyron/veyron/services/mgmt/node/config"
 	"veyron.io/veyron/veyron/services/mgmt/node/impl"
 	suidhelper "veyron.io/veyron/veyron/services/mgmt/suidhelper/impl"
@@ -65,7 +64,7 @@
 	}
 
 	// All the tests require a runtime; so just create it here.
-	rt.Init()
+	rt.Init(veyron2.ForceNewSecurityModel{})
 
 	// Disable the cache because we will be manipulating/using the namespace
 	// across multiple processes and want predictable behaviour without
@@ -722,32 +721,26 @@
 
 type granter struct {
 	ipc.CallOpt
-	self     security.PrivateID
-	blessing security.PublicID
+	p         security.Principal
+	extension string
 }
 
-func (g *granter) Grant(id security.PublicID) (security.PublicID, error) {
-	var err error
-	g.blessing, err = g.self.Bless(id, "claimernode", 10*time.Minute, nil)
-	return g.blessing, err
+func (g *granter) Grant(other security.Blessings) (security.Blessings, error) {
+	return g.p.Bless(other.PublicKey(), g.p.BlessingStore().Default(), g.extension, security.UnconstrainedUse())
 }
 
-func newRuntimeClient(t *testing.T, id security.PrivateID) (veyron2.Runtime, ipc.Client) {
-	runtime, err := rt.New(veyron2.RuntimeID(id))
+func newRuntime(t *testing.T) veyron2.Runtime {
+	runtime, err := rt.New(veyron2.ForceNewSecurityModel{})
 	if err != nil {
 		t.Fatalf("rt.New() failed: %v", err)
 	}
 	runtime.Namespace().SetRoots(rt.R().Namespace().Roots()[0])
-	nodeClient, err := runtime.NewClient()
-	if err != nil {
-		t.Fatalf("rt.NewClient() failed %v", err)
-	}
-	return runtime, nodeClient
+	return runtime
 }
 
-func tryInstall(rt veyron2.Runtime, c ipc.Client) error {
+func tryInstall(rt veyron2.Runtime) error {
 	appsName := "nm//apps"
-	stub, err := node.BindApplication(appsName, c)
+	stub, err := node.BindApplication(appsName, rt.Client())
 	if err != nil {
 		return fmt.Errorf("BindApplication(%v) failed: %v", appsName, err)
 	}
@@ -757,9 +750,6 @@
 	return nil
 }
 
-// TODO(ashankar): Temporarily disabled during security model transition.
-// Fix up and restore!
-/*
 // TestNodeManagerClaim claims a nodemanager and tests ACL permissions on its methods.
 func TestNodeManagerClaim(t *testing.T) {
 	// Set up mount table, application, and binary repositories.
@@ -792,38 +782,25 @@
 		t.Fatalf("BindNode failed: %v", err)
 	}
 
-	// Create a new identity and runtime.
-	claimerIdentity := tsecurity.NewBlessedIdentity(rt.R().Identity(), "claimer")
-	newRT, nodeClient := newRuntimeClient(t, claimerIdentity)
-	defer newRT.Cleanup()
+	selfRT := rt.R()
+	otherRT := newRuntime(t)
+	defer otherRT.Cleanup()
 
-	// Nodemanager should have open ACLs before we claim it and so an Install
-	// should succeed.
-	if err = tryInstall(newRT, nodeClient); err != nil {
-		t.Fatalf("%v", err)
+	// Nodemanager should have open ACLs before we claim it and so an Install from otherRT should succeed.
+	if err = tryInstall(otherRT); err != nil {
+		t.Fatal(err)
 	}
-	// Claim the nodemanager with this identity.
-	if err = nodeStub.Claim(rt.R().NewContext(), &granter{self: claimerIdentity}); err != nil {
-		t.Fatalf("Claim failed: %v", err)
+	// Claim the nodemanager with selfRT as <defaultblessing>/mydevice
+	if err = nodeStub.Claim(selfRT.NewContext(), &granter{p: selfRT.Principal(), extension: "mydevice"}); err != nil {
+		t.Fatal(err)
 	}
-	if err = tryInstall(newRT, nodeClient); err != nil {
-		t.Fatalf("%v", err)
+	// Installation should succeed since selfRT is now the "owner" of the nodemanager.
+	if err = tryInstall(selfRT); err != nil {
+		t.Fatal(err)
 	}
-	// Try to install with a new identity. This should fail.
-	randomIdentity := tsecurity.NewBlessedIdentity(rt.R().Identity(), "random")
-	newRT, nodeClient = newRuntimeClient(t, randomIdentity)
-	defer newRT.Cleanup()
-	if err = tryInstall(newRT, nodeClient); err == nil {
-		t.Fatalf("Install should have failed with random identity")
-	}
-	// Try to install with the original identity. This should still work as the original identity
-	// name is a prefix of the identity used by newRT.
-	nodeClient, err = rt.R().NewClient()
-	if err != nil {
-		t.Fatalf("rt.NewClient() failed %v", err)
-	}
-	if err = tryInstall(rt.R(), nodeClient); err != nil {
-		t.Fatalf("%v", err)
+	// otherRT should be unable to install though, since the ACLs have changed now.
+	if err = tryInstall(otherRT); err == nil {
+		t.Fatalf("Install should have failed from otherRT")
 	}
 	// TODO(gauthamt): Test that ACLs persist across nodemanager restarts
 }
@@ -838,6 +815,24 @@
 	root, cleanup := setupRootDir(t)
 	defer cleanup()
 
+	var (
+		proot = newRootPrincipal("root")
+		// The two "processes"/runtimes which will act as IPC clients to the
+		// nodemanager process.
+		selfRT  = rt.R()
+		otherRT = newRuntime(t)
+	)
+	defer otherRT.Cleanup()
+	// By default, selfRT and otherRT will have blessings generated based on the
+	// username/machine name running this process. Since these blessings will appear
+	// in ACLs, give them recognizable names.
+	if err := setDefaultBlessings(selfRT.Principal(), proot, "self"); err != nil {
+		t.Fatal(err)
+	}
+	if err := setDefaultBlessings(otherRT.Principal(), proot, "other"); err != nil {
+		t.Fatal(err)
+	}
+
 	// Set up the node manager.  Since we won't do node manager updates,
 	// don't worry about its application envelope and current link.
 	nm := blackbox.HelperCommand(t, "nodeManager", "nm", root, "unused app repo name", "unused curr link")
@@ -858,7 +853,7 @@
 	if err != nil {
 		t.Fatalf("BindNode failed: %v", err)
 	}
-	acl, etag, err := nodeStub.GetACL(rt.R().NewContext())
+	acl, etag, err := nodeStub.GetACL(selfRT.NewContext())
 	if err != nil {
 		t.Fatalf("GetACL failed:%v", err)
 	}
@@ -866,59 +861,42 @@
 		t.Fatalf("getACL expected:default, got:%v(%v)", etag, acl)
 	}
 
-	// Create a new identity and claim the node manager
-	claimerIdentity := tsecurity.NewBlessedIdentity(rt.R().Identity(), "claimer")
-	grant := &granter{self: claimerIdentity}
-	if err = nodeStub.Claim(rt.R().NewContext(), grant); err != nil {
-		t.Fatalf("Claim failed: %v", err)
+	// Claim the nodemanager as "root/self/mydevice"
+	if err = nodeStub.Claim(selfRT.NewContext(), &granter{p: selfRT.Principal(), extension: "mydevice"}); err != nil {
+		t.Fatal(err)
 	}
-	expectedACL := security.ACL{In: make(map[security.BlessingPattern]security.LabelSet)}
-	for _, name := range grant.blessing.Names() {
-		expectedACL.In[security.BlessingPattern(name)] = security.AllLabels
-	}
+	expectedACL := security.ACL{In: map[security.BlessingPattern]security.LabelSet{"root/self/mydevice": security.AllLabels}}
 	var b bytes.Buffer
 	if err := vsecurity.SaveACL(&b, expectedACL); err != nil {
 		t.Fatalf("Failed to saveACL:%v", err)
 	}
 	md5hash := md5.Sum(b.Bytes())
 	expectedETAG := hex.EncodeToString(md5hash[:])
-	acl, etag, err = nodeStub.GetACL(rt.R().NewContext())
-	if err != nil {
-		t.Fatalf("GetACL failed")
+	if acl, etag, err = nodeStub.GetACL(selfRT.NewContext()); err != nil {
+		t.Fatal(err)
 	}
 	if etag != expectedETAG {
 		t.Fatalf("getACL expected:%v(%v), got:%v(%v)", expectedACL, expectedETAG, acl, etag)
 	}
-	// Try to install with a new identity. This should fail.
-	randomIdentity := tsecurity.NewBlessedIdentity(rt.R().Identity(), "random")
-	newRT, nodeClient := newRuntimeClient(t, randomIdentity)
-	defer newRT.Cleanup()
-	if err = tryInstall(newRT, nodeClient); err == nil {
+	// Install from otherRT should fail, since it does not match the ACL.
+	if err = tryInstall(otherRT); err == nil {
 		t.Fatalf("Install should have failed with random identity")
 	}
-	newACL := security.ACL{In: make(map[security.BlessingPattern]security.LabelSet)}
-	for _, name := range randomIdentity.PublicID().Names() {
-		newACL.In[security.BlessingPattern(name)] = security.AllLabels
-	}
-	// SetACL with invalid etag
-	if err = nodeStub.SetACL(rt.R().NewContext(), newACL, "invalid"); err == nil {
+	newACL := security.ACL{In: map[security.BlessingPattern]security.LabelSet{"root/other": security.AllLabels}}
+	if err = nodeStub.SetACL(selfRT.NewContext(), newACL, "invalid"); err == nil {
 		t.Fatalf("SetACL should have failed with invalid etag")
 	}
-	if err = nodeStub.SetACL(rt.R().NewContext(), newACL, etag); err != nil {
-		t.Fatalf("SetACL failed:%v", err)
+	if err = nodeStub.SetACL(selfRT.NewContext(), newACL, etag); err != nil {
+		t.Fatal(err)
 	}
-	if err = tryInstall(newRT, nodeClient); err != nil {
-		t.Fatalf("Install failed with new identity:%v", err)
+	// Install should now fail with selfRT, which no longer matches the ACLs but succeed with otherRT, which does.
+	if err = tryInstall(selfRT); err == nil {
+		t.Errorf("Install should have failed with selfRT since it should no longer match the ACL")
 	}
-	// Try to install with the claimer identity. This should fail as the ACLs
-	// belong to the random identity
-	newRT, nodeClient = newRuntimeClient(t, claimerIdentity)
-	defer newRT.Cleanup()
-	if err = tryInstall(newRT, nodeClient); err == nil {
-		t.Fatalf("Install should have failed with claimer identity")
+	if err = tryInstall(otherRT); err != nil {
+		t.Error(err)
 	}
 }
-*/
 
 func TestNodeManagerGlob(t *testing.T) {
 	// Set up mount table, application, and binary repositories.
@@ -1007,3 +985,34 @@
 		}
 	}
 }
+
+// rootPrincipal encapsulates a principal that acts as an "identity provider".
+type rootPrincipal struct {
+	p security.Principal
+	b security.Blessings
+}
+
+func (r *rootPrincipal) Bless(key security.PublicKey, as string) (security.Blessings, error) {
+	return r.p.Bless(key, r.b, as, security.UnconstrainedUse())
+}
+
+func newRootPrincipal(name string) *rootPrincipal {
+	p, err := vsecurity.NewPrincipal()
+	if err != nil {
+		panic(err)
+	}
+	b, err := p.BlessSelf(name)
+	if err != nil {
+		panic(err)
+	}
+	return &rootPrincipal{p, b}
+}
+
+func setDefaultBlessings(p security.Principal, root *rootPrincipal, name string) error {
+	b, err := root.Bless(p.PublicKey(), name)
+	if err != nil {
+		return err
+	}
+	tsecurity.SetDefaultBlessings(p, b)
+	return nil
+}
diff --git a/services/mgmt/node/impl/util_test.go b/services/mgmt/node/impl/util_test.go
index ad9e22a..b519965 100644
--- a/services/mgmt/node/impl/util_test.go
+++ b/services/mgmt/node/impl/util_test.go
@@ -61,16 +61,16 @@
 // TODO(caprita): Move this setup into the blackbox lib.
 
 // setupChildCommand configures the child to use the right mounttable root
-// and identity.  It returns a cleanup function.
+// and blessings.  It returns a cleanup function.
 func setupChildCommand(child *blackbox.Child) func() {
 	cmd := child.Cmd
 	for i, root := range rt.R().Namespace().Roots() {
 		cmd.Env = exec.Setenv(cmd.Env, fmt.Sprintf("NAMESPACE_ROOT%d", i), root)
 	}
-	idFile := security.SaveIdentityToFile(security.NewBlessedIdentity(rt.R().Identity(), "test"))
-	cmd.Env = exec.Setenv(cmd.Env, "VEYRON_IDENTITY", idFile)
+	childcreds := security.NewVeyronCredentials(rt.R().Principal(), "child")
+	cmd.Env = exec.Setenv(cmd.Env, "VEYRON_CREDENTIALS", childcreds)
 	return func() {
-		os.Remove(idFile)
+		os.RemoveAll(childcreds)
 	}
 }
 
diff --git a/services/mounttable/lib/mounttable_test.go b/services/mounttable/lib/mounttable_test.go
index c773312..a8a6286 100644
--- a/services/mounttable/lib/mounttable_test.go
+++ b/services/mounttable/lib/mounttable_test.go
@@ -2,6 +2,7 @@
 
 import (
 	"errors"
+	"fmt"
 	"reflect"
 	"runtime/debug"
 	"sort"
@@ -26,14 +27,12 @@
 // stupidNS is a version of naming.Namespace that we can control.  This exists so that we have some
 // firm ground to stand on vis a vis the stub interface.
 type stupidNS struct {
-	id ipc.ClientOpt
+	r veyron2.Runtime
 }
 
-var (
-	rootID  = veyron2.LocalID(security.FakePublicID("root"))
-	bobID   = veyron2.LocalID(security.FakePublicID("bob"))
-	aliceID = veyron2.LocalID(security.FakePublicID("alice"))
-)
+// Simulate different processes with different runtimes.
+// rootRT is the one running the mounttable service.
+var rootRT, aliceRT, bobRT veyron2.Runtime
 
 const ttlSecs = 60 * 60
 
@@ -42,11 +41,10 @@
 	t.Fatal(string(debug.Stack()))
 }
 
-// quuxClient returns an ipc.Client that uses the simple namespace for name
-// resolution.
-func quuxClient(id ipc.ClientOpt) ipc.Client {
-	ns := stupidNS{id}
-	c, err := rt.R().NewClient(id, veyron2.Namespace(ns))
+// quuxClient returns an ipc.Client that would be used by the provided runtime
+// and uses the simple namespace for name resolution.
+func quuxClient(r veyron2.Runtime) ipc.Client {
+	c, err := r.NewClient(veyron2.Namespace(stupidNS{r}))
 	if err != nil {
 		panic(err)
 	}
@@ -74,11 +72,11 @@
 	}
 
 	// Resolve via another
-	objectPtr, err := mounttable.BindMountTable("/"+address+"//"+suffix, quuxClient(ns.id))
+	objectPtr, err := mounttable.BindMountTable("/"+address+"//"+suffix, quuxClient(ns.r))
 	if err != nil {
 		return nil, err
 	}
-	ss, suffix, err := objectPtr.ResolveStep(rt.R().NewContext())
+	ss, suffix, err := objectPtr.ResolveStep(ns.r.NewContext())
 	if err != nil {
 		return nil, err
 	}
@@ -119,12 +117,12 @@
 	return []string{}
 }
 
-func doMount(t *testing.T, name, service string, shouldSucceed bool, id ipc.ClientOpt) {
-	mtpt, err := mounttable.BindMountTable(name, quuxClient(id))
+func doMount(t *testing.T, name, service string, shouldSucceed bool, as veyron2.Runtime) {
+	mtpt, err := mounttable.BindMountTable(name, quuxClient(as))
 	if err != nil {
 		boom(t, "Failed to BindMountTable: %s", err)
 	}
-	if err := mtpt.Mount(rt.R().NewContext(), service, uint32(ttlSecs), 0, veyron2.RetryTimeoutOpt(0)); err != nil {
+	if err := mtpt.Mount(as.NewContext(), service, uint32(ttlSecs), 0, veyron2.RetryTimeoutOpt(0)); err != nil {
 		if shouldSucceed {
 			boom(t, "Failed to Mount %s onto %s: %s", service, name, err)
 		}
@@ -133,12 +131,12 @@
 	}
 }
 
-func doUnmount(t *testing.T, name, service string, shouldSucceed bool, id ipc.ClientOpt) {
-	mtpt, err := mounttable.BindMountTable(name, quuxClient(id))
+func doUnmount(t *testing.T, name, service string, shouldSucceed bool, as veyron2.Runtime) {
+	mtpt, err := mounttable.BindMountTable(name, quuxClient(as))
 	if err != nil {
 		boom(t, "Failed to BindMountTable: %s", err)
 	}
-	if err := mtpt.Unmount(rt.R().NewContext(), service, veyron2.RetryTimeoutOpt(0)); err != nil {
+	if err := mtpt.Unmount(as.NewContext(), service, veyron2.RetryTimeoutOpt(0)); err != nil {
 		if shouldSucceed {
 			boom(t, "Failed to Unmount %s onto %s: %s", service, name, err)
 		}
@@ -147,22 +145,22 @@
 	}
 }
 
-func create(t *testing.T, name, contents string) {
-	objectPtr, err := BindCollection(name, quuxClient(rootID))
+func export(t *testing.T, name, contents string, as veyron2.Runtime) {
+	objectPtr, err := BindCollection(name, quuxClient(as))
 	if err != nil {
 		boom(t, "Failed to BindCollection: %s", err)
 	}
-	if err := objectPtr.Export(rt.R().NewContext(), contents, true); err != nil {
+	if err := objectPtr.Export(as.NewContext(), contents, true); err != nil {
 		boom(t, "Failed to Export %s to %s: %s", name, contents, err)
 	}
 }
 
-func checkContents(t *testing.T, name, expected string, shouldSucceed bool, id ipc.ClientOpt) {
-	objectPtr, err := BindCollection(name, quuxClient(id))
+func checkContents(t *testing.T, name, expected string, shouldSucceed bool, as veyron2.Runtime) {
+	objectPtr, err := BindCollection(name, quuxClient(as))
 	if err != nil {
 		boom(t, "Failed to BindCollection: %s", err)
 	}
-	contents, err := objectPtr.Lookup(rt.R().NewContext(), veyron2.RetryTimeoutOpt(0))
+	contents, err := objectPtr.Lookup(as.NewContext(), veyron2.RetryTimeoutOpt(0))
 	if err != nil {
 		if shouldSucceed {
 			boom(t, "Failed to Lookup %s: %s", name, err)
@@ -178,13 +176,7 @@
 }
 
 func newMT(t *testing.T, acl string) (ipc.Server, string) {
-	// It is necessary for the private key of runtime's identity and
-	// the public key of the LocalIDOpts passed to clients to correspond.
-	// Since the LocalIDOpts are FakePublicIDs, we initialize the runtime
-	// below with a FakePrivateID. (Note all FakePublicIDs and FakePrivateIDs
-	// always have corresponding public and private keys respectively.)
-	r := rt.Init(veyron2.RuntimeID(security.FakePrivateID("irrelevant")))
-	server, err := r.NewServer(veyron2.ServesMountTableOpt(true))
+	server, err := rootRT.NewServer(veyron2.ServesMountTableOpt(true))
 	if err != nil {
 		boom(t, "r.NewServer: %s", err)
 	}
@@ -207,8 +199,7 @@
 }
 
 func newCollection(t *testing.T, acl string) (ipc.Server, string) {
-	r := rt.Init()
-	server, err := r.NewServer()
+	server, err := rootRT.NewServer()
 	if err != nil {
 		boom(t, "r.NewServer: %s", err)
 	}
@@ -238,69 +229,69 @@
 
 	// Mount the collection server into the mount table.
 	vlog.Infof("Mount the collection server into the mount table.")
-	doMount(t, naming.JoinAddressName(mtAddr, "//mounttable/stuff"), collectionName, true, rootID)
+	doMount(t, naming.JoinAddressName(mtAddr, "//mounttable/stuff"), collectionName, true, rootRT)
 
 	// Create a few objects and make sure we can read them.
 	vlog.Infof("Create a few objects.")
-	create(t, naming.JoinAddressName(mtAddr, "mounttable/stuff/the/rain"), "the rain")
-	create(t, naming.JoinAddressName(mtAddr, "mounttable/stuff/in/spain"), "in spain")
-	create(t, naming.JoinAddressName(mtAddr, "mounttable/stuff/falls"), "falls mainly on the plain")
+	export(t, naming.JoinAddressName(mtAddr, "mounttable/stuff/the/rain"), "the rain", rootRT)
+	export(t, naming.JoinAddressName(mtAddr, "mounttable/stuff/in/spain"), "in spain", rootRT)
+	export(t, naming.JoinAddressName(mtAddr, "mounttable/stuff/falls"), "falls mainly on the plain", rootRT)
 	vlog.Infof("Make sure we can read them.")
-	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/stuff/the/rain"), "the rain", true, rootID)
-	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/stuff/in/spain"), "in spain", true, rootID)
-	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/stuff/falls"), "falls mainly on the plain", true, rootID)
-	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable//stuff/falls"), "falls mainly on the plain", false, rootID)
-	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/stuff/nonexistant"), "falls mainly on the plain", false, rootID)
-	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/stuff/the/rain"), "the rain", true, bobID)
-	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/stuff/the/rain"), "the rain", false, aliceID)
+	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/stuff/the/rain"), "the rain", true, rootRT)
+	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/stuff/in/spain"), "in spain", true, rootRT)
+	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/stuff/falls"), "falls mainly on the plain", true, rootRT)
+	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable//stuff/falls"), "falls mainly on the plain", false, rootRT)
+	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/stuff/nonexistant"), "falls mainly on the plain", false, rootRT)
+	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/stuff/the/rain"), "the rain", true, bobRT)
+	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/stuff/the/rain"), "the rain", false, aliceRT)
 
 	// Test multiple mounts.
 	vlog.Infof("Multiple mounts.")
-	doMount(t, naming.JoinAddressName(mtAddr, "//mounttable//a/b"), collectionName, true, rootID)
-	doMount(t, naming.JoinAddressName(mtAddr, "//mounttable/x/y"), collectionName, true, rootID)
-	doMount(t, naming.JoinAddressName(mtAddr, "//mounttable/alpha//beta"), collectionName, true, rootID)
+	doMount(t, naming.JoinAddressName(mtAddr, "//mounttable//a/b"), collectionName, true, rootRT)
+	doMount(t, naming.JoinAddressName(mtAddr, "//mounttable/x/y"), collectionName, true, rootRT)
+	doMount(t, naming.JoinAddressName(mtAddr, "//mounttable/alpha//beta"), collectionName, true, rootRT)
 	vlog.Infof("Make sure we can read them.")
-	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/stuff/falls"), "falls mainly on the plain", true, rootID)
-	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/a/b/falls"), "falls mainly on the plain", true, rootID)
-	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/x/y/falls"), "falls mainly on the plain", true, rootID)
-	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/alpha/beta/falls"), "falls mainly on the plain", true, rootID)
-	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/a/b/falls"), "falls mainly on the plain", true, aliceID)
-	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/a/b/falls"), "falls mainly on the plain", false, bobID)
+	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/stuff/falls"), "falls mainly on the plain", true, rootRT)
+	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/a/b/falls"), "falls mainly on the plain", true, rootRT)
+	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/x/y/falls"), "falls mainly on the plain", true, rootRT)
+	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/alpha/beta/falls"), "falls mainly on the plain", true, rootRT)
+	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/a/b/falls"), "falls mainly on the plain", true, aliceRT)
+	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/a/b/falls"), "falls mainly on the plain", false, bobRT)
 
 	// Test generic unmount.
 	vlog.Info("Test generic unmount.")
-	doUnmount(t, naming.JoinAddressName(mtAddr, "//mounttable/a/b"), "", true, rootID)
-	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/a/b/falls"), "falls mainly on the plain", false, rootID)
+	doUnmount(t, naming.JoinAddressName(mtAddr, "//mounttable/a/b"), "", true, rootRT)
+	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/a/b/falls"), "falls mainly on the plain", false, rootRT)
 
 	// Test specific unmount.
 	vlog.Info("Test specific unmount.")
-	doMount(t, naming.JoinAddressName(mtAddr, "//mounttable/a/b"), collectionName, true, rootID)
-	doUnmount(t, naming.JoinAddressName(mtAddr, "//mounttable/a/b"), collectionName, true, rootID)
-	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/a/b/falls"), "falls mainly on the plain", false, rootID)
+	doMount(t, naming.JoinAddressName(mtAddr, "//mounttable/a/b"), collectionName, true, rootRT)
+	doUnmount(t, naming.JoinAddressName(mtAddr, "//mounttable/a/b"), collectionName, true, rootRT)
+	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/a/b/falls"), "falls mainly on the plain", false, rootRT)
 
 	// Try timing out a mount.
 	vlog.Info("Try timing out a mount.")
 	ft := NewFakeTimeClock()
 	setServerListClock(ft)
-	doMount(t, naming.JoinAddressName(mtAddr, "//mounttable/stuffWithTTL"), collectionName, true, rootID)
-	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/stuffWithTTL/the/rain"), "the rain", true, rootID)
+	doMount(t, naming.JoinAddressName(mtAddr, "//mounttable/stuffWithTTL"), collectionName, true, rootRT)
+	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/stuffWithTTL/the/rain"), "the rain", true, rootRT)
 	ft.advance(time.Duration(ttlSecs+4) * time.Second)
-	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/stuffWithTTL/the/rain"), "the rain", false, rootID)
+	checkContents(t, naming.JoinAddressName(mtAddr, "mounttable/stuffWithTTL/the/rain"), "the rain", false, rootRT)
 
 	// Test unauthorized mount.
 	vlog.Info("Test unauthorized mount.")
-	doMount(t, naming.JoinAddressName(mtAddr, "//mounttable//a/b"), collectionName, false, bobID)
-	doMount(t, naming.JoinAddressName(mtAddr, "//mounttable//a/b"), collectionName, false, aliceID)
+	doMount(t, naming.JoinAddressName(mtAddr, "//mounttable//a/b"), collectionName, false, bobRT)
+	doMount(t, naming.JoinAddressName(mtAddr, "//mounttable//a/b"), collectionName, false, aliceRT)
 
-	doUnmount(t, naming.JoinAddressName(mtAddr, "//mounttable/x/y"), collectionName, false, bobID)
+	doUnmount(t, naming.JoinAddressName(mtAddr, "//mounttable/x/y"), collectionName, false, bobRT)
 }
 
-func doGlob(t *testing.T, name, pattern string, id ipc.ClientOpt) []string {
-	mtpt, err := mounttable.BindMountTable(name, quuxClient(id))
+func doGlob(t *testing.T, name, pattern string, as veyron2.Runtime) []string {
+	mtpt, err := mounttable.BindMountTable(name, quuxClient(as))
 	if err != nil {
 		boom(t, "Failed to BindMountTable: %s", err)
 	}
-	stream, err := mtpt.Glob(rt.R().NewContext(), pattern)
+	stream, err := mtpt.Glob(as.NewContext(), pattern)
 	if err != nil {
 		boom(t, "Failed call to %s.Glob(%s): %s", name, pattern, err)
 	}
@@ -336,9 +327,9 @@
 
 	// set up a mount space
 	fakeServer := naming.JoinAddressName(estr, "//quux")
-	doMount(t, naming.JoinAddressName(estr, "//one/bright/day"), fakeServer, true, rootID)
-	doMount(t, naming.JoinAddressName(estr, "//in/the/middle"), fakeServer, true, rootID)
-	doMount(t, naming.JoinAddressName(estr, "//of/the/night"), fakeServer, true, rootID)
+	doMount(t, naming.JoinAddressName(estr, "//one/bright/day"), fakeServer, true, rootRT)
+	doMount(t, naming.JoinAddressName(estr, "//in/the/middle"), fakeServer, true, rootRT)
+	doMount(t, naming.JoinAddressName(estr, "//of/the/night"), fakeServer, true, rootRT)
 
 	// Try various globs.
 	tests := []struct {
@@ -356,7 +347,7 @@
 		{"", []string{""}},
 	}
 	for _, test := range tests {
-		out := doGlob(t, naming.JoinAddressName(estr, "//"), test.in, rootID)
+		out := doGlob(t, naming.JoinAddressName(estr, "//"), test.in, rootRT)
 		checkMatch(t, test.expected, out)
 	}
 
@@ -365,11 +356,11 @@
 	{
 		name := naming.JoinAddressName(estr, "//of/the/night/two/dead/boys/got/up/to/fight")
 		pattern := "*"
-		m, err := mounttable.BindGlobbable(name, quuxClient(rootID))
+		m, err := mounttable.BindGlobbable(name, quuxClient(rootRT))
 		if err != nil {
 			boom(t, "Failed to BindMountTable: %s", err)
 		}
-		stream, err := m.Glob(rt.R().NewContext(), pattern)
+		stream, err := m.Glob(rootRT.NewContext(), pattern)
 		if err != nil {
 			boom(t, "Failed call to %s.Glob(%s): %s", name, pattern, err)
 		}
@@ -400,24 +391,24 @@
 
 	// set up a mount space
 	fakeServer := naming.JoinAddressName(estr, "quux")
-	doMount(t, naming.JoinAddressName(estr, "//one/bright/day"), fakeServer, true, rootID)
-	doMount(t, naming.JoinAddressName(estr, "//a/b/c"), fakeServer, true, rootID)
+	doMount(t, naming.JoinAddressName(estr, "//one/bright/day"), fakeServer, true, rootRT)
+	doMount(t, naming.JoinAddressName(estr, "//a/b/c"), fakeServer, true, rootRT)
 
 	// Try various globs.
 	tests := []struct {
-		id       ipc.ClientOpt
+		as       veyron2.Runtime
 		in       string
 		expected []string
 	}{
-		{rootID, "*", []string{"one", "a"}},
-		{aliceID, "*", []string{"one", "a"}},
-		{bobID, "*", []string{"one"}},
-		{rootID, "*/...", []string{"one", "a", "one/bright", "a/b", "one/bright/day", "a/b/c"}},
-		{aliceID, "*/...", []string{"one", "a", "one/bright", "a/b", "one/bright/day", "a/b/c"}},
-		{bobID, "*/...", []string{"one", "one/bright", "one/bright/day"}},
+		{rootRT, "*", []string{"one", "a"}},
+		{aliceRT, "*", []string{"one", "a"}},
+		{bobRT, "*", []string{"one"}},
+		{rootRT, "*/...", []string{"one", "a", "one/bright", "a/b", "one/bright/day", "a/b/c"}},
+		{aliceRT, "*/...", []string{"one", "a", "one/bright", "a/b", "one/bright/day", "a/b/c"}},
+		{bobRT, "*/...", []string{"one", "one/bright", "one/bright/day"}},
 	}
 	for _, test := range tests {
-		out := doGlob(t, naming.JoinAddressName(estr, "//"), test.in, test.id)
+		out := doGlob(t, naming.JoinAddressName(estr, "//"), test.in, test.as)
 		checkMatch(t, test.expected, out)
 	}
 }
@@ -426,12 +417,12 @@
 	server, estr := newMT(t, "")
 	defer server.Stop()
 
-	doMount(t, naming.JoinAddressName(estr, "//mounttable/endpoint"), naming.JoinAddressName(estr, "life/on/the/mississippi"), true, rootID)
-	doMount(t, naming.JoinAddressName(estr, "//mounttable/hostport"), "/atrampabroad:8000", true, rootID)
-	doMount(t, naming.JoinAddressName(estr, "//mounttable/hostport-endpoint-platypus"), "/@atrampabroad:8000@@", true, rootID)
-	doMount(t, naming.JoinAddressName(estr, "//mounttable/invalid/not/rooted"), "atrampabroad:8000", false, rootID)
-	doMount(t, naming.JoinAddressName(estr, "//mounttable/invalid/no/port"), "/atrampabroad", false, rootID)
-	doMount(t, naming.JoinAddressName(estr, "//mounttable/invalid/endpoint"), "/@following the equator:8000@@@", false, rootID)
+	doMount(t, naming.JoinAddressName(estr, "//mounttable/endpoint"), naming.JoinAddressName(estr, "life/on/the/mississippi"), true, rootRT)
+	doMount(t, naming.JoinAddressName(estr, "//mounttable/hostport"), "/atrampabroad:8000", true, rootRT)
+	doMount(t, naming.JoinAddressName(estr, "//mounttable/hostport-endpoint-platypus"), "/@atrampabroad:8000@@", true, rootRT)
+	doMount(t, naming.JoinAddressName(estr, "//mounttable/invalid/not/rooted"), "atrampabroad:8000", false, rootRT)
+	doMount(t, naming.JoinAddressName(estr, "//mounttable/invalid/no/port"), "/atrampabroad", false, rootRT)
+	doMount(t, naming.JoinAddressName(estr, "//mounttable/invalid/endpoint"), "/@following the equator:8000@@@", false, rootRT)
 }
 
 func TestExpiry(t *testing.T) {
@@ -444,21 +435,21 @@
 
 	ft := NewFakeTimeClock()
 	setServerListClock(ft)
-	doMount(t, naming.JoinAddressName(estr, "//mounttable/a1/b1"), collectionName, true, rootID)
-	doMount(t, naming.JoinAddressName(estr, "//mounttable/a1/b2"), collectionName, true, rootID)
-	doMount(t, naming.JoinAddressName(estr, "//mounttable/a2/b1"), collectionName, true, rootID)
-	doMount(t, naming.JoinAddressName(estr, "//mounttable/a2/b2/c"), collectionName, true, rootID)
+	doMount(t, naming.JoinAddressName(estr, "//mounttable/a1/b1"), collectionName, true, rootRT)
+	doMount(t, naming.JoinAddressName(estr, "//mounttable/a1/b2"), collectionName, true, rootRT)
+	doMount(t, naming.JoinAddressName(estr, "//mounttable/a2/b1"), collectionName, true, rootRT)
+	doMount(t, naming.JoinAddressName(estr, "//mounttable/a2/b2/c"), collectionName, true, rootRT)
 
-	checkMatch(t, []string{"a1/b1", "a2/b1"}, doGlob(t, naming.JoinAddressName(estr, "//mounttable"), "*/b1/...", rootID))
+	checkMatch(t, []string{"a1/b1", "a2/b1"}, doGlob(t, naming.JoinAddressName(estr, "//mounttable"), "*/b1/...", rootRT))
 	ft.advance(time.Duration(ttlSecs/2) * time.Second)
-	checkMatch(t, []string{"a1/b1", "a2/b1"}, doGlob(t, naming.JoinAddressName(estr, "//mounttable"), "*/b1/...", rootID))
-	checkMatch(t, []string{"c"}, doGlob(t, naming.JoinAddressName(estr, "//mounttable/a2/b2"), "*", rootID))
+	checkMatch(t, []string{"a1/b1", "a2/b1"}, doGlob(t, naming.JoinAddressName(estr, "//mounttable"), "*/b1/...", rootRT))
+	checkMatch(t, []string{"c"}, doGlob(t, naming.JoinAddressName(estr, "//mounttable/a2/b2"), "*", rootRT))
 	// Refresh only a1/b1.  All the other mounts will expire upon the next
 	// ft advance.
-	doMount(t, naming.JoinAddressName(estr, "//mounttable/a1/b1"), collectionName, true, rootID)
+	doMount(t, naming.JoinAddressName(estr, "//mounttable/a1/b1"), collectionName, true, rootRT)
 	ft.advance(time.Duration(ttlSecs/2+4) * time.Second)
-	checkMatch(t, []string{"a1"}, doGlob(t, naming.JoinAddressName(estr, "//mounttable"), "*", rootID))
-	checkMatch(t, []string{"a1/b1"}, doGlob(t, naming.JoinAddressName(estr, "//mounttable"), "*/b1/...", rootID))
+	checkMatch(t, []string{"a1"}, doGlob(t, naming.JoinAddressName(estr, "//mounttable"), "*", rootRT))
+	checkMatch(t, []string{"a1/b1"}, doGlob(t, naming.JoinAddressName(estr, "//mounttable"), "*/b1/...", rootRT))
 }
 
 func TestBadACLs(t *testing.T) {
@@ -475,3 +466,42 @@
 		boom(t, "Expected error for missing '/' acl")
 	}
 }
+
+func init() {
+	// Create the runtime for each of the three "processes"
+	rootRT = rt.Init(veyron2.ForceNewSecurityModel{})
+	var err error
+	if aliceRT, err = rt.New(veyron2.ForceNewSecurityModel{}); err != nil {
+		panic(err)
+	}
+	if bobRT, err = rt.New(veyron2.ForceNewSecurityModel{}); err != nil {
+		panic(err)
+	}
+
+	// And setup their blessings so that they present "root", "alice" and "bob"
+	// and these blessings are recognized by the others.
+	principals := map[string]security.Principal{
+		"root":  rootRT.Principal(),
+		"alice": aliceRT.Principal(),
+		"bob":   bobRT.Principal(),
+	}
+	for name, p := range principals {
+		blessing, err := p.BlessSelf(name)
+		if err != nil {
+			panic(fmt.Sprintf("BlessSelf(%q) failed: %v", name, err))
+		}
+		// Share this blessing with all servers and use it when serving clients.
+		if err = p.BlessingStore().SetDefault(blessing); err != nil {
+			panic(fmt.Sprintf("%v: %v", blessing, err))
+		}
+		if _, err = p.BlessingStore().Set(blessing, security.AllPrincipals); err != nil {
+			panic(fmt.Sprintf("%v: %v", blessing, err))
+		}
+		// Have all principals trust the root of this blessing.
+		for _, other := range principals {
+			if err := other.AddToRoots(blessing); err != nil {
+				panic(err)
+			}
+		}
+	}
+}
diff --git a/services/mounttable/lib/neighborhood_test.go b/services/mounttable/lib/neighborhood_test.go
index edccc7f..cb95d4c 100644
--- a/services/mounttable/lib/neighborhood_test.go
+++ b/services/mounttable/lib/neighborhood_test.go
@@ -7,9 +7,7 @@
 	"testing"
 	"time"
 
-	"veyron.io/veyron/veyron2"
 	"veyron.io/veyron/veyron2/naming"
-	"veyron.io/veyron/veyron2/rt"
 	"veyron.io/veyron/veyron2/services/mounttable"
 	"veyron.io/veyron/veyron2/vlog"
 
@@ -26,10 +24,8 @@
 }
 
 func TestNeighborhood(t *testing.T) {
-	r := rt.Init()
-	id := veyron2.LocalID(rt.R().Identity().PublicID())
 	vlog.Infof("TestNeighborhood")
-	server, err := r.NewServer()
+	server, err := rootRT.NewServer()
 	if err != nil {
 		boom(t, "r.NewServer: %s", err)
 	}
@@ -63,7 +59,7 @@
 	// Wait for the mounttable to appear in mdns
 L:
 	for tries := 1; tries < 2; tries++ {
-		names := doGlob(t, naming.JoinAddressName(estr, "//"), "*", id)
+		names := doGlob(t, naming.JoinAddressName(estr, "//"), "*", rootRT)
 		t.Logf("names %v", names)
 		for _, n := range names {
 			if n == serverName {
@@ -74,18 +70,18 @@
 	}
 
 	// Make sure we get back a root for the server.
-	want, got := []string{""}, doGlob(t, naming.JoinAddressName(estr, "//"+serverName), "", id)
+	want, got := []string{""}, doGlob(t, naming.JoinAddressName(estr, "//"+serverName), "", rootRT)
 	if !reflect.DeepEqual(want, got) {
 		t.Errorf("Unexpected Glob result want: %q, got: %q", want, got)
 	}
 
 	// Make sure we can resolve through the neighborhood.
 	expectedSuffix := "a/b"
-	objectPtr, err := mounttable.BindMountTable(naming.JoinAddressName(estr, "//"+serverName+"/"+expectedSuffix), quuxClient(id))
+	objectPtr, err := mounttable.BindMountTable(naming.JoinAddressName(estr, "//"+serverName+"/"+expectedSuffix), quuxClient(rootRT))
 	if err != nil {
 		boom(t, "BindMountTable: %s", err)
 	}
-	servers, suffix, err := objectPtr.ResolveStep(r.NewContext())
+	servers, suffix, err := objectPtr.ResolveStep(rootRT.NewContext())
 	if err != nil {
 		boom(t, "resolveStep: %s", err)
 	}
diff --git a/services/mounttable/lib/testdata/test.acl b/services/mounttable/lib/testdata/test.acl
index 9ffe006..597dda9 100644
--- a/services/mounttable/lib/testdata/test.acl
+++ b/services/mounttable/lib/testdata/test.acl
@@ -1,5 +1,5 @@
 {
-"/": {"In": {"fake/root": "RW", "...": "R"}},
-"/stuff": {"In": {"fake/root": "RW", "fake/bob": "R"}},
-"/a": {"In": {"fake/root": "RW", "fake/alice": "R"}}
+"/": {"In": {"root": "RW", "...": "R"}},
+"/stuff": {"In": {"root": "RW", "bob": "R"}},
+"/a": {"In": {"root": "RW", "alice": "R"}}
 }
\ No newline at end of file