Merge "services/tidyable: new tidyable service interface"
diff --git a/cmd/servicerunner/main.go b/cmd/servicerunner/main.go
index 34b7fe4..76e12e8 100644
--- a/cmd/servicerunner/main.go
+++ b/cmd/servicerunner/main.go
@@ -69,7 +69,7 @@
 	ctx, shutdown := v23.Init()
 	defer shutdown()
 
-	mt, err := mounttablelib.NewMountTableDispatcher("", "", "mounttable")
+	mt, err := mounttablelib.NewMountTableDispatcher(ctx, "", "", "mounttable")
 	if err != nil {
 		return fmt.Errorf("mounttablelib.NewMountTableDispatcher failed: %s", err)
 	}
diff --git a/examples/rps/rpsbot/impl_test.go b/examples/rps/rpsbot/impl_test.go
index ec2d3da..2e93780 100644
--- a/examples/rps/rpsbot/impl_test.go
+++ b/examples/rps/rpsbot/impl_test.go
@@ -33,7 +33,7 @@
 	ctx, shutdown := test.V23Init()
 	defer shutdown()
 
-	mt, err := mounttablelib.NewMountTableDispatcher("", "", "mounttable")
+	mt, err := mounttablelib.NewMountTableDispatcher(ctx, "", "", "mounttable")
 	if err != nil {
 		return fmt.Errorf("mounttablelib.NewMountTableDispatcher failed: %s", err)
 	}
diff --git a/lib/security/blessingstore.go b/lib/security/blessingstore.go
index 5ff62b7..0b09ee8 100644
--- a/lib/security/blessingstore.go
+++ b/lib/security/blessingstore.go
@@ -9,10 +9,13 @@
 
 import (
 	"bytes"
+	"crypto/sha256"
 	"fmt"
 	"reflect"
 	"sort"
+	"strings"
 	"sync"
+	"time"
 
 	"v.io/v23/security"
 	"v.io/v23/verror"
@@ -27,6 +30,8 @@
 	errDataOrSignerUnspecified = verror.Register(pkgPath+".errDataOrSignerUnspecified", verror.NoRetry, "{1:}{2:} persisted data or signer is not specified{:_}")
 )
 
+const cacheKeyFormat = uint32(1)
+
 // blessingStore implements security.BlessingStore.
 type blessingStore struct {
 	publicKey  security.PublicKey
@@ -116,6 +121,105 @@
 	return m
 }
 
+func (bs *blessingStore) CacheDischarge(discharge security.Discharge, caveat security.Caveat, impetus security.DischargeImpetus) {
+	id := discharge.ID()
+	tp := caveat.ThirdPartyDetails()
+	// Only add to the cache if the caveat did not require arguments.
+	if id == "" || tp == nil || tp.Requirements().ReportArguments {
+		return
+	}
+	key := dcacheKey(tp, impetus)
+	bs.mu.Lock()
+	defer bs.mu.Unlock()
+	old, hadold := bs.state.DischargeCache[key]
+	bs.state.DischargeCache[key] = discharge
+	if err := bs.save(); err != nil {
+		if hadold {
+			bs.state.DischargeCache[key] = old
+		} else {
+			delete(bs.state.DischargeCache, key)
+		}
+	}
+	return
+}
+
+func (bs *blessingStore) ClearDischarges(discharges ...security.Discharge) {
+	bs.mu.Lock()
+	bs.clearDischargesLocked(discharges...)
+	bs.mu.Unlock()
+	return
+}
+
+func (bs *blessingStore) clearDischargesLocked(discharges ...security.Discharge) {
+	for _, d := range discharges {
+		for k, cached := range bs.state.DischargeCache {
+			if cached.Equivalent(d) {
+				delete(bs.state.DischargeCache, k)
+			}
+		}
+	}
+}
+
+func (bs *blessingStore) Discharge(caveat security.Caveat, impetus security.DischargeImpetus) (out security.Discharge) {
+	defer bs.mu.Unlock()
+	bs.mu.Lock()
+	tp := caveat.ThirdPartyDetails()
+	if tp == nil || tp.Requirements().ReportArguments {
+		return
+	}
+	key := dcacheKey(tp, impetus)
+	if cached, exists := bs.state.DischargeCache[key]; exists {
+		out = cached
+		// If the discharge has expired, purge it from the cache.
+		if hasDischargeExpired(out) {
+			out = security.Discharge{}
+			bs.clearDischargesLocked(cached)
+		}
+	}
+	return
+}
+
+func hasDischargeExpired(dis security.Discharge) bool {
+	expiry := dis.Expiry()
+	if expiry.IsZero() {
+		return false
+	}
+	return expiry.Before(time.Now())
+}
+
+func dcacheKey(tp security.ThirdPartyCaveat, impetus security.DischargeImpetus) dischargeCacheKey {
+	// If the algorithm for computing dcacheKey changes, cacheKeyFormat must be changed as well.
+	id := tp.ID()
+	r := tp.Requirements()
+	var method, servers string
+	// We currently do not cache on impetus.Arguments because there it seems there is no
+	// general way to generate a key from them.
+	if r.ReportMethod {
+		method = impetus.Method
+	}
+	if r.ReportServer && len(impetus.Server) > 0 {
+		// Sort the server blessing patterns to increase cache usage.
+		var bps []string
+		for _, bp := range impetus.Server {
+			bps = append(bps, string(bp))
+		}
+		sort.Strings(bps)
+		servers = strings.Join(bps, ",")
+	}
+	h := sha256.New()
+	h.Write(hashString(id))
+	h.Write(hashString(method))
+	h.Write(hashString(servers))
+	var key [sha256.Size]byte
+	copy(key[:], h.Sum(nil))
+	return key
+}
+
+func hashString(d string) []byte {
+	h := sha256.Sum256([]byte(d))
+	return h[:]
+}
+
 // DebugString return a human-readable string encoding of the store
 // in the following format
 // Default Blessings <blessings>
@@ -158,7 +262,10 @@
 func newInMemoryBlessingStore(publicKey security.PublicKey) security.BlessingStore {
 	return &blessingStore{
 		publicKey: publicKey,
-		state:     blessingStoreState{PeerBlessings: make(map[security.BlessingPattern]security.Blessings)},
+		state: blessingStoreState{
+			PeerBlessings:  make(map[security.BlessingPattern]security.Blessings),
+			DischargeCache: make(map[dischargeCacheKey]security.Discharge),
+		},
 	}
 }
 
@@ -185,6 +292,10 @@
 	if err := decodeFromStorage(&bs.state, data, signature, bs.signer.PublicKey()); err != nil {
 		return err
 	}
+	if bs.state.CacheKeyFormat != cacheKeyFormat {
+		bs.state.CacheKeyFormat = cacheKeyFormat
+		bs.state.DischargeCache = make(map[dischargeCacheKey]security.Discharge)
+	}
 	return bs.verifyState()
 }
 
@@ -197,12 +308,17 @@
 	}
 	bs := &blessingStore{
 		publicKey:  signer.PublicKey(),
-		state:      blessingStoreState{PeerBlessings: make(map[security.BlessingPattern]security.Blessings)},
 		serializer: serializer,
 		signer:     signer,
 	}
 	if err := bs.deserialize(); err != nil {
 		return nil, err
 	}
+	if bs.state.PeerBlessings == nil {
+		bs.state.PeerBlessings = make(map[security.BlessingPattern]security.Blessings)
+	}
+	if bs.state.DischargeCache == nil {
+		bs.state.DischargeCache = make(map[dischargeCacheKey]security.Discharge)
+	}
 	return bs, nil
 }
diff --git a/lib/security/blessingstore_test.go b/lib/security/blessingstore_test.go
index 339cd59..01cc3df 100644
--- a/lib/security/blessingstore_test.go
+++ b/lib/security/blessingstore_test.go
@@ -140,6 +140,7 @@
 	if err := tester.testSetDefault(s); err != nil {
 		t.Error(err)
 	}
+	testDischargeCache(t, s)
 }
 
 func TestBlessingStorePersistence(t *testing.T) {
@@ -164,6 +165,7 @@
 	if err := tester.testSetDefault(s); err != nil {
 		t.Error(err)
 	}
+	testDischargeCache(t, s)
 
 	// Recreate the BlessingStore from the directory.
 	p2, err := LoadPersistentPrincipal(dir, nil)
diff --git a/lib/security/discharge_cache_test.go b/lib/security/discharge_cache_test.go
new file mode 100644
index 0000000..f974d1a
--- /dev/null
+++ b/lib/security/discharge_cache_test.go
@@ -0,0 +1,105 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package security
+
+import (
+	"testing"
+	"time"
+
+	"v.io/v23/security"
+	"v.io/v23/vdl"
+)
+
+func testDischargeCache(t *testing.T, s security.BlessingStore) {
+	var (
+		discharger = mkPrincipal()
+		expiredCav = mkCaveat(security.NewPublicKeyCaveat(discharger.PublicKey(), "moline", security.ThirdPartyRequirements{}, security.UnconstrainedUse()))
+		argsCav    = mkCaveat(security.NewPublicKeyCaveat(discharger.PublicKey(), "peoria", security.ThirdPartyRequirements{ReportArguments: true}, security.UnconstrainedUse()))
+		methodCav  = mkCaveat(security.NewPublicKeyCaveat(discharger.PublicKey(), "moline", security.ThirdPartyRequirements{ReportMethod: true}, security.UnconstrainedUse()))
+		serverCav  = mkCaveat(security.NewPublicKeyCaveat(discharger.PublicKey(), "peoria", security.ThirdPartyRequirements{ReportServer: true}, security.UnconstrainedUse()))
+
+		dEmpty   = security.Discharge{}
+		dExpired = mkDischarge(discharger.MintDischarge(expiredCav, mkCaveat(security.NewExpiryCaveat(time.Now().Add(-1*time.Minute)))))
+		dArgs    = mkDischarge(discharger.MintDischarge(argsCav, security.UnconstrainedUse()))
+		dMethod  = mkDischarge(discharger.MintDischarge(methodCav, security.UnconstrainedUse()))
+		dServer  = mkDischarge(discharger.MintDischarge(serverCav, security.UnconstrainedUse()))
+
+		emptyImp       = security.DischargeImpetus{}
+		argsImp        = security.DischargeImpetus{Arguments: []*vdl.Value{&vdl.Value{}}}
+		methodImp      = security.DischargeImpetus{Method: "foo"}
+		otherMethodImp = security.DischargeImpetus{Method: "bar"}
+		serverImp      = security.DischargeImpetus{Server: []security.BlessingPattern{security.BlessingPattern("fooserver")}}
+		otherServerImp = security.DischargeImpetus{Server: []security.BlessingPattern{security.BlessingPattern("barserver")}}
+	)
+
+	// Discharges for different cavs should not be cached.
+	d := mkDischarge(discharger.MintDischarge(argsCav, security.UnconstrainedUse()))
+	s.CacheDischarge(d, argsCav, emptyImp)
+	if d := s.Discharge(methodCav, emptyImp); d.ID() != "" {
+		t.Errorf("Discharge for different caveat should not have been in cache")
+	}
+	s.ClearDischarges(d)
+
+	// Add some discharges into the cache.
+	s.CacheDischarge(dArgs, argsCav, argsImp)
+	s.CacheDischarge(dMethod, methodCav, methodImp)
+	s.CacheDischarge(dServer, serverCav, serverImp)
+	s.CacheDischarge(dExpired, expiredCav, emptyImp)
+
+	testCases := []struct {
+		caveat          security.Caveat           // caveat that we are fetching discharges for.
+		queryImpetus    security.DischargeImpetus // Impetus used to  query the cache.
+		cachedDischarge security.Discharge        // Discharge that we expect to be returned from the cache, nil if the discharge should not be cached.
+	}{
+		// Expired discharges should not be returned by the cache.
+		{expiredCav, emptyImp, dEmpty},
+
+		// Discharges with Impetuses that have Arguments should not be cached.
+		{argsCav, argsImp, dEmpty},
+
+		{methodCav, methodImp, dMethod},
+		{methodCav, otherMethodImp, dEmpty},
+		{methodCav, emptyImp, dEmpty},
+
+		{serverCav, serverImp, dServer},
+		{serverCav, otherServerImp, dEmpty},
+		{serverCav, emptyImp, dEmpty},
+	}
+
+	for i, test := range testCases {
+		out := s.Discharge(test.caveat, test.queryImpetus)
+		if got := out.ID(); got != test.cachedDischarge.ID() {
+			t.Errorf("#%d: got discharge %v, want %v, queried with %v", i, got, test.cachedDischarge.ID(), test.queryImpetus)
+		}
+	}
+	if t.Failed() {
+		t.Logf("dArgs.ID():    %v", dArgs.ID())
+		t.Logf("dMethod.ID():  %v", dMethod.ID())
+		t.Logf("dServer.ID():  %v", dServer.ID())
+		t.Logf("dExpired.ID(): %v", dExpired.ID())
+	}
+}
+
+func mkPrincipal() security.Principal {
+	p, err := NewPrincipal()
+	if err != nil {
+		panic(err)
+	}
+	return p
+}
+
+func mkDischarge(d security.Discharge, err error) security.Discharge {
+	if err != nil {
+		panic(err)
+	}
+	return d
+}
+
+func mkCaveat(c security.Caveat, err error) security.Caveat {
+	if err != nil {
+		panic(err)
+	}
+	return c
+}
diff --git a/lib/security/type.vdl b/lib/security/type.vdl
index 9d65571..9539700 100644
--- a/lib/security/type.vdl
+++ b/lib/security/type.vdl
@@ -18,4 +18,11 @@
 	// DefaultBlessings is the default Blessings to be shared with peers for which
 	// no other information is available to select blessings.
 	DefaultBlessings security.WireBlessings
+	// DischargeCache is the cache of discharges.
+	DischargeCache map[dischargeCacheKey]security.WireDischarge
+	// CacheKeyFormat is the dischargeCacheKey format version. It should incremented
+	// any time the format of the dischargeCacheKey is changed.
+	CacheKeyFormat uint32
 }
+
+type dischargeCacheKey [32]byte
diff --git a/lib/security/type.vdl.go b/lib/security/type.vdl.go
index 3fabed7..5681451 100644
--- a/lib/security/type.vdl.go
+++ b/lib/security/type.vdl.go
@@ -32,6 +32,11 @@
 	// DefaultBlessings is the default Blessings to be shared with peers for which
 	// no other information is available to select blessings.
 	DefaultBlessings security.Blessings
+	// DischargeCache is the cache of discharges.
+	DischargeCache map[dischargeCacheKey]security.Discharge
+	// CacheKeyFormat is the dischargeCacheKey format version. It should incremented
+	// any time the format of the dischargeCacheKey is changed.
+	CacheKeyFormat uint32
 }
 
 func (blessingStoreState) __VDLReflect(struct {
@@ -39,7 +44,15 @@
 }) {
 }
 
+type dischargeCacheKey [32]byte
+
+func (dischargeCacheKey) __VDLReflect(struct {
+	Name string `vdl:"v.io/x/ref/lib/security.dischargeCacheKey"`
+}) {
+}
+
 func init() {
 	vdl.Register((*blessingRootsState)(nil))
 	vdl.Register((*blessingStoreState)(nil))
+	vdl.Register((*dischargeCacheKey)(nil))
 }
diff --git a/runtime/internal/naming/namespace/all_test.go b/runtime/internal/naming/namespace/all_test.go
index 58be9fa..a27c68e 100644
--- a/runtime/internal/naming/namespace/all_test.go
+++ b/runtime/internal/naming/namespace/all_test.go
@@ -212,7 +212,7 @@
 }
 
 func runMT(t *testing.T, ctx *context.T, mountPoint string) *serverEntry {
-	mtd, err := mounttablelib.NewMountTableDispatcher("", "", "mounttable")
+	mtd, err := mounttablelib.NewMountTableDispatcher(ctx, "", "", "mounttable")
 	if err != nil {
 		boom(t, "NewMountTableDispatcher returned error: %v", err)
 	}
diff --git a/runtime/internal/rpc/client.go b/runtime/internal/rpc/client.go
index d7aa5b8..9c81d74 100644
--- a/runtime/internal/rpc/client.go
+++ b/runtime/internal/rpc/client.go
@@ -1018,7 +1018,7 @@
 			// to detect it, we conservatively flush all discharges we used from the cache.
 			// TODO(ataly,andreser): add verror.BadDischarge and handle it explicitly?
 			vlog.VI(3).Infof("Discarding %d discharges as RPC failed with %v", len(fc.discharges), fc.response.Error)
-			fc.dc.Invalidate(fc.discharges...)
+			fc.dc.Invalidate(fc.ctx, fc.discharges...)
 		}
 		if id == errBadNumInputArgs.ID || id == errBadInputArg.ID {
 			return fc.close(verror.New(verror.ErrBadProtocol, fc.ctx, fc.response.Error))
diff --git a/runtime/internal/rpc/discharges.go b/runtime/internal/rpc/discharges.go
index 46017ee..d69e349 100644
--- a/runtime/internal/rpc/discharges.go
+++ b/runtime/internal/rpc/discharges.go
@@ -5,14 +5,13 @@
 package rpc
 
 import (
-	"sort"
-	"strings"
 	"sync"
 	"time"
 
 	"v.io/x/ref/lib/apilog"
 	"v.io/x/ref/runtime/internal/rpc/stream/vc"
 
+	"v.io/v23"
 	"v.io/v23/context"
 	"v.io/v23/rpc"
 	"v.io/v23/security"
@@ -35,7 +34,6 @@
 type dischargeClient struct {
 	c                     rpc.Client
 	defaultCtx            *context.T
-	cache                 dischargeCache
 	dischargeExpiryBuffer time.Duration
 }
 
@@ -51,12 +49,8 @@
 // Attempts will be made to refresh a discharge DischargeExpiryBuffer before they expire.
 func InternalNewDischargeClient(defaultCtx *context.T, client rpc.Client, dischargeExpiryBuffer time.Duration) vc.DischargeClient {
 	return &dischargeClient{
-		c:          client,
-		defaultCtx: defaultCtx,
-		cache: dischargeCache{
-			cache:    make(map[dischargeCacheKey]security.Discharge),
-			idToKeys: make(map[string][]dischargeCacheKey),
-		},
+		c:                     client,
+		defaultCtx:            defaultCtx,
 		dischargeExpiryBuffer: dischargeExpiryBuffer,
 	}
 }
@@ -85,15 +79,15 @@
 		}
 	}
 
+	if ctx == nil {
+		ctx = d.defaultCtx
+	}
+	bstore := v23.GetPrincipal(ctx).BlessingStore()
 	// Gather discharges from cache.
-	// (Collect a set of pointers, where nil implies a missing discharge)
-	discharges := make([]*security.Discharge, len(caveats))
-	if d.cache.Discharges(caveats, filteredImpetuses, discharges) > 0 {
+	discharges, rem := discharges(bstore, caveats, impetus)
+	if rem > 0 {
 		// Fetch discharges for caveats for which no discharges were
 		// found in the cache.
-		if ctx == nil {
-			ctx = d.defaultCtx
-		}
 		if ctx != nil {
 			var span vtrace.Span
 			ctx, span = vtrace.WithNewSpan(ctx, "Fetching Discharges")
@@ -102,14 +96,30 @@
 		d.fetchDischarges(ctx, caveats, filteredImpetuses, discharges)
 	}
 	for _, d := range discharges {
-		if d != nil {
-			ret = append(ret, *d)
+		if d.ID() != "" {
+			ret = append(ret, d)
 		}
 	}
 	return
 }
-func (d *dischargeClient) Invalidate(discharges ...security.Discharge) {
-	d.cache.invalidate(discharges...)
+
+func discharges(bs security.BlessingStore, caveats []security.Caveat, imp security.DischargeImpetus) (out []security.Discharge, rem int) {
+	out = make([]security.Discharge, len(caveats))
+	for i := range caveats {
+		out[i] = bs.Discharge(caveats[i], imp)
+		if out[i].ID() == "" {
+			rem++
+		}
+	}
+	return
+}
+
+func (d *dischargeClient) Invalidate(ctx *context.T, discharges ...security.Discharge) {
+	if ctx == nil {
+		ctx = d.defaultCtx
+	}
+	bstore := v23.GetPrincipal(ctx).BlessingStore()
+	bstore.ClearDischarges(discharges...)
 }
 
 // fetchDischarges fills out by fetching discharges for caveats from the
@@ -118,12 +128,14 @@
 // fetched or no new discharges are fetched.
 // REQUIRES: len(caveats) == len(out)
 // REQUIRES: caveats[i].ThirdPartyDetails() != nil for 0 <= i < len(caveats)
-func (d *dischargeClient) fetchDischarges(ctx *context.T, caveats []security.Caveat, impetuses []security.DischargeImpetus, out []*security.Discharge) {
+func (d *dischargeClient) fetchDischarges(ctx *context.T, caveats []security.Caveat, impetuses []security.DischargeImpetus, out []security.Discharge) {
+	bstore := v23.GetPrincipal(ctx).BlessingStore()
 	var wg sync.WaitGroup
 	for {
 		type fetched struct {
 			idx       int
-			discharge *security.Discharge
+			discharge security.Discharge
+			caveat    security.Caveat
 			impetus   security.DischargeImpetus
 		}
 		discharges := make(chan fetched, len(caveats))
@@ -143,14 +155,14 @@
 					vlog.VI(3).Infof("Discharge fetch for %v failed: %v", tp, err)
 					return
 				}
-				discharges <- fetched{i, &dis, impetuses[i]}
+				discharges <- fetched{i, dis, caveats[i], impetuses[i]}
 			}(i, ctx, caveats[i])
 		}
 		wg.Wait()
 		close(discharges)
 		var got int
 		for fetched := range discharges {
-			d.cache.Add(*fetched.discharge, fetched.impetus)
+			bstore.CacheDischarge(fetched.discharge, fetched.caveat, fetched.impetus)
 			out[fetched.idx] = fetched.discharge
 			got++
 		}
@@ -163,117 +175,6 @@
 	}
 }
 
-func (d *dischargeClient) shouldFetchDischarge(dis *security.Discharge) bool {
-	if dis == nil {
-		return true
-	}
-	expiry := dis.Expiry()
-	if expiry.IsZero() {
-		return false
-	}
-	return expiry.Before(time.Now().Add(d.dischargeExpiryBuffer))
-}
-
-// dischargeCache is a concurrency-safe cache for third party caveat discharges.
-type dischargeCache struct {
-	mu       sync.RWMutex
-	cache    map[dischargeCacheKey]security.Discharge // GUARDED_BY(mu)
-	idToKeys map[string][]dischargeCacheKey           // GUARDED_BY(mu)
-}
-
-type dischargeCacheKey struct {
-	id, method, serverPatterns string
-}
-
-func (dcc *dischargeCache) cacheKey(id string, impetus security.DischargeImpetus) dischargeCacheKey {
-	// We currently do not cache on impetus.Arguments because there it seems there is no
-	// universal way to generate a key from them.
-	// Add sorted BlessingPatterns to the key.
-	var bps []string
-	for _, bp := range impetus.Server {
-		bps = append(bps, string(bp))
-	}
-	sort.Strings(bps)
-	return dischargeCacheKey{
-		id:             id,
-		method:         impetus.Method,
-		serverPatterns: strings.Join(bps, ","), // "," is restricted in blessingPatterns.
-	}
-}
-
-// Add inserts the argument to the cache, the previous discharge for the same caveat.
-func (dcc *dischargeCache) Add(d security.Discharge, filteredImpetus security.DischargeImpetus) {
-	// Only add to the cache if the caveat did not require arguments.
-	if len(filteredImpetus.Arguments) > 0 {
-		return
-	}
-	id := d.ID()
-	dcc.mu.Lock()
-	dcc.cache[dcc.cacheKey(id, filteredImpetus)] = d
-	if _, ok := dcc.idToKeys[id]; !ok {
-		dcc.idToKeys[id] = []dischargeCacheKey{}
-	}
-	dcc.idToKeys[id] = append(dcc.idToKeys[id], dcc.cacheKey(id, filteredImpetus))
-	dcc.mu.Unlock()
-}
-
-// Discharges takes a slice of caveats, a slice of filtered Discharge impetuses
-// corresponding to the caveats, and a slice of discharges of the same length and
-// fills in nil entries in the discharges slice with pointers to cached discharges
-// (if there are any).
-//
-// REQUIRES: len(caveats) == len(impetuses) == len(out)
-// REQUIRES: caveats[i].ThirdPartyDetails() != nil, for all 0 <= i < len(caveats)
-func (dcc *dischargeCache) Discharges(caveats []security.Caveat, impetuses []security.DischargeImpetus, out []*security.Discharge) (remaining int) {
-	dcc.mu.Lock()
-	for i, d := range out {
-		if d != nil {
-			continue
-		}
-		id := caveats[i].ThirdPartyDetails().ID()
-		key := dcc.cacheKey(id, impetuses[i])
-		if cached, exists := dcc.cache[key]; exists {
-			out[i] = &cached
-			// If the discharge has expired, purge it from the cache.
-			if hasDischargeExpired(out[i]) {
-				out[i] = nil
-				delete(dcc.cache, key)
-				remaining++
-			}
-		} else {
-			remaining++
-		}
-	}
-	dcc.mu.Unlock()
-	return
-}
-
-func hasDischargeExpired(dis *security.Discharge) bool {
-	expiry := dis.Expiry()
-	if expiry.IsZero() {
-		return false
-	}
-	return expiry.Before(time.Now())
-}
-
-func (dcc *dischargeCache) invalidate(discharges ...security.Discharge) {
-	dcc.mu.Lock()
-	for _, d := range discharges {
-		if keys, ok := dcc.idToKeys[d.ID()]; ok {
-			var newKeys []dischargeCacheKey
-			for _, k := range keys {
-				if cached := dcc.cache[k]; cached.Equivalent(d) {
-					delete(dcc.cache, k)
-				} else {
-					newKeys = append(newKeys, k)
-				}
-			}
-			dcc.idToKeys[d.ID()] = newKeys
-		}
-	}
-	dcc.mu.Unlock()
-}
-
 // filteredImpetus returns a copy of 'before' after removing any values that are not required as per 'r'.
 func filteredImpetus(r security.ThirdPartyRequirements, before security.DischargeImpetus) (after security.DischargeImpetus) {
 	if r.ReportServer && len(before.Server) > 0 {
@@ -293,3 +194,14 @@
 	}
 	return
 }
+
+func (d *dischargeClient) shouldFetchDischarge(dis security.Discharge) bool {
+	if dis.ID() == "" {
+		return true
+	}
+	expiry := dis.Expiry()
+	if expiry.IsZero() {
+		return false
+	}
+	return expiry.Before(time.Now().Add(d.dischargeExpiryBuffer))
+}
diff --git a/runtime/internal/rpc/discharges_test.go b/runtime/internal/rpc/discharges_test.go
deleted file mode 100644
index 7b67b1b..0000000
--- a/runtime/internal/rpc/discharges_test.go
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package rpc
-
-import (
-	"testing"
-	"time"
-
-	"v.io/v23/security"
-	"v.io/v23/vdl"
-	"v.io/x/ref/test/testutil"
-)
-
-func TestDischargeClientCache(t *testing.T) {
-	dcc := &dischargeCache{
-		cache:    make(map[dischargeCacheKey]security.Discharge),
-		idToKeys: make(map[string][]dischargeCacheKey),
-	}
-
-	var (
-		discharger = testutil.NewPrincipal("discharger")
-		expiredCav = mkCaveat(security.NewPublicKeyCaveat(discharger.PublicKey(), "moline", security.ThirdPartyRequirements{}, security.UnconstrainedUse()))
-		argsCav    = mkCaveat(security.NewPublicKeyCaveat(discharger.PublicKey(), "moline", security.ThirdPartyRequirements{}, security.UnconstrainedUse()))
-		methodCav  = mkCaveat(security.NewPublicKeyCaveat(discharger.PublicKey(), "moline", security.ThirdPartyRequirements{}, security.UnconstrainedUse()))
-		serverCav  = mkCaveat(security.NewPublicKeyCaveat(discharger.PublicKey(), "moline", security.ThirdPartyRequirements{}, security.UnconstrainedUse()))
-
-		dExpired = mkDischarge(discharger.MintDischarge(expiredCav, mkCaveat(security.NewExpiryCaveat(time.Now().Add(-1*time.Minute)))))
-		dArgs    = mkDischarge(discharger.MintDischarge(argsCav, security.UnconstrainedUse()))
-		dMethod  = mkDischarge(discharger.MintDischarge(methodCav, security.UnconstrainedUse()))
-		dServer  = mkDischarge(discharger.MintDischarge(serverCav, security.UnconstrainedUse()))
-
-		emptyImp       = security.DischargeImpetus{}
-		argsImp        = security.DischargeImpetus{Arguments: []*vdl.Value{&vdl.Value{}}}
-		methodImp      = security.DischargeImpetus{Method: "foo"}
-		otherMethodImp = security.DischargeImpetus{Method: "bar"}
-		serverImp      = security.DischargeImpetus{Server: []security.BlessingPattern{security.BlessingPattern("fooserver")}}
-		otherServerImp = security.DischargeImpetus{Server: []security.BlessingPattern{security.BlessingPattern("barserver")}}
-	)
-
-	// Discharges for different cavs should not be cached.
-	d := mkDischarge(discharger.MintDischarge(argsCav, security.UnconstrainedUse()))
-	dcc.Add(d, emptyImp)
-	outdis := make([]*security.Discharge, 1)
-	if remaining := dcc.Discharges([]security.Caveat{methodCav}, []security.DischargeImpetus{emptyImp}, outdis); remaining == 0 {
-		t.Errorf("Discharge for different caveat should not have been in cache")
-	}
-	dcc.invalidate(d)
-
-	// Add some discharges into the cache.
-	dcc.Add(dArgs, argsImp)
-	dcc.Add(dMethod, methodImp)
-	dcc.Add(dServer, serverImp)
-	dcc.Add(dExpired, emptyImp)
-
-	testCases := []struct {
-		caveat          security.Caveat           // caveat that we are fetching discharges for.
-		queryImpetus    security.DischargeImpetus // Impetus used to  query the cache.
-		cachedDischarge *security.Discharge       // Discharge that we expect to be returned from the cache, nil if the discharge should not be cached.
-	}{
-		// Expired discharges should not be returned by the cache.
-		{expiredCav, emptyImp, nil},
-
-		// Discharges with Impetuses that have Arguments should not be cached.
-		{argsCav, argsImp, nil},
-
-		{methodCav, methodImp, &dMethod},
-		{methodCav, otherMethodImp, nil},
-		{methodCav, emptyImp, nil},
-
-		{serverCav, serverImp, &dServer},
-		{serverCav, otherServerImp, nil},
-		{serverCav, emptyImp, nil},
-	}
-
-	for i, test := range testCases {
-		out := make([]*security.Discharge, 1)
-		remaining := dcc.Discharges([]security.Caveat{test.caveat}, []security.DischargeImpetus{test.queryImpetus}, out)
-		if test.cachedDischarge != nil {
-			got := "nil"
-			if remaining == 0 {
-				got = out[0].ID()
-			}
-			if got != test.cachedDischarge.ID() {
-				t.Errorf("#%d: got discharge %v, want %v, queried with %v", i, got, test.cachedDischarge.ID(), test.queryImpetus)
-			}
-		} else if remaining == 0 {
-			t.Errorf("#%d: discharge %v should not have been in cache, queried with %v", i, out[0].ID(), test.queryImpetus)
-		}
-	}
-	if t.Failed() {
-		t.Logf("dArgs.ID():    %v", dArgs.ID())
-		t.Logf("dMethod.ID():  %v", dMethod.ID())
-		t.Logf("dServer.ID():  %v", dServer.ID())
-		t.Logf("dExpired.ID(): %v", dExpired.ID())
-	}
-}
-
-func mkDischarge(d security.Discharge, err error) security.Discharge {
-	if err != nil {
-		panic(err)
-	}
-	return d
-}
diff --git a/runtime/internal/rpc/full_test.go b/runtime/internal/rpc/full_test.go
index f60009b..8224776 100644
--- a/runtime/internal/rpc/full_test.go
+++ b/runtime/internal/rpc/full_test.go
@@ -1193,6 +1193,15 @@
 func (*singleBlessingStore) PeerBlessings() map[security.BlessingPattern]security.Blessings {
 	return nil
 }
+func (*singleBlessingStore) CacheDischarge(security.Discharge, security.Caveat, security.DischargeImpetus) {
+	return
+}
+func (*singleBlessingStore) ClearDischarges(...security.Discharge) {
+	return
+}
+func (*singleBlessingStore) Discharge(security.Caveat, security.DischargeImpetus) security.Discharge {
+	return security.Discharge{}
+}
 
 // singleBlessingPrincipal implements security.Principal. It is a wrapper over
 // a security.Principal that intercepts  all invocations on the
diff --git a/runtime/internal/rpc/resolve_test.go b/runtime/internal/rpc/resolve_test.go
index 2c33e04..da3649f 100644
--- a/runtime/internal/rpc/resolve_test.go
+++ b/runtime/internal/rpc/resolve_test.go
@@ -72,7 +72,7 @@
 	defer shutdown()
 
 	mp := ""
-	mt, err := mounttablelib.NewMountTableDispatcher("", "", "mounttable")
+	mt, err := mounttablelib.NewMountTableDispatcher(ctx, "", "", "mounttable")
 	if err != nil {
 		return fmt.Errorf("mounttablelib.NewMountTableDispatcher failed: %s", err)
 	}
diff --git a/runtime/internal/rpc/stream/vc/vc.go b/runtime/internal/rpc/stream/vc/vc.go
index 12c2527..805a07f 100644
--- a/runtime/internal/rpc/stream/vc/vc.go
+++ b/runtime/internal/rpc/stream/vc/vc.go
@@ -199,7 +199,7 @@
 	PrepareDischarges(ctx *context.T, forcaveats []security.Caveat, impetus security.DischargeImpetus) []security.Discharge
 	// Invalidate marks the provided discharges as invalid, and therefore unfit
 	// for being returned by a subsequent PrepareDischarges call.
-	Invalidate(discharges ...security.Discharge)
+	Invalidate(ctx *context.T, discharges ...security.Discharge)
 	RPCStreamListenerOpt()
 }
 
diff --git a/runtime/internal/rpc/stream/vc/vc_test.go b/runtime/internal/rpc/stream/vc/vc_test.go
index e42c385..6e2737f 100644
--- a/runtime/internal/rpc/stream/vc/vc_test.go
+++ b/runtime/internal/rpc/stream/vc/vc_test.go
@@ -170,9 +170,9 @@
 func (m mockDischargeClient) PrepareDischarges(_ *context.T, forcaveats []security.Caveat, impetus security.DischargeImpetus) []security.Discharge {
 	return m
 }
-func (mockDischargeClient) Invalidate(...security.Discharge) {}
-func (mockDischargeClient) RPCStreamListenerOpt()            {}
-func (mockDischargeClient) RPCStreamVCOpt()                  {}
+func (mockDischargeClient) Invalidate(*context.T, ...security.Discharge) {}
+func (mockDischargeClient) RPCStreamListenerOpt()                        {}
+func (mockDischargeClient) RPCStreamVCOpt()                              {}
 
 // Test that mockDischargeClient implements vc.DischargeClient.
 var _ vc.DischargeClient = (mockDischargeClient)(nil)
diff --git a/runtime/internal/rpc/test/client_test.go b/runtime/internal/rpc/test/client_test.go
index e131796..c886455 100644
--- a/runtime/internal/rpc/test/client_test.go
+++ b/runtime/internal/rpc/test/client_test.go
@@ -52,7 +52,7 @@
 	ctx, shutdown := v23.Init()
 	defer shutdown()
 
-	mt, err := mounttablelib.NewMountTableDispatcher("", "", "mounttable")
+	mt, err := mounttablelib.NewMountTableDispatcher(ctx, "", "", "mounttable")
 	if err != nil {
 		return fmt.Errorf("mounttablelib.NewMountTableDispatcher failed: %s", err)
 	}
diff --git a/runtime/internal/vtrace/vtrace_test.go b/runtime/internal/vtrace/vtrace_test.go
index dbdb299..2a12083 100644
--- a/runtime/internal/vtrace/vtrace_test.go
+++ b/runtime/internal/vtrace/vtrace_test.go
@@ -43,7 +43,7 @@
 		t.Fatalf("Could not bless initial principal %v", err)
 	}
 	// Start a local mounttable.
-	disp, err := mounttablelib.NewMountTableDispatcher("", "", "mounttable")
+	disp, err := mounttablelib.NewMountTableDispatcher(ctx, "", "", "mounttable")
 	if err != nil {
 		t.Fatalf("Could not create mt dispatcher %v", err)
 	}
diff --git a/services/agent/agentlib/client.go b/services/agent/agentlib/client.go
index 7dc2c3c..e3b33eb 100644
--- a/services/agent/agentlib/client.go
+++ b/services/agent/agentlib/client.go
@@ -169,7 +169,7 @@
 func (c *client) BlessingsByName(pattern security.BlessingPattern) []security.Blessings {
 	var blessings []security.Blessings
 	if err := c.caller.call("BlessingsByName", results(&blessings), pattern); err != nil {
-		vlog.Errorf("error calling BlessingsByName: %v", err)
+		vlog.Infof("error calling BlessingsByName: %v", err)
 		return nil
 	}
 	return blessings
@@ -179,7 +179,7 @@
 	var bInfo map[string][]security.Caveat
 	err := c.caller.call("BlessingsInfo", results(&bInfo), blessings)
 	if err != nil {
-		vlog.Errorf("error calling BlessingsInfo: %v", err)
+		vlog.Infof("error calling BlessingsInfo: %v", err)
 		return nil
 	}
 	return bInfo
@@ -210,7 +210,7 @@
 func (b *blessingStore) ForPeer(peerBlessings ...string) security.Blessings {
 	var blessings security.Blessings
 	if err := b.caller.call("BlessingStoreForPeer", results(&blessings), peerBlessings); err != nil {
-		vlog.Errorf("error calling BlessingStorePeerBlessings: %v", err)
+		vlog.Infof("error calling BlessingStorePeerBlessings: %v", err)
 	}
 	return blessings
 }
@@ -223,7 +223,7 @@
 	var blessings security.Blessings
 	err := b.caller.call("BlessingStoreDefault", results(&blessings))
 	if err != nil {
-		vlog.Errorf("error calling BlessingStoreDefault: %v", err)
+		vlog.Infof("error calling BlessingStoreDefault: %v", err)
 		return security.Blessings{}
 	}
 	return blessings
@@ -237,7 +237,7 @@
 	var bmap map[security.BlessingPattern]security.Blessings
 	err := b.caller.call("BlessingStorePeerBlessings", results(&bmap))
 	if err != nil {
-		vlog.Errorf("error calling BlessingStorePeerBlessings: %v", err)
+		vlog.Infof("error calling BlessingStorePeerBlessings: %v", err)
 		return nil
 	}
 	return bmap
@@ -247,7 +247,29 @@
 	err := b.caller.call("BlessingStoreDebugString", results(&s))
 	if err != nil {
 		s = fmt.Sprintf("error calling BlessingStoreDebugString: %v", err)
-		vlog.Errorf(s)
+		vlog.Infof(s)
+	}
+	return
+}
+
+func (b *blessingStore) CacheDischarge(d security.Discharge, c security.Caveat, i security.DischargeImpetus) {
+	err := b.caller.call("BlessingStoreCacheDischarge", results(), d, c, i)
+	if err != nil {
+		vlog.Infof("error calling BlessingStoreCacheDischarge: %v", err)
+	}
+}
+
+func (b *blessingStore) ClearDischarges(discharges ...security.Discharge) {
+	err := b.caller.call("BlessingStoreClearDischarges", results(), discharges)
+	if err != nil {
+		vlog.Infof("error calling BlessingStoreClearDischarges: %v", err)
+	}
+}
+
+func (b *blessingStore) Discharge(caveat security.Caveat, impetus security.DischargeImpetus) (out security.Discharge) {
+	err := b.caller.call("BlessingStoreDischarge", results(&out), caveat, impetus)
+	if err != nil {
+		vlog.Infof("error calling BlessingStoreDischarge: %v", err)
 	}
 	return
 }
@@ -275,7 +297,7 @@
 func (b *blessingRoots) Dump() map[security.BlessingPattern][]security.PublicKey {
 	var marshaledRoots map[security.BlessingPattern][][]byte
 	if err := b.caller.call("BlessingRootsDump", results(&marshaledRoots)); err != nil {
-		vlog.Errorf("error calling BlessingRootsDump: %v", err)
+		vlog.Infof("error calling BlessingRootsDump: %v", err)
 		return nil
 	}
 	ret := make(map[security.BlessingPattern][]security.PublicKey)
@@ -283,7 +305,7 @@
 		for _, marshaledKey := range marshaledKeys {
 			key, err := security.UnmarshalPublicKey(marshaledKey)
 			if err != nil {
-				vlog.Errorf("security.UnmarshalPublicKey(%v) returned error: %v", marshaledKey, err)
+				vlog.Infof("security.UnmarshalPublicKey(%v) returned error: %v", marshaledKey, err)
 				continue
 			}
 			ret[p] = append(ret[p], key)
@@ -296,7 +318,7 @@
 	err := b.caller.call("BlessingRootsDebugString", results(&s))
 	if err != nil {
 		s = fmt.Sprintf("error calling BlessingRootsDebugString: %v", err)
-		vlog.Errorf(s)
+		vlog.Infof(s)
 	}
 	return
 }
diff --git a/services/agent/internal/cache/cache.go b/services/agent/internal/cache/cache.go
index cc6b904..70bca36 100644
--- a/services/agent/internal/cache/cache.go
+++ b/services/agent/internal/cache/cache.go
@@ -312,6 +312,24 @@
 	return fmt.Sprintf("cached[%s]", s.impl)
 }
 
+func (s *cachedStore) CacheDischarge(d security.Discharge, c security.Caveat, i security.DischargeImpetus) {
+	s.mu.Lock()
+	s.impl.CacheDischarge(d, c, i)
+	s.mu.Unlock()
+}
+
+func (s *cachedStore) ClearDischarges(discharges ...security.Discharge) {
+	s.mu.Lock()
+	s.impl.ClearDischarges(discharges...)
+	s.mu.Unlock()
+}
+
+func (s *cachedStore) Discharge(caveat security.Caveat, impetus security.DischargeImpetus) security.Discharge {
+	defer s.mu.Unlock()
+	s.mu.Lock()
+	return s.impl.Discharge(caveat, impetus)
+}
+
 // Must be called while holding mu.
 func (s *cachedStore) flush() {
 	s.hasDef = false
diff --git a/services/agent/internal/server/server.go b/services/agent/internal/server/server.go
index 893d4e7..eab49a2 100644
--- a/services/agent/internal/server/server.go
+++ b/services/agent/internal/server/server.go
@@ -403,6 +403,26 @@
 	return a.principal.BlessingStore().Default(), nil
 }
 
+func (a agentd) BlessingStoreCacheDischarge(_ *context.T, _ rpc.ServerCall, discharge security.Discharge, caveat security.Caveat, impetus security.DischargeImpetus) error {
+	a.w.lock()
+	a.principal.BlessingStore().CacheDischarge(discharge, caveat, impetus)
+	a.w.unlock(a.id)
+	return nil
+}
+
+func (a agentd) BlessingStoreClearDischarges(_ *context.T, _ rpc.ServerCall, discharges []security.Discharge) error {
+	a.w.lock()
+	a.principal.BlessingStore().ClearDischarges(discharges...)
+	a.w.unlock(a.id)
+	return nil
+}
+
+func (a agentd) BlessingStoreDischarge(_ *context.T, _ rpc.ServerCall, caveat security.Caveat, impetus security.DischargeImpetus) (security.Discharge, error) {
+	a.w.lock()
+	defer a.w.unlock(a.id)
+	return a.principal.BlessingStore().Discharge(caveat, impetus), nil
+}
+
 func (a agentd) BlessingRootsAdd(_ *context.T, _ rpc.ServerCall, root []byte, pattern security.BlessingPattern) error {
 	pkey, err := security.UnmarshalPublicKey(root)
 	if err != nil {
diff --git a/services/agent/internal/test_principal/main.go b/services/agent/internal/test_principal/main.go
index 28cc564..7887d67 100644
--- a/services/agent/internal/test_principal/main.go
+++ b/services/agent/internal/test_principal/main.go
@@ -94,7 +94,8 @@
 	if err != nil {
 		errorf("security.NewPublicKeyCaveat: %v", err)
 	}
-	if _, err := p.MintDischarge(tpcav, cav); err != nil {
+	dis, err := p.MintDischarge(tpcav, cav)
+	if err != nil {
 		errorf("MintDischarge: %v", err)
 	}
 	// BlessingRoots
@@ -134,6 +135,14 @@
 	if forpeer := p.BlessingStore().ForPeer("superman/friend"); !reflect.DeepEqual(forpeer, b) {
 		errorf("BlessingStore().ForPeer returned %v and not %v", forpeer, b)
 	}
+	p.BlessingStore().CacheDischarge(dis, tpcav, security.DischargeImpetus{})
+	if got := p.BlessingStore().Discharge(tpcav, security.DischargeImpetus{}); !dis.Equivalent(got) {
+		errorf("BlessingStore().Discharges returned %#v want %#v", got, dis)
+	}
+	p.BlessingStore().ClearDischarges(dis)
+	if got := p.BlessingStore().Discharge(tpcav, security.DischargeImpetus{}); got.ID() != "" {
+		errorf("BlessingStore().Discharges returned %#v want empty", got)
+	}
 
 	if len(errors) > 0 {
 		// Print out all errors and exit with failure.
diff --git a/services/agent/wire.vdl b/services/agent/wire.vdl
index 994aaf5..1d92fcc 100644
--- a/services/agent/wire.vdl
+++ b/services/agent/wire.vdl
@@ -52,6 +52,9 @@
 	BlessingStoreDefault() (security.WireBlessings | error)
 	BlessingStorePeerBlessings() (map[security.BlessingPattern]security.WireBlessings | error)
 	BlessingStoreDebugString() (string | error)
+	BlessingStoreCacheDischarge(discharge security.WireDischarge, caveat security.Caveat, impetus security.DischargeImpetus) error
+	BlessingStoreClearDischarges(discharges []security.WireDischarge) error
+	BlessingStoreDischarge(caveat security.Caveat, impetus security.DischargeImpetus) (wd security.WireDischarge | error)
 
 	BlessingRootsAdd(root []byte, pattern security.BlessingPattern) error
 	BlessingRootsRecognized(root []byte, blessing string) error
diff --git a/services/agent/wire.vdl.go b/services/agent/wire.vdl.go
index 1a0e6a2..da18067 100644
--- a/services/agent/wire.vdl.go
+++ b/services/agent/wire.vdl.go
@@ -63,6 +63,9 @@
 	BlessingStoreDefault(*context.T, ...rpc.CallOpt) (security.Blessings, error)
 	BlessingStorePeerBlessings(*context.T, ...rpc.CallOpt) (map[security.BlessingPattern]security.Blessings, error)
 	BlessingStoreDebugString(*context.T, ...rpc.CallOpt) (string, error)
+	BlessingStoreCacheDischarge(ctx *context.T, discharge security.Discharge, caveat security.Caveat, impetus security.DischargeImpetus, opts ...rpc.CallOpt) error
+	BlessingStoreClearDischarges(ctx *context.T, discharges []security.Discharge, opts ...rpc.CallOpt) error
+	BlessingStoreDischarge(ctx *context.T, caveat security.Caveat, impetus security.DischargeImpetus, opts ...rpc.CallOpt) (wd security.Discharge, err error)
 	BlessingRootsAdd(ctx *context.T, root []byte, pattern security.BlessingPattern, opts ...rpc.CallOpt) error
 	BlessingRootsRecognized(ctx *context.T, root []byte, blessing string, opts ...rpc.CallOpt) error
 	BlessingRootsDump(*context.T, ...rpc.CallOpt) (map[security.BlessingPattern][][]byte, error)
@@ -159,6 +162,21 @@
 	return
 }
 
+func (c implAgentClientStub) BlessingStoreCacheDischarge(ctx *context.T, i0 security.Discharge, i1 security.Caveat, i2 security.DischargeImpetus, opts ...rpc.CallOpt) (err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "BlessingStoreCacheDischarge", []interface{}{i0, i1, i2}, nil, opts...)
+	return
+}
+
+func (c implAgentClientStub) BlessingStoreClearDischarges(ctx *context.T, i0 []security.Discharge, opts ...rpc.CallOpt) (err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "BlessingStoreClearDischarges", []interface{}{i0}, nil, opts...)
+	return
+}
+
+func (c implAgentClientStub) BlessingStoreDischarge(ctx *context.T, i0 security.Caveat, i1 security.DischargeImpetus, opts ...rpc.CallOpt) (o0 security.Discharge, err error) {
+	err = v23.GetClient(ctx).Call(ctx, c.name, "BlessingStoreDischarge", []interface{}{i0, i1}, []interface{}{&o0}, opts...)
+	return
+}
+
 func (c implAgentClientStub) BlessingRootsAdd(ctx *context.T, i0 []byte, i1 security.BlessingPattern, opts ...rpc.CallOpt) (err error) {
 	err = v23.GetClient(ctx).Call(ctx, c.name, "BlessingRootsAdd", []interface{}{i0, i1}, nil, opts...)
 	return
@@ -273,6 +291,9 @@
 	BlessingStoreDefault(*context.T, rpc.ServerCall) (security.Blessings, error)
 	BlessingStorePeerBlessings(*context.T, rpc.ServerCall) (map[security.BlessingPattern]security.Blessings, error)
 	BlessingStoreDebugString(*context.T, rpc.ServerCall) (string, error)
+	BlessingStoreCacheDischarge(ctx *context.T, call rpc.ServerCall, discharge security.Discharge, caveat security.Caveat, impetus security.DischargeImpetus) error
+	BlessingStoreClearDischarges(ctx *context.T, call rpc.ServerCall, discharges []security.Discharge) error
+	BlessingStoreDischarge(ctx *context.T, call rpc.ServerCall, caveat security.Caveat, impetus security.DischargeImpetus) (wd security.Discharge, err error)
 	BlessingRootsAdd(ctx *context.T, call rpc.ServerCall, root []byte, pattern security.BlessingPattern) error
 	BlessingRootsRecognized(ctx *context.T, call rpc.ServerCall, root []byte, blessing string) error
 	BlessingRootsDump(*context.T, rpc.ServerCall) (map[security.BlessingPattern][][]byte, error)
@@ -303,6 +324,9 @@
 	BlessingStoreDefault(*context.T, rpc.ServerCall) (security.Blessings, error)
 	BlessingStorePeerBlessings(*context.T, rpc.ServerCall) (map[security.BlessingPattern]security.Blessings, error)
 	BlessingStoreDebugString(*context.T, rpc.ServerCall) (string, error)
+	BlessingStoreCacheDischarge(ctx *context.T, call rpc.ServerCall, discharge security.Discharge, caveat security.Caveat, impetus security.DischargeImpetus) error
+	BlessingStoreClearDischarges(ctx *context.T, call rpc.ServerCall, discharges []security.Discharge) error
+	BlessingStoreDischarge(ctx *context.T, call rpc.ServerCall, caveat security.Caveat, impetus security.DischargeImpetus) (wd security.Discharge, err error)
 	BlessingRootsAdd(ctx *context.T, call rpc.ServerCall, root []byte, pattern security.BlessingPattern) error
 	BlessingRootsRecognized(ctx *context.T, call rpc.ServerCall, root []byte, blessing string) error
 	BlessingRootsDump(*context.T, rpc.ServerCall) (map[security.BlessingPattern][][]byte, error)
@@ -399,6 +423,18 @@
 	return s.impl.BlessingStoreDebugString(ctx, call)
 }
 
+func (s implAgentServerStub) BlessingStoreCacheDischarge(ctx *context.T, call rpc.ServerCall, i0 security.Discharge, i1 security.Caveat, i2 security.DischargeImpetus) error {
+	return s.impl.BlessingStoreCacheDischarge(ctx, call, i0, i1, i2)
+}
+
+func (s implAgentServerStub) BlessingStoreClearDischarges(ctx *context.T, call rpc.ServerCall, i0 []security.Discharge) error {
+	return s.impl.BlessingStoreClearDischarges(ctx, call, i0)
+}
+
+func (s implAgentServerStub) BlessingStoreDischarge(ctx *context.T, call rpc.ServerCall, i0 security.Caveat, i1 security.DischargeImpetus) (security.Discharge, error) {
+	return s.impl.BlessingStoreDischarge(ctx, call, i0, i1)
+}
+
 func (s implAgentServerStub) BlessingRootsAdd(ctx *context.T, call rpc.ServerCall, i0 []byte, i1 security.BlessingPattern) error {
 	return s.impl.BlessingRootsAdd(ctx, call, i0, i1)
 }
@@ -552,6 +588,30 @@
 			},
 		},
 		{
+			Name: "BlessingStoreCacheDischarge",
+			InArgs: []rpc.ArgDesc{
+				{"discharge", ``}, // security.Discharge
+				{"caveat", ``},    // security.Caveat
+				{"impetus", ``},   // security.DischargeImpetus
+			},
+		},
+		{
+			Name: "BlessingStoreClearDischarges",
+			InArgs: []rpc.ArgDesc{
+				{"discharges", ``}, // []security.Discharge
+			},
+		},
+		{
+			Name: "BlessingStoreDischarge",
+			InArgs: []rpc.ArgDesc{
+				{"caveat", ``},  // security.Caveat
+				{"impetus", ``}, // security.DischargeImpetus
+			},
+			OutArgs: []rpc.ArgDesc{
+				{"wd", ``}, // security.Discharge
+			},
+		},
+		{
 			Name: "BlessingRootsAdd",
 			InArgs: []rpc.ArgDesc{
 				{"root", ``},    // []byte
diff --git a/services/binary/binaryd/main.go b/services/binary/binaryd/main.go
index 71916c0..f7788af 100644
--- a/services/binary/binaryd/main.go
+++ b/services/binary/binaryd/main.go
@@ -89,13 +89,13 @@
 	}
 	vlog.Infof("Binary repository HTTP server at: %q", rootURL)
 	go func() {
-		if err := http.Serve(listener, http.FileServer(binarylib.NewHTTPRoot(state))); err != nil {
+		if err := http.Serve(listener, http.FileServer(binarylib.NewHTTPRoot(ctx, state))); err != nil {
 			vlog.Errorf("Serve() failed: %v", err)
 			os.Exit(1)
 		}
 	}()
 
-	dis, err := binarylib.NewDispatcher(v23.GetPrincipal(ctx), state)
+	dis, err := binarylib.NewDispatcher(ctx, state)
 	if err != nil {
 		return fmt.Errorf("NewDispatcher() failed: %v\n", err)
 	}
diff --git a/services/device/device/doc.go b/services/device/device/doc.go
index 5c11a9c..d25dc90 100644
--- a/services/device/device/doc.go
+++ b/services/device/device/doc.go
@@ -41,35 +41,16 @@
 
  -alsologtostderr=true
    log to standard error as well as files
- -chown=false
-   Change owner of files and directories given as command-line arguments to the
-   user specified by this flag
- -dryrun=false
-   Elides root-requiring systemcalls.
- -kill=false
-   Kill process ids given as command-line arguments.
  -log_backtrace_at=:0
    when logging hits line file:N, emit a stack trace
  -log_dir=
    if non-empty, write log files to this directory
- -logdir=
-   Path to the log directory.
  -logtostderr=false
    log to standard error instead of files
  -max_stack_buf_size=4292608
    max size in bytes of the buffer to use for logging stack traces
- -minuid=501
-   UIDs cannot be less than this number.
- -progname=unnamed_app
-   Visible name of the application, used in argv[0]
- -rm=false
-   Remove the file trees given as command-line arguments.
- -run=
-   Path to the application to exec.
  -stderrthreshold=2
    logs at or above this threshold go to stderr
- -username=
-   The UNIX user name used for the other functions of this tool.
  -v=0
    log level for V logs
  -v23.credentials=
@@ -100,8 +81,6 @@
    comma-separated list of pattern=N settings for filename-filtered logging
  -vpath=
    comma-separated list of pattern=N settings for file pathname-filtered logging
- -workspace=
-   Path to the application's workspace directory.
 
 Device install
 
diff --git a/services/device/device/glob.go b/services/device/device/glob.go
index c483aa2..f442072 100644
--- a/services/device/device/glob.go
+++ b/services/device/device/glob.go
@@ -16,16 +16,14 @@
 	"sync/atomic"
 	"time"
 
-	"v.io/x/lib/cmdline"
-	deviceimpl "v.io/x/ref/services/device/internal/impl"
-
 	"v.io/v23"
 	"v.io/v23/context"
 	"v.io/v23/naming"
 	"v.io/v23/services/device"
 	"v.io/v23/verror"
-
+	"v.io/x/lib/cmdline"
 	"v.io/x/ref/lib/v23cmd"
+	"v.io/x/ref/services/device/internal/errors"
 )
 
 // GlobHandler is implemented by each command that wants to execute against name
@@ -247,7 +245,7 @@
 func getStatus(ctx *context.T, env *cmdline.Env, name string, resultsCh chan<- *GlobResult) {
 	status, err := device.DeviceClient(name).Status(ctx)
 	// Skip non-instances/installations.
-	if verror.ErrorID(err) == deviceimpl.ErrInvalidSuffix.ID {
+	if verror.ErrorID(err) == errors.ErrInvalidSuffix.ID {
 		return
 	}
 	if err != nil {
diff --git a/services/device/device/update.go b/services/device/device/update.go
index 6a4214e..5829d05 100644
--- a/services/device/device/update.go
+++ b/services/device/device/update.go
@@ -16,7 +16,7 @@
 	"v.io/v23/verror"
 
 	"v.io/x/lib/cmdline"
-	deviceimpl "v.io/x/ref/services/device/internal/impl"
+	"v.io/x/ref/services/device/internal/errors"
 )
 
 var cmdUpdate = &cmdline.Command{
@@ -102,7 +102,7 @@
 	case err == nil:
 		fmt.Fprintf(stdout, "Successful %s of version for instance \"%s\".\n", revertOrUpdate[revert], name)
 		return nil
-	case verror.ErrorID(err) == deviceimpl.ErrUpdateNoOp.ID:
+	case verror.ErrorID(err) == errors.ErrUpdateNoOp.ID:
 		// TODO(caprita): Ideally, we wouldn't even attempt a kill /
 		// restart if the update/revert is a no-op.
 		fmt.Fprintf(stdout, "Instance \"%s\": %s.\n", name, revertOrUpdateNoOp[revert])
@@ -123,7 +123,7 @@
 	case err == nil:
 		fmt.Fprintf(stdout, "Successful %s of version for %s \"%s\".\n", revertOrUpdate[revert], what, name)
 		return nil
-	case verror.ErrorID(err) == deviceimpl.ErrUpdateNoOp.ID:
+	case verror.ErrorID(err) == errors.ErrUpdateNoOp.ID:
 		fmt.Fprintf(stdout, "%s \"%s\": %s.\n", what, name, revertOrUpdateNoOp[revert])
 		return nil
 	default:
diff --git a/services/device/internal/errors/errors.go b/services/device/internal/errors/errors.go
new file mode 100644
index 0000000..f268f18
--- /dev/null
+++ b/services/device/internal/errors/errors.go
@@ -0,0 +1,31 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// TODO(caprita): Consider moving these to v23 if they're meant to be public
+// beyond the deviced and device tool implementations.
+
+// Package errors defines the error ids that are shared between server and
+// client-side.
+package errors
+
+import "v.io/v23/verror"
+
+// TODO(caprita): the value of pkgPath corresponds to the previous package where
+// the error ids were defined.  Updating error ids needs to be carefully
+// coordinated between clients and servers, so we should do it when we settle on
+// the final location for these error definitions.
+const pkgPath = "v.io/x/ref/services/device/internal/impl"
+
+var (
+	ErrInvalidSuffix        = verror.Register(pkgPath+".InvalidSuffix", verror.NoRetry, "{1:}{2:} invalid suffix{:_}")
+	ErrOperationFailed      = verror.Register(pkgPath+".OperationFailed", verror.NoRetry, "{1:}{2:} operation failed{:_}")
+	ErrOperationInProgress  = verror.Register(pkgPath+".OperationInProgress", verror.NoRetry, "{1:}{2:} operation in progress{:_}")
+	ErrAppTitleMismatch     = verror.Register(pkgPath+".AppTitleMismatch", verror.NoRetry, "{1:}{2:} app title mismatch{:_}")
+	ErrUpdateNoOp           = verror.Register(pkgPath+".UpdateNoOp", verror.NoRetry, "{1:}{2:} update is no op{:_}")
+	ErrInvalidOperation     = verror.Register(pkgPath+".InvalidOperation", verror.NoRetry, "{1:}{2:} invalid operation{:_}")
+	ErrInvalidBlessing      = verror.Register(pkgPath+".InvalidBlessing", verror.NoRetry, "{1:}{2:} invalid blessing{:_}")
+	ErrInvalidPairingToken  = verror.Register(pkgPath+".InvalidPairingToken", verror.NoRetry, "{1:}{2:} pairing token mismatch{:_}")
+	ErrUnclaimedDevice      = verror.Register(pkgPath+".UnclaimedDevice", verror.NoRetry, "{1:}{2:} device needs to be claimed first")
+	ErrDeviceAlreadyClaimed = verror.Register(pkgPath+".AlreadyClaimed", verror.NoRetry, "{1:}{2:} device has already been claimed")
+)
diff --git a/services/device/internal/impl/app_service.go b/services/device/internal/impl/app_service.go
index 4d935eb..e143a13 100644
--- a/services/device/internal/impl/app_service.go
+++ b/services/device/internal/impl/app_service.go
@@ -150,6 +150,7 @@
 	"v.io/x/ref/services/agent/agentlib"
 	"v.io/x/ref/services/agent/keymgr"
 	"v.io/x/ref/services/device/internal/config"
+	"v.io/x/ref/services/device/internal/errors"
 	"v.io/x/ref/services/internal/packages"
 	"v.io/x/ref/services/internal/pathperms"
 )
@@ -167,11 +168,11 @@
 func saveInstanceInfo(ctx *context.T, dir string, info *instanceInfo) error {
 	jsonInfo, err := json.Marshal(info)
 	if err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Marshal(%v) failed: %v", info, err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("Marshal(%v) failed: %v", info, err))
 	}
 	infoPath := filepath.Join(dir, "info")
 	if err := ioutil.WriteFile(infoPath, jsonInfo, 0600); err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("WriteFile(%v) failed: %v", infoPath, err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("WriteFile(%v) failed: %v", infoPath, err))
 	}
 	return nil
 }
@@ -180,9 +181,9 @@
 	infoPath := filepath.Join(dir, "info")
 	info := new(instanceInfo)
 	if infoBytes, err := ioutil.ReadFile(infoPath); err != nil {
-		return nil, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("ReadFile(%v) failed: %v", infoPath, err))
+		return nil, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("ReadFile(%v) failed: %v", infoPath, err))
 	} else if err := json.Unmarshal(infoBytes, info); err != nil {
-		return nil, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Unmarshal(%v) failed: %v", infoBytes, err))
+		return nil, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("Unmarshal(%v) failed: %v", infoBytes, err))
 	}
 	return info, nil
 }
@@ -223,11 +224,11 @@
 func saveEnvelope(ctx *context.T, dir string, envelope *application.Envelope) error {
 	jsonEnvelope, err := json.Marshal(envelope)
 	if err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Marshal(%v) failed: %v", envelope, err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("Marshal(%v) failed: %v", envelope, err))
 	}
 	path := filepath.Join(dir, "envelope")
 	if err := ioutil.WriteFile(path, jsonEnvelope, 0600); err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("WriteFile(%v) failed: %v", path, err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("WriteFile(%v) failed: %v", path, err))
 	}
 	return nil
 }
@@ -236,9 +237,9 @@
 	path := filepath.Join(dir, "envelope")
 	envelope := new(application.Envelope)
 	if envelopeBytes, err := ioutil.ReadFile(path); err != nil {
-		return nil, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("ReadFile(%v) failed: %v", path, err))
+		return nil, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("ReadFile(%v) failed: %v", path, err))
 	} else if err := json.Unmarshal(envelopeBytes, envelope); err != nil {
-		return nil, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Unmarshal(%v) failed: %v", envelopeBytes, err))
+		return nil, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("Unmarshal(%v) failed: %v", envelopeBytes, err))
 	}
 	return envelope, nil
 }
@@ -247,7 +248,7 @@
 	versionLink := filepath.Join(instanceDir, "version")
 	versionDir, err := filepath.EvalSymlinks(versionLink)
 	if err != nil {
-		return nil, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", versionLink, err))
+		return nil, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", versionLink, err))
 	}
 	return loadEnvelope(ctx, versionDir)
 }
@@ -255,11 +256,11 @@
 func saveConfig(ctx *context.T, dir string, config device.Config) error {
 	jsonConfig, err := json.Marshal(config)
 	if err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Marshal(%v) failed: %v", config, err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("Marshal(%v) failed: %v", config, err))
 	}
 	path := filepath.Join(dir, "config")
 	if err := ioutil.WriteFile(path, jsonConfig, 0600); err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("WriteFile(%v) failed: %v", path, err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("WriteFile(%v) failed: %v", path, err))
 	}
 	return nil
 }
@@ -268,9 +269,9 @@
 	path := filepath.Join(dir, "config")
 	var config device.Config
 	if configBytes, err := ioutil.ReadFile(path); err != nil {
-		return nil, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("ReadFile(%v) failed: %v", path, err))
+		return nil, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("ReadFile(%v) failed: %v", path, err))
 	} else if err := json.Unmarshal(configBytes, &config); err != nil {
-		return nil, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Unmarshal(%v) failed: %v", configBytes, err))
+		return nil, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("Unmarshal(%v) failed: %v", configBytes, err))
 	}
 	return config, nil
 }
@@ -278,11 +279,11 @@
 func savePackages(ctx *context.T, dir string, packages application.Packages) error {
 	jsonPackages, err := json.Marshal(packages)
 	if err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Marshal(%v) failed: %v", packages, err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("Marshal(%v) failed: %v", packages, err))
 	}
 	path := filepath.Join(dir, "packages")
 	if err := ioutil.WriteFile(path, jsonPackages, 0600); err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("WriteFile(%v) failed: %v", path, err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("WriteFile(%v) failed: %v", path, err))
 	}
 	return nil
 }
@@ -291,9 +292,9 @@
 	path := filepath.Join(dir, "packages")
 	var packages application.Packages
 	if packagesBytes, err := ioutil.ReadFile(path); err != nil {
-		return nil, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("ReadFile(%v) failed: %v", path, err))
+		return nil, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("ReadFile(%v) failed: %v", path, err))
 	} else if err := json.Unmarshal(packagesBytes, &packages); err != nil {
-		return nil, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Unmarshal(%v) failed: %v", packagesBytes, err))
+		return nil, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("Unmarshal(%v) failed: %v", packagesBytes, err))
 	}
 	return packages, nil
 }
@@ -301,7 +302,7 @@
 func saveOrigin(ctx *context.T, dir, originVON string) error {
 	path := filepath.Join(dir, "origin")
 	if err := ioutil.WriteFile(path, []byte(originVON), 0600); err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("WriteFile(%v) failed: %v", path, err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("WriteFile(%v) failed: %v", path, err))
 	}
 	return nil
 }
@@ -309,7 +310,7 @@
 func loadOrigin(ctx *context.T, dir string) (string, error) {
 	path := filepath.Join(dir, "origin")
 	if originBytes, err := ioutil.ReadFile(path); err != nil {
-		return "", verror.New(ErrOperationFailed, ctx, fmt.Sprintf("ReadFile(%v) failed: %v", path, err))
+		return "", verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("ReadFile(%v) failed: %v", path, err))
 	} else {
 		return string(originBytes), nil
 	}
@@ -375,7 +376,7 @@
 	if envelope.Title == application.DeviceManagerTitle {
 		// Disallow device manager apps from being installed like a
 		// regular app.
-		return nil, verror.New(ErrInvalidOperation, ctx, "DeviceManager apps cannot be installed")
+		return nil, verror.New(errors.ErrInvalidOperation, ctx, "DeviceManager apps cannot be installed")
 	}
 	return envelope, nil
 }
@@ -384,14 +385,14 @@
 func newVersion(ctx *context.T, installationDir string, envelope *application.Envelope, oldVersionDir string) (string, error) {
 	versionDir := filepath.Join(installationDir, generateVersionDirName())
 	if err := mkdirPerm(versionDir, 0711); err != nil {
-		return "", verror.New(ErrOperationFailed, ctx, err)
+		return "", verror.New(errors.ErrOperationFailed, ctx, err)
 	}
 	if err := saveEnvelope(ctx, versionDir, envelope); err != nil {
 		return versionDir, err
 	}
 	pkgDir := filepath.Join(versionDir, "pkg")
 	if err := mkdir(pkgDir); err != nil {
-		return "", verror.New(ErrOperationFailed, ctx, err)
+		return "", verror.New(errors.ErrOperationFailed, ctx, err)
 	}
 	publisher := envelope.Publisher
 	// TODO(caprita): Share binaries if already existing locally.
@@ -402,15 +403,15 @@
 		return versionDir, err
 	}
 	if err := installPackages(ctx, installationDir, versionDir); err != nil {
-		return versionDir, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("installPackages(%v, %v) failed: %v", installationDir, versionDir, err))
+		return versionDir, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("installPackages(%v, %v) failed: %v", installationDir, versionDir, err))
 	}
 	if err := os.RemoveAll(pkgDir); err != nil {
-		return versionDir, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("RemoveAll(%v) failed: %v", pkgDir, err))
+		return versionDir, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("RemoveAll(%v) failed: %v", pkgDir, err))
 	}
 	if oldVersionDir != "" {
 		previousLink := filepath.Join(versionDir, "previous")
 		if err := os.Symlink(oldVersionDir, previousLink); err != nil {
-			return versionDir, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Symlink(%v, %v) failed: %v", oldVersionDir, previousLink, err))
+			return versionDir, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("Symlink(%v, %v) failed: %v", oldVersionDir, previousLink, err))
 		}
 	}
 	// updateLink should be the last thing we do, after we've ensured the
@@ -421,7 +422,7 @@
 
 func (i *appService) Install(ctx *context.T, call rpc.ServerCall, applicationVON string, config device.Config, packages application.Packages) (string, error) {
 	if len(i.suffix) > 0 {
-		return "", verror.New(ErrInvalidSuffix, ctx)
+		return "", verror.New(errors.ErrInvalidSuffix, ctx)
 	}
 	ctx, cancel := context.WithTimeout(ctx, rpcContextLongTimeout)
 	defer cancel()
@@ -435,7 +436,7 @@
 		CleanupDir(installationDir, "")
 	}
 	if err := mkdirPerm(installationDir, 0711); err != nil {
-		return "", verror.New(ErrOperationFailed, nil)
+		return "", verror.New(errors.ErrOperationFailed, nil)
 	}
 	defer func() {
 		if deferrer != nil {
@@ -457,7 +458,7 @@
 	}
 	pkgDir := filepath.Join(installationDir, "pkg")
 	if err := mkdir(pkgDir); err != nil {
-		return "", verror.New(ErrOperationFailed, ctx, err)
+		return "", verror.New(errors.ErrOperationFailed, ctx, err)
 	}
 	// We use a zero value publisher, meaning that any signatures present in the
 	// package files are not verified.
@@ -494,7 +495,7 @@
 // TODO(gauthamt): Make sure we pass the context to installationDirCore.
 func installationDirCore(components []string, root string) (string, error) {
 	if nComponents := len(components); nComponents != 2 {
-		return "", verror.New(ErrInvalidSuffix, nil)
+		return "", verror.New(errors.ErrInvalidSuffix, nil)
 	}
 	app, installation := components[0], components[1]
 	installationDir := filepath.Join(root, applicationDirName(app), installationDirName(installation))
@@ -502,7 +503,7 @@
 		if os.IsNotExist(err) {
 			return "", verror.New(verror.ErrNoExist, nil, naming.Join(components...))
 		}
-		return "", verror.New(ErrOperationFailed, nil, fmt.Sprintf("Stat(%v) failed: %v", installationDir, err))
+		return "", verror.New(errors.ErrOperationFailed, nil, fmt.Sprintf("Stat(%v) failed: %v", installationDir, err))
 	}
 	return installationDir, nil
 }
@@ -544,11 +545,11 @@
 		// instance, we should tell the agent to drop the principal.
 		handle, conn, err := securityAgent.keyMgrAgent.NewPrincipal(ctx, false)
 		if err != nil {
-			return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("NewPrincipal() failed %v", err))
+			return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("NewPrincipal() failed %v", err))
 		}
 		var cancel func()
 		if p, cancel, err = agentPrincipal(ctx, conn); err != nil {
-			return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("agentPrincipal failed: %v", err))
+			return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("agentPrincipal failed: %v", err))
 		}
 		defer cancel()
 		info.SecurityAgentHandle = handle
@@ -561,40 +562,40 @@
 		// Use the suidhelper to chown it.
 		var err error
 		if p, err = vsecurity.CreatePersistentPrincipal(credentialsDir, nil); err != nil {
-			return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("CreatePersistentPrincipal(%v, nil) failed: %v", credentialsDir, err))
+			return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("CreatePersistentPrincipal(%v, nil) failed: %v", credentialsDir, err))
 		}
 	}
 	mPubKey, err := p.PublicKey().MarshalBinary()
 	if err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("PublicKey().MarshalBinary() failed: %v", err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("PublicKey().MarshalBinary() failed: %v", err))
 	}
 	if err := call.SendStream().Send(device.BlessServerMessageInstancePublicKey{Value: mPubKey}); err != nil {
 		return err
 	}
 	if !call.RecvStream().Advance() {
-		return verror.New(ErrInvalidBlessing, ctx, fmt.Sprintf("no blessings on stream: %v", call.RecvStream().Err()))
+		return verror.New(errors.ErrInvalidBlessing, ctx, fmt.Sprintf("no blessings on stream: %v", call.RecvStream().Err()))
 	}
 	msg := call.RecvStream().Value()
 	appBlessingsFromInstantiator, ok := msg.(device.BlessClientMessageAppBlessings)
 	if !ok {
-		return verror.New(ErrInvalidBlessing, ctx, fmt.Sprintf("wrong message type: %#v", msg))
+		return verror.New(errors.ErrInvalidBlessing, ctx, fmt.Sprintf("wrong message type: %#v", msg))
 	}
 	// Should we move this after the addition of publisher blessings, and thus allow
 	// apps to run with only publisher blessings?
 	if appBlessingsFromInstantiator.Value.IsZero() {
-		return verror.New(ErrInvalidBlessing, ctx)
+		return verror.New(errors.ErrInvalidBlessing, ctx)
 	}
 	if err := p.BlessingStore().SetDefault(appBlessingsFromInstantiator.Value); err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("BlessingStore.SetDefault() failed: %v", err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("BlessingStore.SetDefault() failed: %v", err))
 	}
 	// If there were any publisher blessings in the envelope, add those to the set of blessings
 	// sent to servers by default
 	appBlessings, err := addPublisherBlessings(ctx, instanceDir, p, appBlessingsFromInstantiator.Value)
 	if _, err := p.BlessingStore().Set(appBlessings, security.AllPrincipals); err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("BlessingStore.Set() failed: %v", err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("BlessingStore.Set() failed: %v", err))
 	}
 	if err := p.AddToRoots(appBlessings); err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("AddToRoots() failed: %v", err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("AddToRoots() failed: %v", err))
 	}
 	// In addition, we give the app separate blessings for the purpose of
 	// communicating with the device manager.
@@ -612,7 +613,7 @@
 	// back to the device manager.
 	for n, _ := range dmPrincipal.BlessingsInfo(dmPrincipal.BlessingStore().Default()) {
 		if _, err := p.BlessingStore().Set(dmBlessings, security.BlessingPattern(n)); err != nil {
-			return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("BlessingStore.Set() failed: %v", err))
+			return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("BlessingStore.Set() failed: %v", err))
 		}
 	}
 	// We also want to override the app cycle manager's server blessing in
@@ -621,14 +622,14 @@
 	// to extract the right blessing to use from its store for this purpose.
 	randomPattern, err := generateRandomString()
 	if err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("generateRandomString() failed: %v", err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("generateRandomString() failed: %v", err))
 	}
 	if _, err := p.BlessingStore().Set(dmBlessings, security.BlessingPattern(randomPattern)); err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("BlessingStore.Set() failed: %v", err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("BlessingStore.Set() failed: %v", err))
 	}
 	info.DeviceManagerPeerPattern = randomPattern
 	if err := p.AddToRoots(dmBlessings); err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("AddToRoots() failed: %v", err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("AddToRoots() failed: %v", err))
 	}
 	return nil
 }
@@ -648,7 +649,7 @@
 		vlog.VI(2).Infof("adding publisher blessing %v for app %v", s, envelope.Title)
 		tmpBlessing, err := dmPrincipal.Bless(p.PublicKey(), dmPrincipal.BlessingStore().Default(), "a/"+s, security.UnconstrainedUse())
 		if b, err = security.UnionOfBlessings(b, tmpBlessing); err != nil {
-			return b, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("UnionOfBlessings failed: %v %v", b, tmpBlessing))
+			return b, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("UnionOfBlessings failed: %v %v", b, tmpBlessing))
 		}
 	}
 
@@ -715,34 +716,34 @@
 		return "", "", err
 	}
 	if !installationStateIs(installationDir, device.InstallationStateActive) {
-		return "", "", verror.New(ErrInvalidOperation, ctx)
+		return "", "", verror.New(errors.ErrInvalidOperation, ctx)
 	}
 	instanceID := generateID()
 	instanceDir := filepath.Join(installationDir, "instances", instanceDirName(instanceID))
 	// Set permissions for app to have access.
 	if mkdirPerm(instanceDir, 0711) != nil {
-		return "", "", verror.New(ErrOperationFailed, ctx)
+		return "", "", verror.New(errors.ErrOperationFailed, ctx)
 	}
 	rootDir := filepath.Join(instanceDir, "root")
 	if err := mkdir(rootDir); err != nil {
-		return instanceDir, instanceID, verror.New(ErrOperationFailed, ctx, err)
+		return instanceDir, instanceID, verror.New(errors.ErrOperationFailed, ctx, err)
 	}
 	installationLink := filepath.Join(instanceDir, "installation")
 	if err := os.Symlink(installationDir, installationLink); err != nil {
-		return instanceDir, instanceID, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Symlink(%v, %v) failed: %v", installationDir, installationLink, err))
+		return instanceDir, instanceID, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("Symlink(%v, %v) failed: %v", installationDir, installationLink, err))
 	}
 	currLink := filepath.Join(installationDir, "current")
 	versionDir, err := filepath.EvalSymlinks(currLink)
 	if err != nil {
-		return instanceDir, instanceID, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", currLink, err))
+		return instanceDir, instanceID, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", currLink, err))
 	}
 	versionLink := filepath.Join(instanceDir, "version")
 	if err := os.Symlink(versionDir, versionLink); err != nil {
-		return instanceDir, instanceID, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Symlink(%v, %v) failed: %v", versionDir, versionLink, err))
+		return instanceDir, instanceID, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("Symlink(%v, %v) failed: %v", versionDir, versionLink, err))
 	}
 	packagesDir, packagesLink := filepath.Join(versionLink, "packages"), filepath.Join(rootDir, "packages")
 	if err := os.Symlink(packagesDir, packagesLink); err != nil {
-		return instanceDir, instanceID, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Symlink(%v, %v) failed: %v", packagesDir, packagesLink, err))
+		return instanceDir, instanceID, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("Symlink(%v, %v) failed: %v", packagesDir, packagesLink, err))
 	}
 	instanceInfo := new(instanceInfo)
 	if err := setupPrincipal(ctx, instanceDir, call, i.runner.securityAgent, instanceInfo); err != nil {
@@ -777,7 +778,7 @@
 	versionLink := filepath.Join(instanceDir, "version")
 	versionDir, err := filepath.EvalSymlinks(versionLink)
 	if err != nil {
-		return nil, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", versionLink, err))
+		return nil, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", versionLink, err))
 	}
 	envelope, err := loadEnvelope(ctx, versionDir)
 	if err != nil {
@@ -785,7 +786,7 @@
 	}
 	binPath := filepath.Join(versionDir, "bin")
 	if _, err := os.Stat(binPath); err != nil {
-		return nil, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Stat(%v) failed: %v", binPath, err))
+		return nil, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("Stat(%v) failed: %v", binPath, err))
 	}
 
 	saArgs := suidAppCmdArgs{targetUser: systemName, binpath: binPath}
@@ -821,11 +822,11 @@
 
 	stdoutLog := filepath.Join(logDir, fmt.Sprintf("STDOUT-%d", timestamp))
 	if saArgs.stdout, err = openWriteFile(stdoutLog); err != nil {
-		return nil, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("OpenFile(%v) failed: %v", stdoutLog, err))
+		return nil, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("OpenFile(%v) failed: %v", stdoutLog, err))
 	}
 	stderrLog := filepath.Join(logDir, fmt.Sprintf("STDERR-%d", timestamp))
 	if saArgs.stderr, err = openWriteFile(stderrLog); err != nil {
-		return nil, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("OpenFile(%v) failed: %v", stderrLog, err))
+		return nil, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("OpenFile(%v) failed: %v", stderrLog, err))
 	}
 
 	// Args to be passed by helper to the app.
@@ -849,7 +850,7 @@
 	installationLink := filepath.Join(instanceDir, "installation")
 	installationDir, err := filepath.EvalSymlinks(installationLink)
 	if err != nil {
-		return 0, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", installationLink, err))
+		return 0, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", installationLink, err))
 	}
 	config, err := loadConfig(ctx, installationDir)
 	if err != nil {
@@ -915,13 +916,13 @@
 	}
 	// Now react to any error in handle.Start()
 	if startErr != nil {
-		return 0, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Start() failed: %v", err))
+		return 0, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("Start() failed: %v", err))
 	}
 
 	// Wait for the suidhelper to exit. This is blocking as we assume the
 	// helper won't get stuck.
 	if err := handle.Wait(0); err != nil {
-		return 0, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Wait() on suidhelper failed: %v", err))
+		return 0, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("Wait() on suidhelper failed: %v", err))
 	}
 
 	pid, childName, err := handshaker.doHandshake(handle, listener)
@@ -1031,7 +1032,7 @@
 // TODO(gauthamt): Make sure we pass the context to instanceDir.
 func instanceDir(root string, suffix []string) (string, error) {
 	if nComponents := len(suffix); nComponents != 3 {
-		return "", verror.New(ErrInvalidSuffix, nil)
+		return "", verror.New(errors.ErrInvalidSuffix, nil)
 	}
 	app, installation, instance := suffix[0], suffix[1], suffix[2]
 	instancesDir := filepath.Join(root, applicationDirName(app), installationDirName(installation), "instances")
@@ -1070,17 +1071,17 @@
 	defer cancel()
 	stream, err := appStub.Stop(ctx)
 	if err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("%v.Stop() failed: %v", appVON, err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("%v.Stop() failed: %v", appVON, err))
 	}
 	rstream := stream.RecvStream()
 	for rstream.Advance() {
 		vlog.VI(2).Infof("%v.Stop() task update: %v", appVON, rstream.Value())
 	}
 	if err := rstream.Err(); err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Advance() failed: %v", err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("Advance() failed: %v", err))
 	}
 	if err := stream.Finish(); err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Finish() failed: %v", err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("Finish() failed: %v", err))
 	}
 	return nil
 }
@@ -1144,15 +1145,15 @@
 	versionLink := filepath.Join(instanceDir, "version")
 	versionDir, err := filepath.EvalSymlinks(versionLink)
 	if err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", versionLink, err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", versionLink, err))
 	}
 	latestVersionLink := filepath.Join(instanceDir, "installation", "current")
 	latestVersionDir, err := filepath.EvalSymlinks(latestVersionLink)
 	if err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", latestVersionLink, err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", latestVersionLink, err))
 	}
 	if versionDir == latestVersionDir {
-		return verror.New(ErrUpdateNoOp, ctx)
+		return verror.New(errors.ErrUpdateNoOp, ctx)
 	}
 	// Update to the newer version.  Note, this is the only mutation
 	// performed to the instance, and, since it's atomic, the state of the
@@ -1162,7 +1163,7 @@
 
 func updateInstallation(ctx *context.T, installationDir string) error {
 	if !installationStateIs(installationDir, device.InstallationStateActive) {
-		return verror.New(ErrInvalidOperation, ctx)
+		return verror.New(errors.ErrInvalidOperation, ctx)
 	}
 	originVON, err := loadOrigin(ctx, installationDir)
 	if err != nil {
@@ -1177,7 +1178,7 @@
 	currLink := filepath.Join(installationDir, "current")
 	oldVersionDir, err := filepath.EvalSymlinks(currLink)
 	if err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", currLink, err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", currLink, err))
 	}
 	// NOTE(caprita): A race can occur between two competing updates, where
 	// both use the old version as their baseline.  This can result in both
@@ -1192,10 +1193,10 @@
 		return err
 	}
 	if oldEnvelope.Title != newEnvelope.Title {
-		return verror.New(ErrAppTitleMismatch, ctx)
+		return verror.New(errors.ErrAppTitleMismatch, ctx)
 	}
 	if reflect.DeepEqual(oldEnvelope, newEnvelope) {
-		return verror.New(ErrUpdateNoOp, ctx)
+		return verror.New(errors.ErrUpdateNoOp, ctx)
 	}
 	versionDir, err := newVersion(ctx, installationDir, newEnvelope, oldVersionDir)
 	if err != nil {
@@ -1212,7 +1213,7 @@
 	if instanceDir, err := i.instanceDir(); err == nil {
 		return updateInstance(ctx, instanceDir)
 	}
-	return verror.New(ErrInvalidSuffix, nil)
+	return verror.New(errors.ErrInvalidSuffix, nil)
 }
 
 func (*appService) UpdateTo(_ *context.T, _ rpc.ServerCall, von string) error {
@@ -1234,26 +1235,26 @@
 	versionLink := filepath.Join(instanceDir, "version")
 	versionDir, err := filepath.EvalSymlinks(versionLink)
 	if err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", versionLink, err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", versionLink, err))
 	}
 	previousLink := filepath.Join(versionDir, "previous")
 	if _, err := os.Lstat(previousLink); err != nil {
 		if os.IsNotExist(err) {
 			// No 'previous' link -- must be the first version.
-			return verror.New(ErrUpdateNoOp, ctx)
+			return verror.New(errors.ErrUpdateNoOp, ctx)
 		}
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Lstat(%v) failed: %v", previousLink, err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("Lstat(%v) failed: %v", previousLink, err))
 	}
 	prevVersionDir, err := filepath.EvalSymlinks(previousLink)
 	if err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", previousLink, err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", previousLink, err))
 	}
 	return updateLink(prevVersionDir, versionLink)
 }
 
 func revertInstallation(ctx *context.T, installationDir string) error {
 	if !installationStateIs(installationDir, device.InstallationStateActive) {
-		return verror.New(ErrInvalidOperation, ctx)
+		return verror.New(errors.ErrInvalidOperation, ctx)
 	}
 	// NOTE(caprita): A race can occur between an update and a revert, where
 	// both use the same current version as their starting point.  This will
@@ -1263,19 +1264,19 @@
 	currLink := filepath.Join(installationDir, "current")
 	currVersionDir, err := filepath.EvalSymlinks(currLink)
 	if err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", currLink, err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", currLink, err))
 	}
 	previousLink := filepath.Join(currVersionDir, "previous")
 	if _, err := os.Lstat(previousLink); err != nil {
 		if os.IsNotExist(err) {
 			// No 'previous' link -- must be the first version.
-			return verror.New(ErrUpdateNoOp, ctx)
+			return verror.New(errors.ErrUpdateNoOp, ctx)
 		}
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Lstat(%v) failed: %v", previousLink, err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("Lstat(%v) failed: %v", previousLink, err))
 	}
 	prevVersionDir, err := filepath.EvalSymlinks(previousLink)
 	if err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", previousLink, err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", previousLink, err))
 	}
 	return updateLink(prevVersionDir, currLink)
 }
@@ -1287,7 +1288,7 @@
 	if instanceDir, err := i.instanceDir(); err == nil {
 		return revertInstance(ctx, instanceDir)
 	}
-	return verror.New(ErrInvalidSuffix, nil)
+	return verror.New(errors.ErrInvalidSuffix, nil)
 }
 
 type treeNode struct {
@@ -1410,7 +1411,7 @@
 	}
 	n := tree.find(i.suffix, false)
 	if n == nil {
-		return nil, verror.New(ErrInvalidSuffix, nil)
+		return nil, verror.New(errors.ErrInvalidSuffix, nil)
 	}
 	ch := make(chan string)
 	go func() {
@@ -1439,7 +1440,7 @@
 		}
 		return p, true, nil
 	}
-	return "", false, verror.New(ErrInvalidSuffix, nil)
+	return "", false, verror.New(errors.ErrInvalidSuffix, nil)
 }
 
 // TODO(rjkroege): Consider maintaining an in-memory Permissions cache.
@@ -1472,7 +1473,7 @@
 	case 3:
 		return i.instanceDebug(ctx, call.Security())
 	default:
-		return "", verror.New(ErrInvalidSuffix, nil)
+		return "", verror.New(errors.ErrInvalidSuffix, nil)
 	}
 }
 
@@ -1614,7 +1615,7 @@
 		status, err := i.instanceStatus(ctx)
 		return device.StatusInstance{Value: status}, err
 	default:
-		return nil, verror.New(ErrInvalidSuffix, ctx)
+		return nil, verror.New(errors.ErrInvalidSuffix, ctx)
 	}
 }
 
@@ -1630,7 +1631,7 @@
 	versionLink := filepath.Join(installationDir, "current")
 	versionDir, err := filepath.EvalSymlinks(versionLink)
 	if err != nil {
-		return device.InstallationStatus{}, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", versionLink, err))
+		return device.InstallationStatus{}, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", versionLink, err))
 	}
 	return device.InstallationStatus{
 		State:   state,
@@ -1650,7 +1651,7 @@
 	versionLink := filepath.Join(instanceDir, "version")
 	versionDir, err := filepath.EvalSymlinks(versionLink)
 	if err != nil {
-		return device.InstanceStatus{}, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", versionLink, err))
+		return device.InstanceStatus{}, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("EvalSymlinks(%v) failed: %v", versionLink, err))
 	}
 	return device.InstanceStatus{
 		State:   state,
diff --git a/services/device/internal/impl/app_starting_util.go b/services/device/internal/impl/app_starting_util.go
index 1c47e15..21b6a3c 100644
--- a/services/device/internal/impl/app_starting_util.go
+++ b/services/device/internal/impl/app_starting_util.go
@@ -22,6 +22,7 @@
 	"v.io/v23/verror"
 	"v.io/x/lib/vlog"
 	vexec "v.io/x/ref/lib/exec"
+	"v.io/x/ref/services/device/internal/errors"
 	"v.io/x/ref/services/device/internal/suid"
 )
 
@@ -93,7 +94,7 @@
 // the app is started so that the app will inherit the file descriptor
 func (a *appHandshaker) prepareToStart(ctx *context.T, cmd *exec.Cmd) error {
 	if suid.PipeToParentFD != (len(cmd.ExtraFiles) + vexec.FileOffset) {
-		return verror.New(ErrOperationFailed, ctx,
+		return verror.New(errors.ErrOperationFailed, ctx,
 			fmt.Sprintf("FD expected by helper (%v) was not available (%v) (%v)",
 				suid.PipeToParentFD, len(cmd.ExtraFiles), vexec.FileOffset))
 	}
@@ -124,7 +125,7 @@
 	var pid32 int32
 	if err := binary.Read(a.helperRead, binary.LittleEndian, &pid32); err != nil {
 		vlog.Errorf("Error reading app pid from child: %v", err)
-		return 0, "", verror.New(ErrOperationFailed, a.ctx, fmt.Sprintf("failed to read pid from helper: %v", err))
+		return 0, "", verror.New(errors.ErrOperationFailed, a.ctx, fmt.Sprintf("failed to read pid from helper: %v", err))
 	}
 	pidFromHelper := int(pid32)
 	vlog.VI(1).Infof("read app pid %v from child", pidFromHelper)
@@ -142,7 +143,7 @@
 	childReadyErrChan := make(chan error, 1)
 	go func() {
 		if err := handle.WaitForReady(childReadyTimeout); err != nil {
-			childReadyErrChan <- verror.New(ErrOperationFailed, a.ctx, fmt.Sprintf("WaitForReady(%v) failed: %v", childReadyTimeout, err))
+			childReadyErrChan <- verror.New(errors.ErrOperationFailed, a.ctx, fmt.Sprintf("WaitForReady(%v) failed: %v", childReadyTimeout, err))
 		}
 		childReadyErrChan <- nil
 	}()
@@ -153,7 +154,7 @@
 
 	select {
 	case <-pidExitedChan:
-		return 0, "", verror.New(ErrOperationFailed, a.ctx,
+		return 0, "", verror.New(errors.ErrOperationFailed, a.ctx,
 			fmt.Sprintf("App exited (pid %d)", pidFromHelper))
 
 	case err := <-childReadyErrChan:
@@ -169,7 +170,7 @@
 	if pidFromHelper != pidFromChild {
 		// Something nasty is going on (the child may be lying).
 		suidHelper.terminatePid(pidFromHelper, nil, nil)
-		return 0, "", verror.New(ErrOperationFailed, a.ctx,
+		return 0, "", verror.New(errors.ErrOperationFailed, a.ctx,
 			fmt.Sprintf("Child pids do not match! (%d != %d)", pidFromHelper, pidFromChild))
 	}
 
@@ -177,7 +178,7 @@
 	childName, err := listener.waitForValue(childReadyTimeout)
 	if err != nil {
 		suidHelper.terminatePid(pidFromHelper, nil, nil)
-		return 0, "", verror.New(ErrOperationFailed, a.ctx,
+		return 0, "", verror.New(errors.ErrOperationFailed, a.ctx,
 			fmt.Sprintf("Waiting for child name: %v", err))
 	}
 
diff --git a/services/device/internal/impl/app_state.go b/services/device/internal/impl/app_state.go
index ca50ab8..98936d2 100644
--- a/services/device/internal/impl/app_state.go
+++ b/services/device/internal/impl/app_state.go
@@ -12,6 +12,7 @@
 
 	"v.io/v23/services/device"
 	"v.io/v23/verror"
+	"v.io/x/ref/services/device/internal/errors"
 )
 
 func getInstallationState(installationDir string) (device.InstallationState, error) {
@@ -27,7 +28,7 @@
 			}
 		}
 	}
-	return device.InstallationStateActive, verror.New(ErrOperationFailed, nil, fmt.Sprintf("failed to determine state for installation in dir %v", installationDir))
+	return device.InstallationStateActive, verror.New(errors.ErrOperationFailed, nil, fmt.Sprintf("failed to determine state for installation in dir %v", installationDir))
 }
 
 func installationStateIs(installationDir string, state device.InstallationState) bool {
@@ -51,7 +52,7 @@
 			return s, nil
 		}
 	}
-	return device.InstanceStateLaunching, verror.New(ErrOperationFailed, nil, fmt.Sprintf("failed to determine state for instance in dir %v", instanceDir))
+	return device.InstanceStateLaunching, verror.New(errors.ErrOperationFailed, nil, fmt.Sprintf("failed to determine state for instance in dir %v", instanceDir))
 }
 
 func instanceStateIs(instanceDir string, state device.InstanceState) bool {
@@ -74,9 +75,9 @@
 	targetState := filepath.Join(dir, target.String())
 	if err := os.Rename(initialState, targetState); err != nil {
 		if os.IsNotExist(err) {
-			return verror.New(ErrInvalidOperation, nil, err)
+			return verror.New(errors.ErrInvalidOperation, nil, err)
 		}
-		return verror.New(ErrOperationFailed, nil, fmt.Sprintf("Rename(%v, %v) failed: %v", initialState, targetState, err))
+		return verror.New(errors.ErrOperationFailed, nil, fmt.Sprintf("Rename(%v, %v) failed: %v", initialState, targetState, err))
 	}
 	return nil
 }
@@ -84,7 +85,7 @@
 func initializeState(dir string, initial fmt.Stringer) error {
 	initialStatus := filepath.Join(dir, initial.String())
 	if err := ioutil.WriteFile(initialStatus, []byte("status"), 0600); err != nil {
-		return verror.New(ErrOperationFailed, nil, fmt.Sprintf("WriteFile(%v) failed: %v", initialStatus, err))
+		return verror.New(errors.ErrOperationFailed, nil, fmt.Sprintf("WriteFile(%v) failed: %v", initialStatus, err))
 	}
 	return nil
 }
diff --git a/services/device/internal/impl/applife/app_life_test.go b/services/device/internal/impl/applife/app_life_test.go
index 13fc965..48643e3 100644
--- a/services/device/internal/impl/applife/app_life_test.go
+++ b/services/device/internal/impl/applife/app_life_test.go
@@ -26,6 +26,7 @@
 	"v.io/x/ref"
 	"v.io/x/ref/lib/mgmt"
 	vsecurity "v.io/x/ref/lib/security"
+	"v.io/x/ref/services/device/internal/errors"
 	"v.io/x/ref/services/device/internal/impl"
 	"v.io/x/ref/services/device/internal/impl/utiltest"
 	"v.io/x/ref/services/internal/servicetest"
@@ -205,12 +206,12 @@
 	}
 
 	// Updating the installation to itself is a no-op.
-	utiltest.UpdateAppExpectError(t, ctx, appID, impl.ErrUpdateNoOp.ID)
+	utiltest.UpdateAppExpectError(t, ctx, appID, errors.ErrUpdateNoOp.ID)
 
 	// Updating the installation should not work with a mismatched title.
 	*envelope = utiltest.EnvelopeFromShell(sh, nil, utiltest.App, "bogus", 0, 0)
 
-	utiltest.UpdateAppExpectError(t, ctx, appID, impl.ErrAppTitleMismatch.ID)
+	utiltest.UpdateAppExpectError(t, ctx, appID, errors.ErrAppTitleMismatch.ID)
 
 	// Create a second version of the app and update the app to it.
 	*envelope = utiltest.EnvelopeFromShell(sh, []string{utiltest.TestEnvVarName + "=env-val-envelope"}, utiltest.App, "google naps", 0, 0, "appV2")
@@ -249,7 +250,7 @@
 	}
 
 	// Trying to update first instance while it's running should fail.
-	utiltest.UpdateInstanceExpectError(t, ctx, appID, instance1ID, impl.ErrInvalidOperation.ID)
+	utiltest.UpdateInstanceExpectError(t, ctx, appID, instance1ID, errors.ErrInvalidOperation.ID)
 	// Stop first instance and try again.
 	utiltest.KillApp(t, ctx, appID, instance1ID)
 	// Only the second instance should still be running and mounted, don't retry.
@@ -268,7 +269,7 @@
 	utiltest.Resolve(t, ctx, "appV2", 1, false)
 
 	// Reverting first instance fails since it's still running.
-	utiltest.RevertAppExpectError(t, ctx, appID+"/"+instance1ID, impl.ErrInvalidOperation.ID)
+	utiltest.RevertAppExpectError(t, ctx, appID+"/"+instance1ID, errors.ErrInvalidOperation.ID)
 	// Stop first instance and try again.
 	utiltest.KillApp(t, ctx, appID, instance1ID)
 	verifyAppWorkspace(t, root, appID, instance1ID)
@@ -296,7 +297,7 @@
 	utiltest.ResolveExpectNotFound(t, ctx, "appV1", true)
 
 	// Reverting second instance is a no-op since it's already running v1.
-	utiltest.RevertAppExpectError(t, ctx, appID+"/"+instance2ID, impl.ErrUpdateNoOp.ID)
+	utiltest.RevertAppExpectError(t, ctx, appID+"/"+instance2ID, errors.ErrUpdateNoOp.ID)
 
 	// Stop third instance.
 	utiltest.TerminateApp(t, ctx, appID, instance3ID)
@@ -319,20 +320,20 @@
 	utiltest.ResolveExpectNotFound(t, ctx, "appV1", true)
 
 	// We are already on the first version, no further revert possible.
-	utiltest.RevertAppExpectError(t, ctx, appID, impl.ErrUpdateNoOp.ID)
+	utiltest.RevertAppExpectError(t, ctx, appID, errors.ErrUpdateNoOp.ID)
 
 	// Uninstall the app.
 	utiltest.UninstallApp(t, ctx, appID)
 	utiltest.VerifyState(t, ctx, device.InstallationStateUninstalled, appID)
 
 	// Updating the installation should no longer be allowed.
-	utiltest.UpdateAppExpectError(t, ctx, appID, impl.ErrInvalidOperation.ID)
+	utiltest.UpdateAppExpectError(t, ctx, appID, errors.ErrInvalidOperation.ID)
 
 	// Reverting the installation should no longer be allowed.
-	utiltest.RevertAppExpectError(t, ctx, appID, impl.ErrInvalidOperation.ID)
+	utiltest.RevertAppExpectError(t, ctx, appID, errors.ErrInvalidOperation.ID)
 
 	// Starting new instances should no longer be allowed.
-	utiltest.LaunchAppExpectError(t, ctx, appID, impl.ErrInvalidOperation.ID)
+	utiltest.LaunchAppExpectError(t, ctx, appID, errors.ErrInvalidOperation.ID)
 
 	// Make sure that Kill will actually kill an app that doesn't exit
 	// cleanly Do this by installing, instantiating, running, and killing
diff --git a/services/device/internal/impl/association_instance.go b/services/device/internal/impl/association_instance.go
index 498cf09..0f15505 100644
--- a/services/device/internal/impl/association_instance.go
+++ b/services/device/internal/impl/association_instance.go
@@ -13,12 +13,13 @@
 	"path/filepath"
 
 	"v.io/v23/verror"
+	"v.io/x/ref/services/device/internal/errors"
 )
 
 func saveSystemNameForInstance(dir, systemName string) error {
 	snp := filepath.Join(dir, "systemname")
 	if err := ioutil.WriteFile(snp, []byte(systemName), 0600); err != nil {
-		return verror.New(ErrOperationFailed, nil, fmt.Sprintf("WriteFile(%v, %v) failed: %v", snp, systemName, err))
+		return verror.New(errors.ErrOperationFailed, nil, fmt.Sprintf("WriteFile(%v, %v) failed: %v", snp, systemName, err))
 	}
 	return nil
 }
@@ -27,7 +28,7 @@
 	snp := filepath.Join(dir, "systemname")
 	name, err := ioutil.ReadFile(snp)
 	if err != nil {
-		return "", verror.New(ErrOperationFailed, nil, fmt.Sprintf("ReadFile(%v) failed: %v", snp, err))
+		return "", verror.New(errors.ErrOperationFailed, nil, fmt.Sprintf("ReadFile(%v) failed: %v", snp, err))
 	}
 	return string(name), nil
 }
diff --git a/services/device/internal/impl/claim.go b/services/device/internal/impl/claim.go
index 10133ea..1eb0a47 100644
--- a/services/device/internal/impl/claim.go
+++ b/services/device/internal/impl/claim.go
@@ -15,6 +15,7 @@
 	"v.io/v23/security/access"
 	"v.io/v23/verror"
 	"v.io/x/lib/vlog"
+	"v.io/x/ref/services/device/internal/errors"
 	"v.io/x/ref/services/internal/pathperms"
 )
 
@@ -37,7 +38,7 @@
 func (c *claimable) Claim(ctx *context.T, call rpc.ServerCall, pairingToken string) error {
 	// Verify that the claimer pairing tokens match that of the device manager.
 	if subtle.ConstantTimeCompare([]byte(pairingToken), []byte(c.token)) != 1 {
-		return verror.New(ErrInvalidPairingToken, ctx)
+		return verror.New(errors.ErrInvalidPairingToken, ctx)
 	}
 	var (
 		granted   = call.GrantedBlessings() // blessings granted by the claimant
@@ -45,32 +46,32 @@
 		store     = principal.BlessingStore()
 	)
 	if granted.IsZero() {
-		return verror.New(ErrInvalidBlessing, ctx)
+		return verror.New(errors.ErrInvalidBlessing, ctx)
 	}
 	c.mu.Lock()
 	defer c.mu.Unlock()
 	if c.notify == nil {
 		// Device has already been claimed (by a concurrent
 		// RPC perhaps), it cannot be reclaimed
-		return verror.New(ErrDeviceAlreadyClaimed, ctx)
+		return verror.New(errors.ErrDeviceAlreadyClaimed, ctx)
 	}
 	// TODO(ashankar): If the claim fails, would make sense
 	// to remove from roots as well.
 	if err := principal.AddToRoots(granted); err != nil {
-		return verror.New(ErrInvalidBlessing, ctx)
+		return verror.New(errors.ErrInvalidBlessing, ctx)
 	}
 	if _, err := store.Set(granted, security.AllPrincipals); err != nil {
-		return verror.New(ErrInvalidBlessing, ctx, err)
+		return verror.New(errors.ErrInvalidBlessing, ctx, err)
 	}
 	if err := store.SetDefault(granted); err != nil {
-		return verror.New(ErrInvalidBlessing, ctx, err)
+		return verror.New(errors.ErrInvalidBlessing, ctx, err)
 	}
 
 	// Create Permissions with all the granted blessings (which are now the default blessings)
 	// (irrespective of caveats).
 	patterns := security.DefaultBlessingPatterns(principal)
 	if len(patterns) == 0 {
-		return verror.New(ErrInvalidBlessing, ctx)
+		return verror.New(errors.ErrInvalidBlessing, ctx)
 	}
 
 	// Create Permissions that allow principals with the caller's blessings to
@@ -87,7 +88,7 @@
 		}
 	}
 	if err := c.permsStore.Set(c.permsDir, perms, ""); err != nil {
-		return verror.New(ErrOperationFailed, ctx)
+		return verror.New(errors.ErrOperationFailed, ctx)
 	}
 	vlog.Infof("Device claimed and Permissions set to: %v", perms)
 	close(c.notify)
@@ -99,7 +100,7 @@
 // the Claiming service. Shouldn't need the "device" suffix.
 func (c *claimable) Lookup(suffix string) (interface{}, security.Authorizer, error) {
 	if suffix != "" && suffix != "device" {
-		return nil, nil, verror.New(ErrUnclaimedDevice, nil)
+		return nil, nil, verror.New(errors.ErrUnclaimedDevice, nil)
 	}
 	return c, c, nil
 }
diff --git a/services/device/internal/impl/config_service.go b/services/device/internal/impl/config_service.go
index 42e4986..f4b975f 100644
--- a/services/device/internal/impl/config_service.go
+++ b/services/device/internal/impl/config_service.go
@@ -19,6 +19,7 @@
 	"v.io/v23/naming"
 	"v.io/v23/rpc"
 	"v.io/v23/verror"
+	"v.io/x/ref/services/device/internal/errors"
 )
 
 type callbackState struct {
@@ -72,9 +73,9 @@
 	case value := <-l.ch:
 		return value, nil
 	case <-time.After(timeout):
-		return "", verror.New(ErrOperationFailed, nil, fmt.Sprintf("Waiting for callback timed out after %v", timeout))
+		return "", verror.New(errors.ErrOperationFailed, nil, fmt.Sprintf("Waiting for callback timed out after %v", timeout))
 	case <-l.stopper:
-		return "", verror.New(ErrOperationFailed, nil, fmt.Sprintf("Stopped while waiting for callack"))
+		return "", verror.New(errors.ErrOperationFailed, nil, fmt.Sprintf("Stopped while waiting for callack"))
 	}
 }
 
@@ -143,7 +144,7 @@
 	i.callback.Lock()
 	if _, ok := i.callback.channels[id]; !ok {
 		i.callback.Unlock()
-		return verror.New(ErrInvalidSuffix, nil)
+		return verror.New(errors.ErrInvalidSuffix, nil)
 	}
 	channel, ok := i.callback.channels[id][key]
 	i.callback.Unlock()
diff --git a/services/device/internal/impl/device_service.go b/services/device/internal/impl/device_service.go
index 68a4d76..06b8e93 100644
--- a/services/device/internal/impl/device_service.go
+++ b/services/device/internal/impl/device_service.go
@@ -69,6 +69,7 @@
 	vsecurity "v.io/x/ref/lib/security"
 	"v.io/x/ref/services/agent/agentlib"
 	"v.io/x/ref/services/device/internal/config"
+	"v.io/x/ref/services/device/internal/errors"
 	"v.io/x/ref/services/profile"
 )
 
@@ -134,21 +135,21 @@
 	jsonInfo, err := json.Marshal(info)
 	if err != nil {
 		vlog.Errorf("Marshal(%v) failed: %v", info, err)
-		return verror.New(ErrOperationFailed, nil)
+		return verror.New(errors.ErrOperationFailed, nil)
 	}
 	if err := os.MkdirAll(dir, os.FileMode(0700)); err != nil {
 		vlog.Errorf("MkdirAll(%v) failed: %v", dir, err)
-		return verror.New(ErrOperationFailed, nil)
+		return verror.New(errors.ErrOperationFailed, nil)
 	}
 	infoPath := filepath.Join(dir, "creation_info")
 	if err := ioutil.WriteFile(infoPath, jsonInfo, 0600); err != nil {
 		vlog.Errorf("WriteFile(%v) failed: %v", infoPath, err)
-		return verror.New(ErrOperationFailed, nil)
+		return verror.New(errors.ErrOperationFailed, nil)
 	}
 	// Make the file read-only as we don't want anyone changing it
 	if err := os.Chmod(infoPath, 0400); err != nil {
 		vlog.Errorf("Chmod(0400, %v) failed: %v", infoPath, err)
-		return verror.New(ErrOperationFailed, nil)
+		return verror.New(errors.ErrOperationFailed, nil)
 	}
 	return nil
 }
@@ -158,10 +159,10 @@
 	info := new(CreatorInfo)
 	if infoBytes, err := ioutil.ReadFile(infoPath); err != nil {
 		vlog.Errorf("ReadFile(%v) failed: %v", infoPath, err)
-		return nil, verror.New(ErrOperationFailed, nil)
+		return nil, verror.New(errors.ErrOperationFailed, nil)
 	} else if err := json.Unmarshal(infoBytes, info); err != nil {
 		vlog.Errorf("Unmarshal(%v) failed: %v", infoBytes, err)
-		return nil, verror.New(ErrOperationFailed, nil)
+		return nil, verror.New(errors.ErrOperationFailed, nil)
 	}
 	return info, nil
 }
@@ -170,11 +171,11 @@
 func CheckCompatibility(dir string) error {
 	if infoOnDisk, err := loadCreatorInfo(dir); err != nil {
 		vlog.Errorf("Failed to load creator info from %s", dir)
-		return verror.New(ErrOperationFailed, nil)
+		return verror.New(errors.ErrOperationFailed, nil)
 	} else if CurrentVersion.Major != infoOnDisk.Version.Major {
 		vlog.Errorf("Device Manager binary vs disk major version mismatch (%+v vs %+v)",
 			CurrentVersion, infoOnDisk.Version)
-		return verror.New(ErrOperationFailed, nil)
+		return verror.New(errors.ErrOperationFailed, nil)
 	}
 	return nil
 }
@@ -187,14 +188,14 @@
 func SaveManagerInfo(dir string, info *ManagerInfo) error {
 	jsonInfo, err := json.Marshal(info)
 	if err != nil {
-		return verror.New(ErrOperationFailed, nil, fmt.Sprintf("Marshal(%v) failed: %v", info, err))
+		return verror.New(errors.ErrOperationFailed, nil, fmt.Sprintf("Marshal(%v) failed: %v", info, err))
 	}
 	if err := os.MkdirAll(dir, os.FileMode(0700)); err != nil {
-		return verror.New(ErrOperationFailed, nil, fmt.Sprintf("MkdirAll(%v) failed: %v", dir, err))
+		return verror.New(errors.ErrOperationFailed, nil, fmt.Sprintf("MkdirAll(%v) failed: %v", dir, err))
 	}
 	infoPath := filepath.Join(dir, "info")
 	if err := ioutil.WriteFile(infoPath, jsonInfo, 0600); err != nil {
-		return verror.New(ErrOperationFailed, nil, fmt.Sprintf("WriteFile(%v) failed: %v", infoPath, err))
+		return verror.New(errors.ErrOperationFailed, nil, fmt.Sprintf("WriteFile(%v) failed: %v", infoPath, err))
 	}
 	return nil
 }
@@ -203,9 +204,9 @@
 	infoPath := filepath.Join(dir, "info")
 	info := new(ManagerInfo)
 	if infoBytes, err := ioutil.ReadFile(infoPath); err != nil {
-		return nil, verror.New(ErrOperationFailed, nil, fmt.Sprintf("ReadFile(%v) failed: %v", infoPath, err))
+		return nil, verror.New(errors.ErrOperationFailed, nil, fmt.Sprintf("ReadFile(%v) failed: %v", infoPath, err))
 	} else if err := json.Unmarshal(infoBytes, info); err != nil {
-		return nil, verror.New(ErrOperationFailed, nil, fmt.Sprintf("Unmarshal(%v) failed: %v", infoBytes, err))
+		return nil, verror.New(errors.ErrOperationFailed, nil, fmt.Sprintf("Unmarshal(%v) failed: %v", infoBytes, err))
 	}
 	return info, nil
 }
@@ -268,18 +269,18 @@
 	path := s.config.CurrentLink
 	link, err := os.Lstat(path)
 	if err != nil {
-		return nil, "", verror.New(ErrOperationFailed, nil, fmt.Sprintf("Lstat(%v) failed: %v", path, err))
+		return nil, "", verror.New(errors.ErrOperationFailed, nil, fmt.Sprintf("Lstat(%v) failed: %v", path, err))
 	}
 	scriptPath, err := filepath.EvalSymlinks(path)
 	if err != nil {
-		return nil, "", verror.New(ErrOperationFailed, nil, fmt.Sprintf("EvalSymlinks(%v) failed: %v", path, err))
+		return nil, "", verror.New(errors.ErrOperationFailed, nil, fmt.Sprintf("EvalSymlinks(%v) failed: %v", path, err))
 	}
 	return link, scriptPath, nil
 }
 
 func (s *deviceService) revertDeviceManager(ctx *context.T) error {
 	if err := updateLink(s.config.Previous, s.config.CurrentLink); err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("updateLink failed: %v", err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("updateLink failed: %v", err))
 	}
 	if s.restartHandler != nil {
 		s.restartHandler()
@@ -349,12 +350,12 @@
 		// TODO(rthellend): Cleanup principal
 		handle, conn, err := s.securityAgent.keyMgrAgent.NewPrincipal(ctx, false)
 		if err != nil {
-			return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("NewPrincipal() failed %v", err))
+			return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("NewPrincipal() failed %v", err))
 		}
 		agentHandle = handle
 		var cancel func()
 		if p, cancel, err = agentPrincipal(ctx, conn); err != nil {
-			return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("agentPrincipal failed: %v", err))
+			return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("agentPrincipal failed: %v", err))
 		}
 		defer cancel()
 
@@ -362,26 +363,26 @@
 		credentialsDir := filepath.Join(workspace, "credentials")
 		var err error
 		if p, err = vsecurity.CreatePersistentPrincipal(credentialsDir, nil); err != nil {
-			return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("CreatePersistentPrincipal(%v, nil) failed: %v", credentialsDir, err))
+			return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("CreatePersistentPrincipal(%v, nil) failed: %v", credentialsDir, err))
 		}
 		cmd.Env = append(cmd.Env, ref.EnvCredentials+"="+credentialsDir)
 	}
 	dmPrincipal := v23.GetPrincipal(ctx)
 	dmBlessings, err := dmPrincipal.Bless(p.PublicKey(), dmPrincipal.BlessingStore().Default(), "testdm", security.UnconstrainedUse())
 	if err := p.BlessingStore().SetDefault(dmBlessings); err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("BlessingStore.SetDefault() failed: %v", err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("BlessingStore.SetDefault() failed: %v", err))
 	}
 	if _, err := p.BlessingStore().Set(dmBlessings, security.AllPrincipals); err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("BlessingStore.Set() failed: %v", err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("BlessingStore.Set() failed: %v", err))
 	}
 	if err := p.AddToRoots(dmBlessings); err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("AddToRoots() failed: %v", err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("AddToRoots() failed: %v", err))
 	}
 
 	if s.securityAgent != nil {
 		file, err := s.securityAgent.keyMgrAgent.NewConnection(agentHandle)
 		if err != nil {
-			return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("NewConnection(%v) failed: %v", agentHandle, err))
+			return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("NewConnection(%v) failed: %v", agentHandle, err))
 		}
 		defer file.Close()
 
@@ -397,7 +398,7 @@
 	// Start the child process.
 	if err := handle.Start(); err != nil {
 		vlog.Errorf("Start() failed: %v", err)
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Start() failed: %v", err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("Start() failed: %v", err))
 	}
 	defer func() {
 		if err := handle.Clean(); err != nil {
@@ -407,7 +408,7 @@
 
 	// Wait for the child process to start.
 	if err := handle.WaitForReady(childReadyTimeout); err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("WaitForReady(%v) failed: %v", childReadyTimeout, err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("WaitForReady(%v) failed: %v", childReadyTimeout, err))
 	}
 
 	// Watch for the exit of the child. Failures could cause it to happen at any time
@@ -416,7 +417,7 @@
 		// Wait timeout needs to be long enough to give the rest of the operations time to run
 		err := handle.Wait(2*childReadyTimeout + childWaitTimeout)
 		if err != nil {
-			waitchan <- verror.New(ErrOperationFailed, ctx, fmt.Sprintf("new device manager failed to exit cleanly: %v", err))
+			waitchan <- verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("new device manager failed to exit cleanly: %v", err))
 		}
 		close(waitchan)
 		listener.stop()
@@ -424,13 +425,13 @@
 
 	childName, err := listener.waitForValue(childReadyTimeout)
 	if err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("waitForValue(%v) failed: %v", childReadyTimeout, err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("waitForValue(%v) failed: %v", childReadyTimeout, err))
 	}
 	// Check that invoking Delete() succeeds.
 	childName = naming.Join(childName, "device")
 	dmClient := device.DeviceClient(childName)
 	if err := dmClient.Delete(ctx); err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Delete() failed: %v", err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("Delete() failed: %v", err))
 	}
 	if err := <-waitchan; err != nil {
 		return err
@@ -445,11 +446,11 @@
 	// any purpose.
 	path, err := filepath.EvalSymlinks(os.Args[0])
 	if err != nil {
-		return verror.New(ErrOperationFailed, nil, fmt.Sprintf("EvalSymlinks(%v) failed: %v", os.Args[0], err))
+		return verror.New(errors.ErrOperationFailed, nil, fmt.Sprintf("EvalSymlinks(%v) failed: %v", os.Args[0], err))
 	}
 
 	if err := os.MkdirAll(logs, 0711); err != nil {
-		return verror.New(ErrOperationFailed, nil, fmt.Sprintf("MkdirAll(%v) failed: %v", logs, err))
+		return verror.New(errors.ErrOperationFailed, nil, fmt.Sprintf("MkdirAll(%v) failed: %v", logs, err))
 	}
 	stderrLog, stdoutLog := filepath.Join(logs, "STDERR"), filepath.Join(logs, "STDOUT")
 
@@ -474,34 +475,34 @@
 
 	path = filepath.Join(workspace, "deviced.sh")
 	if err := ioutil.WriteFile(path, []byte(output), 0700); err != nil {
-		return verror.New(ErrOperationFailed, nil, fmt.Sprintf("WriteFile(%v) failed: %v", path, err))
+		return verror.New(errors.ErrOperationFailed, nil, fmt.Sprintf("WriteFile(%v) failed: %v", path, err))
 	}
 	return nil
 }
 
 func (s *deviceService) updateDeviceManager(ctx *context.T) error {
 	if len(s.config.Origin) == 0 {
-		return verror.New(ErrUpdateNoOp, ctx)
+		return verror.New(errors.ErrUpdateNoOp, ctx)
 	}
 	envelope, err := fetchEnvelope(ctx, s.config.Origin)
 	if err != nil {
 		return err
 	}
 	if envelope.Title != application.DeviceManagerTitle {
-		return verror.New(ErrAppTitleMismatch, ctx, fmt.Sprintf("app title mismatch. Got %q, expected %q.", envelope.Title, application.DeviceManagerTitle))
+		return verror.New(errors.ErrAppTitleMismatch, ctx, fmt.Sprintf("app title mismatch. Got %q, expected %q.", envelope.Title, application.DeviceManagerTitle))
 	}
 	// Read and merge persistent args, if present.
 	if args, err := loadPersistentArgs(s.config.Root); err == nil {
 		envelope.Args = append(envelope.Args, args...)
 	}
 	if s.config.Envelope != nil && reflect.DeepEqual(envelope, s.config.Envelope) {
-		return verror.New(ErrUpdateNoOp, ctx)
+		return verror.New(errors.ErrUpdateNoOp, ctx)
 	}
 	// Create new workspace.
 	workspace := filepath.Join(s.config.Root, "device-manager", generateVersionDirName())
 	perm := os.FileMode(0700)
 	if err := os.MkdirAll(workspace, perm); err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("MkdirAll(%v, %v) failed: %v", workspace, perm, err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("MkdirAll(%v, %v) failed: %v", workspace, perm, err))
 	}
 
 	deferrer := func() {
@@ -530,7 +531,7 @@
 	// Populate the new workspace with a device manager script.
 	configSettings, err := s.config.Save(envelope)
 	if err != nil {
-		return verror.New(ErrOperationFailed, ctx, err)
+		return verror.New(errors.ErrOperationFailed, ctx, err)
 	}
 
 	logs := filepath.Join(s.config.Root, "device-manager", "logs")
@@ -539,7 +540,7 @@
 	}
 
 	if err := s.testDeviceManager(ctx, workspace, envelope); err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("testDeviceManager failed: %v", err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("testDeviceManager failed: %v", err))
 	}
 
 	if err := updateLink(filepath.Join(workspace, "deviced.sh"), s.config.CurrentLink); err != nil {
@@ -555,20 +556,20 @@
 }
 
 func (*deviceService) Install(ctx *context.T, _ rpc.ServerCall, _ string, _ device.Config, _ application.Packages) (string, error) {
-	return "", verror.New(ErrInvalidSuffix, ctx)
+	return "", verror.New(errors.ErrInvalidSuffix, ctx)
 }
 
 func (*deviceService) Run(ctx *context.T, _ rpc.ServerCall) error {
-	return verror.New(ErrInvalidSuffix, ctx)
+	return verror.New(errors.ErrInvalidSuffix, ctx)
 }
 
 func (s *deviceService) Revert(ctx *context.T, _ rpc.ServerCall) error {
 	if s.config.Previous == "" {
-		return verror.New(ErrUpdateNoOp, ctx, fmt.Sprintf("Revert failed: no previous version"))
+		return verror.New(errors.ErrUpdateNoOp, ctx, fmt.Sprintf("Revert failed: no previous version"))
 	}
 	updatingState := s.updating
 	if updatingState.testAndSetUpdating() {
-		return verror.New(ErrOperationInProgress, ctx, fmt.Sprintf("Revert failed: already in progress"))
+		return verror.New(errors.ErrOperationInProgress, ctx, fmt.Sprintf("Revert failed: already in progress"))
 	}
 	err := s.revertDeviceManager(ctx)
 	if err != nil {
@@ -578,7 +579,7 @@
 }
 
 func (*deviceService) Instantiate(ctx *context.T, _ device.ApplicationInstantiateServerCall) (string, error) {
-	return "", verror.New(ErrInvalidSuffix, ctx)
+	return "", verror.New(errors.ErrInvalidSuffix, ctx)
 }
 
 func (*deviceService) Delete(ctx *context.T, _ rpc.ServerCall) error {
@@ -595,7 +596,7 @@
 }
 
 func (*deviceService) Uninstall(ctx *context.T, _ rpc.ServerCall) error {
-	return verror.New(ErrInvalidSuffix, ctx)
+	return verror.New(errors.ErrInvalidSuffix, ctx)
 }
 
 func (s *deviceService) Update(ctx *context.T, _ rpc.ServerCall) error {
@@ -604,7 +605,7 @@
 
 	updatingState := s.updating
 	if updatingState.testAndSetUpdating() {
-		return verror.New(ErrOperationInProgress, ctx)
+		return verror.New(errors.ErrOperationInProgress, ctx)
 	}
 
 	err := s.updateDeviceManager(ctx)
diff --git a/services/device/internal/impl/dispatcher.go b/services/device/internal/impl/dispatcher.go
index 16f81d0..21ebe01 100644
--- a/services/device/internal/impl/dispatcher.go
+++ b/services/device/internal/impl/dispatcher.go
@@ -12,7 +12,6 @@
 	"strings"
 	"sync"
 
-	"v.io/v23"
 	"v.io/v23/context"
 	"v.io/v23/naming"
 	"v.io/v23/rpc"
@@ -29,6 +28,7 @@
 	"v.io/x/ref/services/agent/keymgr"
 	s_device "v.io/x/ref/services/device"
 	"v.io/x/ref/services/device/internal/config"
+	"v.io/x/ref/services/device/internal/errors"
 	"v.io/x/ref/services/internal/logreaderlib"
 	"v.io/x/ref/services/internal/pathperms"
 )
@@ -74,17 +74,6 @@
 )
 
 var (
-	ErrInvalidSuffix        = verror.Register(pkgPath+".InvalidSuffix", verror.NoRetry, "{1:}{2:} invalid suffix{:_}")
-	ErrOperationFailed      = verror.Register(pkgPath+".OperationFailed", verror.NoRetry, "{1:}{2:} operation failed{:_}")
-	ErrOperationInProgress  = verror.Register(pkgPath+".OperationInProgress", verror.NoRetry, "{1:}{2:} operation in progress{:_}")
-	ErrAppTitleMismatch     = verror.Register(pkgPath+".AppTitleMismatch", verror.NoRetry, "{1:}{2:} app title mismatch{:_}")
-	ErrUpdateNoOp           = verror.Register(pkgPath+".UpdateNoOp", verror.NoRetry, "{1:}{2:} update is no op{:_}")
-	ErrInvalidOperation     = verror.Register(pkgPath+".InvalidOperation", verror.NoRetry, "{1:}{2:} invalid operation{:_}")
-	ErrInvalidBlessing      = verror.Register(pkgPath+".InvalidBlessing", verror.NoRetry, "{1:}{2:} invalid blessing{:_}")
-	ErrInvalidPairingToken  = verror.Register(pkgPath+".InvalidPairingToken", verror.NoRetry, "{1:}{2:} pairing token mismatch{:_}")
-	ErrUnclaimedDevice      = verror.Register(pkgPath+".UnclaimedDevice", verror.NoRetry, "{1:}{2:} device needs to be claimed first")
-	ErrDeviceAlreadyClaimed = verror.Register(pkgPath+".AlreadyClaimed", verror.NoRetry, "{1:}{2:} device has already been claimed")
-
 	errInvalidConfig          = verror.Register(pkgPath+".errInvalidConfig", verror.NoRetry, "{1:}{2:} invalid config {3}{:_}")
 	errCantCreateAccountStore = verror.Register(pkgPath+".errCantCreateAccountStore", verror.NoRetry, "{1:}{2:} cannot create persistent store for identity to system account associations{:_}")
 	errCantCreateAppWatcher   = verror.Register(pkgPath+".errCantCreateAppWatcher", verror.NoRetry, "{1:}{2:} cannot create app status watcher{:_}")
@@ -99,7 +88,7 @@
 func NewClaimableDispatcher(ctx *context.T, config *config.State, pairingToken string) (rpc.Dispatcher, <-chan struct{}) {
 	var (
 		permsDir   = PermsDir(config)
-		permsStore = pathperms.NewPathStore(v23.GetPrincipal(ctx))
+		permsStore = pathperms.NewPathStore(ctx)
 	)
 	if _, _, err := permsStore.Get(permsDir); !os.IsNotExist(err) {
 		return nil, nil
@@ -309,7 +298,7 @@
 					return nil, nil, err
 				}
 				if !instanceStateIs(appInstanceDir, device.InstanceStateRunning) {
-					return nil, nil, verror.New(ErrInvalidSuffix, nil)
+					return nil, nil, verror.New(errors.ErrInvalidSuffix, nil)
 				}
 				var desc []rpc.InterfaceDesc
 				switch kind {
@@ -348,7 +337,7 @@
 		return receiver, appSpecificAuthorizer, nil
 	case configSuffix:
 		if len(components) != 2 {
-			return nil, nil, verror.New(ErrInvalidSuffix, nil)
+			return nil, nil, verror.New(errors.ErrInvalidSuffix, nil)
 		}
 		receiver := s_device.ConfigServer(&configService{
 			callback: d.internal.callback,
@@ -363,7 +352,7 @@
 		// (and not other apps).
 		return receiver, nil, nil
 	default:
-		return nil, nil, verror.New(ErrInvalidSuffix, nil)
+		return nil, nil, verror.New(errors.ErrInvalidSuffix, nil)
 	}
 }
 
@@ -385,7 +374,7 @@
 		return nil
 	}
 	vlog.Infof("testModeDispatcher.Authorize: Reject %q.%s()", call.Suffix(), call.Method())
-	return verror.New(ErrInvalidSuffix, nil)
+	return verror.New(errors.ErrInvalidSuffix, nil)
 }
 
 func newAppSpecificAuthorizer(sec security.Authorizer, config *config.State, suffix []string, getter pathperms.PermsGetter) (security.Authorizer, error) {
@@ -401,7 +390,7 @@
 	if len(suffix) == 2 {
 		p, err := installationDirCore(suffix, config.Root)
 		if err != nil {
-			return nil, verror.New(ErrOperationFailed, nil, fmt.Sprintf("newAppSpecificAuthorizer failed: %v", err))
+			return nil, verror.New(errors.ErrOperationFailed, nil, fmt.Sprintf("newAppSpecificAuthorizer failed: %v", err))
 		}
 		return pathperms.NewHierarchicalAuthorizer(PermsDir(config), path.Join(p, "acls"), getter)
 	}
@@ -409,14 +398,14 @@
 	if len(suffix) > 3 && (suffix[3] == "logs" || suffix[3] == "pprof" || suffix[3] == "stats") {
 		p, err := instanceDir(config.Root, suffix[0:3])
 		if err != nil {
-			return nil, verror.New(ErrOperationFailed, nil, fmt.Sprintf("newAppSpecificAuthorizer failed: %v", err))
+			return nil, verror.New(errors.ErrOperationFailed, nil, fmt.Sprintf("newAppSpecificAuthorizer failed: %v", err))
 		}
 		return pathperms.NewHierarchicalAuthorizer(PermsDir(config), path.Join(p, "debugacls"), getter)
 	}
 
 	p, err := instanceDir(config.Root, suffix[0:3])
 	if err != nil {
-		return nil, verror.New(ErrOperationFailed, nil, fmt.Sprintf("newAppSpecificAuthorizer failed: %v", err))
+		return nil, verror.New(errors.ErrOperationFailed, nil, fmt.Sprintf("newAppSpecificAuthorizer failed: %v", err))
 	}
 	return pathperms.NewHierarchicalAuthorizer(PermsDir(config), path.Join(p, "acls"), getter)
 }
diff --git a/services/device/internal/impl/globsuid/signature_match_test.go b/services/device/internal/impl/globsuid/signature_match_test.go
index 5aabcbc..02ace25 100644
--- a/services/device/internal/impl/globsuid/signature_match_test.go
+++ b/services/device/internal/impl/globsuid/signature_match_test.go
@@ -18,7 +18,7 @@
 	"v.io/v23/services/device"
 	"v.io/v23/services/repository"
 	"v.io/v23/verror"
-
+	"v.io/x/ref/services/device/internal/errors"
 	"v.io/x/ref/services/device/internal/impl"
 	"v.io/x/ref/services/device/internal/impl/utiltest"
 	"v.io/x/ref/services/internal/binarylib"
@@ -101,7 +101,7 @@
 
 	// Using the publisher should fail, because blessing "publisher" is not covered by the
 	// trusted roots of the device manager's principal
-	if _, err := utiltest.AppStub().Install(ctx, utiltest.MockApplicationRepoName, device.Config{}, nil); verror.ErrorID(err) != impl.ErrOperationFailed.ID {
+	if _, err := utiltest.AppStub().Install(ctx, utiltest.MockApplicationRepoName, device.Config{}, nil); verror.ErrorID(err) != errors.ErrOperationFailed.ID {
 		t.Fatalf("Unexpected error installing app:%v (expected ErrOperationFailed)", err)
 	}
 
@@ -124,8 +124,8 @@
 	if _, err := binarylib.Upload(ctx, naming.Join(binaryVON, "testbinary"), up, mediaInfo); err != nil {
 		t.Fatalf("Upload(%v) failed:%v", binaryVON, err)
 	}
-	if _, err := utiltest.AppStub().Install(ctx, utiltest.MockApplicationRepoName, device.Config{}, nil); verror.ErrorID(err) != impl.ErrOperationFailed.ID {
-		t.Fatalf("Failed to verify signature mismatch for binary:%v. Got errorid=%v[%v], want errorid=%v", binaryVON, verror.ErrorID(err), err, impl.ErrOperationFailed.ID)
+	if _, err := utiltest.AppStub().Install(ctx, utiltest.MockApplicationRepoName, device.Config{}, nil); verror.ErrorID(err) != errors.ErrOperationFailed.ID {
+		t.Fatalf("Failed to verify signature mismatch for binary:%v. Got errorid=%v[%v], want errorid=%v", binaryVON, verror.ErrorID(err), err, errors.ErrOperationFailed.ID)
 	}
 
 	// Restore the binary and verify that installation succeeds.
@@ -154,7 +154,7 @@
 	if _, err = binarylib.UploadFromDir(ctx, pkgVON, tmpdir); err != nil {
 		t.Fatalf("binarylib.UploadFromDir failed: %v", err)
 	}
-	if _, err := utiltest.AppStub().Install(ctx, utiltest.MockApplicationRepoName, device.Config{}, nil); verror.ErrorID(err) != impl.ErrOperationFailed.ID {
+	if _, err := utiltest.AppStub().Install(ctx, utiltest.MockApplicationRepoName, device.Config{}, nil); verror.ErrorID(err) != errors.ErrOperationFailed.ID {
 		t.Fatalf("Failed to verify signature mismatch for package:%v", pkgVON)
 	}
 }
diff --git a/services/device/internal/impl/helper_manager.go b/services/device/internal/impl/helper_manager.go
index a0528e0..3d24b16 100644
--- a/services/device/internal/impl/helper_manager.go
+++ b/services/device/internal/impl/helper_manager.go
@@ -16,6 +16,7 @@
 	"v.io/v23/security"
 	"v.io/v23/verror"
 	"v.io/x/lib/vlog"
+	"v.io/x/ref/services/device/internal/errors"
 )
 
 type suidHelperState struct {
@@ -150,7 +151,7 @@
 func (s suidHelperState) suidhelperEnabled(targetUser string) (bool, error) {
 	helperStat, err := os.Stat(s.helperPath)
 	if err != nil {
-		return false, verror.New(ErrOperationFailed, nil, fmt.Sprintf("Stat(%v) failed: %v. helper is required.", s.helperPath, err))
+		return false, verror.New(errors.ErrOperationFailed, nil, fmt.Sprintf("Stat(%v) failed: %v. helper is required.", s.helperPath, err))
 	}
 	haveHelper := IsSetuid(helperStat)
 
diff --git a/services/device/internal/impl/impl_test.go b/services/device/internal/impl/impl_test.go
index a0cb125..c641600 100644
--- a/services/device/internal/impl/impl_test.go
+++ b/services/device/internal/impl/impl_test.go
@@ -15,15 +15,15 @@
 	"syscall"
 	"testing"
 
-	"v.io/x/lib/vlog"
-
 	"v.io/v23"
 	"v.io/v23/context"
 	"v.io/v23/naming"
 	"v.io/v23/services/application"
 	"v.io/v23/services/device"
+	"v.io/x/lib/vlog"
 	"v.io/x/ref"
 	"v.io/x/ref/services/device/internal/config"
+	"v.io/x/ref/services/device/internal/errors"
 	"v.io/x/ref/services/device/internal/impl"
 	"v.io/x/ref/services/device/internal/impl/utiltest"
 	"v.io/x/ref/services/internal/binarylib"
@@ -144,8 +144,8 @@
 	// Simulate an invalid envelope in the application repository.
 	*envelope = utiltest.EnvelopeFromShell(sh, dmPauseBeforeStopEnv, utiltest.DeviceManager, "bogus", 0, 0, dmArgs...)
 
-	utiltest.UpdateDeviceExpectError(t, ctx, "factoryDM", impl.ErrAppTitleMismatch.ID)
-	utiltest.RevertDeviceExpectError(t, ctx, "factoryDM", impl.ErrUpdateNoOp.ID)
+	utiltest.UpdateDeviceExpectError(t, ctx, "factoryDM", errors.ErrAppTitleMismatch.ID)
+	utiltest.RevertDeviceExpectError(t, ctx, "factoryDM", errors.ErrUpdateNoOp.ID)
 
 	// Set up a second version of the device manager. The information in the
 	// envelope will be used by the device manager to stage the next
@@ -167,7 +167,7 @@
 	}
 	v2 := utiltest.VerifyDeviceState(t, ctx, device.InstanceStateUpdating, "factoryDM")
 
-	utiltest.UpdateDeviceExpectError(t, ctx, "factoryDM", impl.ErrOperationInProgress.ID)
+	utiltest.UpdateDeviceExpectError(t, ctx, "factoryDM", errors.ErrOperationInProgress.ID)
 
 	dmh.CloseStdin()
 
@@ -187,7 +187,7 @@
 	// Try issuing an update without changing the envelope in the
 	// application repository: this should fail, and current link should be
 	// unchanged.
-	utiltest.UpdateDeviceExpectError(t, ctx, "v2DM", impl.ErrUpdateNoOp.ID)
+	utiltest.UpdateDeviceExpectError(t, ctx, "v2DM", errors.ErrUpdateNoOp.ID)
 	if evalLink() != scriptPathV2 {
 		t.Fatalf("script changed")
 	}
@@ -196,7 +196,7 @@
 	// number. It should fail.
 	utiltest.ResolveExpectNotFound(t, ctx, "v2.5DM", false) // Ensure a clean slate.
 	*envelope = utiltest.EnvelopeFromShell(sh, dmEnv, utiltest.DeviceManagerV10, application.DeviceManagerTitle, 0, 0, "v2.5DM")
-	utiltest.UpdateDeviceExpectError(t, ctx, "v2DM", impl.ErrOperationFailed.ID)
+	utiltest.UpdateDeviceExpectError(t, ctx, "v2DM", errors.ErrOperationFailed.ID)
 
 	if evalLink() != scriptPathV2 {
 		t.Fatalf("script changed")
@@ -232,7 +232,7 @@
 
 	// Revert the device manager to its previous version (v2).
 	utiltest.RevertDevice(t, ctx, "v3DM")
-	utiltest.RevertDeviceExpectError(t, ctx, "v3DM", impl.ErrOperationInProgress.ID) // Revert already in progress.
+	utiltest.RevertDeviceExpectError(t, ctx, "v3DM", errors.ErrOperationInProgress.ID) // Revert already in progress.
 	dmh.CloseStdin()
 	dmh.Expect("restart handler")
 	dmh.Expect("v3DM terminated")
@@ -329,7 +329,7 @@
 	dms := expect.NewSession(t, stdout, servicetest.ExpectTimeout)
 	servicetest.ReadPID(t, dms)
 	utiltest.ClaimDevice(t, ctx, "claimable", "dm", "mydevice", utiltest.NoPairingToken)
-	utiltest.RevertDeviceExpectError(t, ctx, "dm", impl.ErrUpdateNoOp.ID) // No previous version available.
+	utiltest.RevertDeviceExpectError(t, ctx, "dm", errors.ErrUpdateNoOp.ID) // No previous version available.
 
 	// Stop the device manager.
 	if err := impl.Stop(ctx, dmDir, os.Stderr, os.Stdout); err != nil {
diff --git a/services/device/internal/impl/perms/perms_test.go b/services/device/internal/impl/perms/perms_test.go
index 99b4e84..0756938 100644
--- a/services/device/internal/impl/perms/perms_test.go
+++ b/services/device/internal/impl/perms/perms_test.go
@@ -16,7 +16,7 @@
 	"v.io/v23/security/access"
 	"v.io/v23/services/device"
 	"v.io/v23/verror"
-
+	"v.io/x/ref/services/device/internal/errors"
 	"v.io/x/ref/services/device/internal/impl"
 	"v.io/x/ref/services/device/internal/impl/utiltest"
 	"v.io/x/ref/services/internal/servicetest"
@@ -75,7 +75,7 @@
 	//installAppExpectError(t, octx, impl.ErrUnclaimedDevice.ID)
 
 	// Claim the device with an incorrect pairing token should fail.
-	utiltest.ClaimDeviceExpectError(t, claimantCtx, "claimable", "mydevice", "badtoken", impl.ErrInvalidPairingToken.ID)
+	utiltest.ClaimDeviceExpectError(t, claimantCtx, "claimable", "mydevice", "badtoken", errors.ErrInvalidPairingToken.ID)
 	// But succeed with a valid pairing token
 	utiltest.ClaimDevice(t, claimantCtx, "claimable", "dm", "mydevice", pairingToken)
 
diff --git a/services/device/internal/impl/tidyup.go b/services/device/internal/impl/tidyup.go
index 3b9c3ca..38aea0d 100644
--- a/services/device/internal/impl/tidyup.go
+++ b/services/device/internal/impl/tidyup.go
@@ -14,8 +14,8 @@
 	"v.io/v23/context"
 	"v.io/v23/services/device"
 	"v.io/v23/verror"
-
 	"v.io/x/lib/vlog"
+	"v.io/x/ref/services/device/internal/errors"
 )
 
 // This file contains the various routines that the device manager uses
@@ -99,7 +99,7 @@
 		for _, ep := range allerrors {
 			errormessages = append(errormessages, fmt.Sprintf("path: %s failed: %v", ep.pth, ep.err))
 		}
-		return verror.New(ErrOperationFailed, ctx, "Some older instances could not be deleted: %s", strings.Join(errormessages, ", "))
+		return verror.New(errors.ErrOperationFailed, ctx, "Some older instances could not be deleted: %s", strings.Join(errormessages, ", "))
 	}
 	return nil
 }
diff --git a/services/device/internal/impl/util.go b/services/device/internal/impl/util.go
index 188605d..bc97de3 100644
--- a/services/device/internal/impl/util.go
+++ b/services/device/internal/impl/util.go
@@ -15,9 +15,6 @@
 	"strings"
 	"time"
 
-	"v.io/x/ref/services/device/internal/config"
-	"v.io/x/ref/services/internal/binarylib"
-
 	"v.io/v23"
 	"v.io/v23/context"
 	"v.io/v23/security"
@@ -25,6 +22,9 @@
 	"v.io/v23/services/repository"
 	"v.io/v23/verror"
 	"v.io/x/lib/vlog"
+	"v.io/x/ref/services/device/internal/config"
+	"v.io/x/ref/services/device/internal/errors"
+	"v.io/x/ref/services/internal/binarylib"
 )
 
 // TODO(caprita): Set these timeout in a more principled manner.
@@ -39,7 +39,7 @@
 	if !publisher.IsZero() {
 		h := sha256.Sum256(data)
 		if !sig.Verify(publisher.PublicKey(), h[:]) {
-			return verror.New(ErrOperationFailed, nil)
+			return verror.New(errors.ErrOperationFailed, nil)
 		}
 	}
 	return nil
@@ -50,14 +50,14 @@
 	// data to verify its checksum and signature.
 	data, _, err := binarylib.Download(ctx, bin.File)
 	if err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Download(%v) failed: %v", bin.File, err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("Download(%v) failed: %v", bin.File, err))
 	}
 	if err := verifySignature(data, publisher, bin.Signature); err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Publisher binary(%v) signature verification failed", bin.File))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("Publisher binary(%v) signature verification failed", bin.File))
 	}
 	path, perm := filepath.Join(workspace, fileName), os.FileMode(0755)
 	if err := ioutil.WriteFile(path, data, perm); err != nil {
-		return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("WriteFile(%v, %v) failed: %v", path, perm, err))
+		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("WriteFile(%v, %v) failed: %v", path, perm, err))
 	}
 	return nil
 }
@@ -66,20 +66,20 @@
 func downloadPackages(ctx *context.T, publisher security.Blessings, packages application.Packages, pkgDir string) error {
 	for localPkg, pkgName := range packages {
 		if localPkg == "" || localPkg[0] == '.' || strings.Contains(localPkg, string(filepath.Separator)) {
-			return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("invalid local package name: %q", localPkg))
+			return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("invalid local package name: %q", localPkg))
 		}
 		path := filepath.Join(pkgDir, localPkg)
 		if err := binarylib.DownloadToFile(ctx, pkgName.File, path); err != nil {
-			return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("DownloadToFile(%q, %q) failed: %v", pkgName, path, err))
+			return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("DownloadToFile(%q, %q) failed: %v", pkgName, path, err))
 		}
 		data, err := ioutil.ReadFile(path)
 		if err != nil {
-			return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("ReadPackage(%v) failed: %v", path, err))
+			return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("ReadPackage(%v) failed: %v", path, err))
 		}
 		// If a nonempty signature is present, verify it. (i.e., we accept unsigned packages.)
 		if !reflect.DeepEqual(pkgName.Signature, security.Signature{}) {
 			if err := verifySignature(data, publisher, pkgName.Signature); err != nil {
-				return verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Publisher package(%v:%v) signature verification failed", localPkg, pkgName))
+				return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("Publisher package(%v:%v) signature verification failed", localPkg, pkgName))
 			}
 		}
 	}
@@ -90,7 +90,7 @@
 	stub := repository.ApplicationClient(origin)
 	profilesSet, err := Describe()
 	if err != nil {
-		return nil, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Failed to obtain profile labels: %v", err))
+		return nil, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("Failed to obtain profile labels: %v", err))
 	}
 	var profiles []string
 	for label := range profilesSet.Profiles {
@@ -98,14 +98,14 @@
 	}
 	envelope, err := stub.Match(ctx, profiles)
 	if err != nil {
-		return nil, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("Match(%v) failed: %v", profiles, err))
+		return nil, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("Match(%v) failed: %v", profiles, err))
 	}
 	// If a publisher blessing is present, it must be from a publisher we recognize. If not,
 	// reject the envelope. Note that unsigned envelopes are accepted by this check.
 	// TODO: Implment a real ACL check based on publisher
 	names, rejected := publisherBlessingNames(ctx, envelope)
 	if len(names) == 0 && len(rejected) > 0 {
-		return nil, verror.New(ErrOperationFailed, ctx, fmt.Sprintf("publisher %v in envelope %v was not recognized", rejected, envelope.Title))
+		return nil, verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("publisher %v in envelope %v was not recognized", rejected, envelope.Title))
 	}
 	return &envelope, nil
 }
@@ -130,7 +130,7 @@
 	path := filepath.Join(workspace, fileName)
 	self := os.Args[0]
 	if err := os.Link(self, path); err != nil {
-		return verror.New(ErrOperationFailed, nil, fmt.Sprintf("Link(%v, %v) failed: %v", self, path, err))
+		return verror.New(errors.ErrOperationFailed, nil, fmt.Sprintf("Link(%v, %v) failed: %v", self, path, err))
 	}
 	return nil
 }
@@ -145,14 +145,14 @@
 	fi, err := os.Lstat(newLink)
 	if err == nil {
 		if err := os.Remove(fi.Name()); err != nil {
-			return verror.New(ErrOperationFailed, nil, fmt.Sprintf("Remove(%v) failed: %v", fi.Name(), err))
+			return verror.New(errors.ErrOperationFailed, nil, fmt.Sprintf("Remove(%v) failed: %v", fi.Name(), err))
 		}
 	}
 	if err := os.Symlink(target, newLink); err != nil {
-		return verror.New(ErrOperationFailed, nil, fmt.Sprintf("Symlink(%v, %v) failed: %v", target, newLink, err))
+		return verror.New(errors.ErrOperationFailed, nil, fmt.Sprintf("Symlink(%v, %v) failed: %v", target, newLink, err))
 	}
 	if err := os.Rename(newLink, link); err != nil {
-		return verror.New(ErrOperationFailed, nil, fmt.Sprintf("Rename(%v, %v) failed: %v", newLink, link, err))
+		return verror.New(errors.ErrOperationFailed, nil, fmt.Sprintf("Rename(%v, %v) failed: %v", newLink, link, err))
 	}
 	return nil
 }
diff --git a/services/device/internal/impl/utiltest/helpers.go b/services/device/internal/impl/utiltest/helpers.go
index 0f1260d..0e93a36 100644
--- a/services/device/internal/impl/utiltest/helpers.go
+++ b/services/device/internal/impl/utiltest/helpers.go
@@ -771,7 +771,7 @@
 	if err != nil {
 		t.Fatalf("binarylib.NewState failed: %v", err)
 	}
-	d, err := binarylib.NewDispatcher(v23.GetPrincipal(ctx), state)
+	d, err := binarylib.NewDispatcher(ctx, state)
 	if err != nil {
 		t.Fatalf("server.NewDispatcher failed: %v", err)
 	}
diff --git a/services/device/internal/starter/starter.go b/services/device/internal/starter/starter.go
index 977567e..e6d6b97 100644
--- a/services/device/internal/starter/starter.go
+++ b/services/device/internal/starter/starter.go
@@ -153,6 +153,7 @@
 		cancel()
 		return "", nil, err
 	}
+	ctx = v23.WithListenSpec(ctx, args.Device.ListenSpec)
 	server, err := xrpc.NewDispatchingServer(ctx, "", dispatcher)
 	if err != nil {
 		cancel()
@@ -215,7 +216,7 @@
 }
 
 func startClaimedDevice(ctx *context.T, args Args) (func(), error) {
-	permStore := pathperms.NewPathStore(v23.GetPrincipal(ctx))
+	permStore := pathperms.NewPathStore(ctx)
 	permsdir := impl.PermsDir(args.Device.ConfigState)
 	debugAuth, err := pathperms.NewHierarchicalAuthorizer(permsdir, permsdir, permStore)
 	if err != nil {
diff --git a/services/identity/internal/revocation/sql_database.go b/services/identity/internal/revocation/sql_database.go
index fb1c409..482c240 100644
--- a/services/identity/internal/revocation/sql_database.go
+++ b/services/identity/internal/revocation/sql_database.go
@@ -38,6 +38,7 @@
 
 func (s *sqlDatabase) IsRevoked(revocationCaveatID []byte) (bool, error) {
 	rows, err := s.isRevokedStmt.Query(hex.EncodeToString(revocationCaveatID))
+	defer rows.Close()
 	if err != nil {
 		return false, err
 	}
@@ -49,6 +50,7 @@
 	if err != nil {
 		return nil, err
 	}
+	defer rows.Close()
 	if rows.Next() {
 		var timestamp time.Time
 		if err := rows.Scan(&timestamp); err != nil {
diff --git a/services/internal/binarylib/client.go b/services/internal/binarylib/client.go
index c04156a..2219e34 100644
--- a/services/internal/binarylib/client.go
+++ b/services/internal/binarylib/client.go
@@ -24,7 +24,6 @@
 	"v.io/v23/services/binary"
 	"v.io/v23/services/repository"
 	"v.io/v23/verror"
-	"v.io/x/lib/vlog"
 
 	"v.io/x/ref/services/internal/packages"
 )
@@ -41,7 +40,7 @@
 
 func Delete(ctx *context.T, name string) error {
 	if err := repository.BinaryClient(name).Delete(ctx); err != nil {
-		vlog.Errorf("Delete() failed: %v", err)
+		ctx.Errorf("Delete() failed: %v", err)
 		return err
 	}
 	return nil
@@ -58,12 +57,12 @@
 	defer cancel()
 
 	if _, err := w.Seek(ip.offset, 0); err != nil {
-		vlog.Errorf("Seek(%v, 0) failed: %v", ip.offset, err)
+		ctx.Errorf("Seek(%v, 0) failed: %v", ip.offset, err)
 		return false
 	}
 	stream, err := client.Download(ctx, int32(ip.index))
 	if err != nil {
-		vlog.Errorf("Download(%v) failed: %v", ip.index, err)
+		ctx.Errorf("Download(%v) failed: %v", ip.index, err)
 		return false
 	}
 	h, nreceived := md5.New(), 0
@@ -71,7 +70,7 @@
 	for rStream.Advance() {
 		bytes := rStream.Value()
 		if _, err := w.Write(bytes); err != nil {
-			vlog.Errorf("Write() failed: %v", err)
+			ctx.Errorf("Write() failed: %v", err)
 			return false
 		}
 		h.Write(bytes)
@@ -79,19 +78,19 @@
 	}
 
 	if err := rStream.Err(); err != nil {
-		vlog.Errorf("Advance() failed: %v", err)
+		ctx.Errorf("Advance() failed: %v", err)
 		return false
 	}
 	if err := stream.Finish(); err != nil {
-		vlog.Errorf("Finish() failed: %v", err)
+		ctx.Errorf("Finish() failed: %v", err)
 		return false
 	}
 	if expected, got := ip.part.Checksum, hex.EncodeToString(h.Sum(nil)); expected != got {
-		vlog.Errorf("Unexpected checksum: expected %v, got %v", expected, got)
+		ctx.Errorf("Unexpected checksum: expected %v, got %v", expected, got)
 		return false
 	}
 	if expected, got := ip.part.Size, int64(nreceived); expected != got {
-		vlog.Errorf("Unexpected size: expected %v, got %v", expected, got)
+		ctx.Errorf("Unexpected size: expected %v, got %v", expected, got)
 		return false
 	}
 	return true
@@ -110,7 +109,7 @@
 	client := repository.BinaryClient(von)
 	parts, mediaInfo, err := client.Stat(ctx)
 	if err != nil {
-		vlog.Errorf("Stat() failed: %v", err)
+		ctx.Errorf("Stat() failed: %v", err)
 		return repository.MediaInfo{}, err
 	}
 	for _, part := range parts {
@@ -133,7 +132,7 @@
 	dir, prefix := "", ""
 	file, err := ioutil.TempFile(dir, prefix)
 	if err != nil {
-		vlog.Errorf("TempFile(%v, %v) failed: %v", dir, prefix, err)
+		ctx.Errorf("TempFile(%v, %v) failed: %v", dir, prefix, err)
 		return nil, repository.MediaInfo{}, verror.New(errOperationFailed, ctx)
 	}
 	defer os.Remove(file.Name())
@@ -144,7 +143,7 @@
 	}
 	bytes, err := ioutil.ReadFile(file.Name())
 	if err != nil {
-		vlog.Errorf("ReadFile(%v) failed: %v", file.Name(), err)
+		ctx.Errorf("ReadFile(%v) failed: %v", file.Name(), err)
 		return nil, repository.MediaInfo{}, verror.New(errOperationFailed, ctx)
 	}
 	return bytes, mediaInfo, nil
@@ -155,36 +154,36 @@
 	prefix := fmt.Sprintf(".download.%s.", filepath.Base(path))
 	file, err := ioutil.TempFile(dir, prefix)
 	if err != nil {
-		vlog.Errorf("TempFile(%v, %v) failed: %v", dir, prefix, err)
+		ctx.Errorf("TempFile(%v, %v) failed: %v", dir, prefix, err)
 		return verror.New(errOperationFailed, ctx)
 	}
 	defer file.Close()
 	mediaInfo, err := download(ctx, file, von)
 	if err != nil {
 		if err := os.Remove(file.Name()); err != nil {
-			vlog.Errorf("Remove(%v) failed: %v", file.Name(), err)
+			ctx.Errorf("Remove(%v) failed: %v", file.Name(), err)
 		}
 		return verror.New(errOperationFailed, ctx)
 	}
 	perm := os.FileMode(0600)
 	if err := file.Chmod(perm); err != nil {
-		vlog.Errorf("Chmod(%v) failed: %v", perm, err)
+		ctx.Errorf("Chmod(%v) failed: %v", perm, err)
 		if err := os.Remove(file.Name()); err != nil {
-			vlog.Errorf("Remove(%v) failed: %v", file.Name(), err)
+			ctx.Errorf("Remove(%v) failed: %v", file.Name(), err)
 		}
 		return verror.New(errOperationFailed, ctx)
 	}
 	if err := os.Rename(file.Name(), path); err != nil {
-		vlog.Errorf("Rename(%v, %v) failed: %v", file.Name(), path, err)
+		ctx.Errorf("Rename(%v, %v) failed: %v", file.Name(), path, err)
 		if err := os.Remove(file.Name()); err != nil {
-			vlog.Errorf("Remove(%v) failed: %v", file.Name(), err)
+			ctx.Errorf("Remove(%v) failed: %v", file.Name(), err)
 		}
 		return verror.New(errOperationFailed, ctx)
 	}
 	if err := packages.SaveMediaInfo(path, mediaInfo); err != nil {
-		vlog.Errorf("packages.SaveMediaInfo(%v, %v) failed: %v", path, mediaInfo, err)
+		ctx.Errorf("packages.SaveMediaInfo(%v, %v) failed: %v", path, mediaInfo, err)
 		if err := os.Remove(path); err != nil {
-			vlog.Errorf("Remove(%v) failed: %v", path, err)
+			ctx.Errorf("Remove(%v) failed: %v", path, err)
 		}
 		return verror.New(errOperationFailed, ctx)
 	}
@@ -194,7 +193,7 @@
 func DownloadUrl(ctx *context.T, von string) (string, int64, error) {
 	url, ttl, err := repository.BinaryClient(von).DownloadUrl(ctx)
 	if err != nil {
-		vlog.Errorf("DownloadUrl() failed: %v", err)
+		ctx.Errorf("DownloadUrl() failed: %v", err)
 		return "", 0, err
 	}
 	return url, ttl, nil
@@ -206,12 +205,12 @@
 
 	offset := int64(part * partSize)
 	if _, err := r.Seek(offset, 0); err != nil {
-		vlog.Errorf("Seek(%v, 0) failed: %v", offset, err)
+		ctx.Errorf("Seek(%v, 0) failed: %v", offset, err)
 		return false, nil
 	}
 	stream, err := client.Upload(ctx, int32(part))
 	if err != nil {
-		vlog.Errorf("Upload(%v) failed: %v", part, err)
+		ctx.Errorf("Upload(%v) failed: %v", part, err)
 		return false, nil
 	}
 	bufferSize := partSize
@@ -225,7 +224,7 @@
 		n, err := r.Read(buffer[nread:])
 		nread += n
 		if err != nil && (err != io.EOF || nread < len(buffer)) {
-			vlog.Errorf("Read() failed: %v", err)
+			ctx.Errorf("Read() failed: %v", err)
 			return false, nil
 		}
 	}
@@ -236,19 +235,19 @@
 			to = len(buffer)
 		}
 		if err := sender.Send(buffer[from:to]); err != nil {
-			vlog.Errorf("Send() failed: %v", err)
+			ctx.Errorf("Send() failed: %v", err)
 			return false, nil
 		}
 	}
 	// TODO(gauthamt): To detect corruption, the upload checksum needs
 	// to be computed here rather than on the binary server.
 	if err := sender.Close(); err != nil {
-		vlog.Errorf("Close() failed: %v", err)
+		ctx.Errorf("Close() failed: %v", err)
 		parts, _, statErr := client.Stat(ctx)
 		if statErr != nil {
-			vlog.Errorf("Stat() failed: %v", statErr)
+			ctx.Errorf("Stat() failed: %v", statErr)
 			if deleteErr := client.Delete(ctx); err != nil {
-				vlog.Errorf("Delete() failed: %v", deleteErr)
+				ctx.Errorf("Delete() failed: %v", deleteErr)
 			}
 			return false, err
 		}
@@ -257,12 +256,12 @@
 		}
 	}
 	if err := stream.Finish(); err != nil {
-		vlog.Errorf("Finish() failed: %v", err)
+		ctx.Errorf("Finish() failed: %v", err)
 		parts, _, statErr := client.Stat(ctx)
 		if statErr != nil {
-			vlog.Errorf("Stat() failed: %v", statErr)
+			ctx.Errorf("Stat() failed: %v", statErr)
 			if deleteErr := client.Delete(ctx); err != nil {
-				vlog.Errorf("Delete() failed: %v", deleteErr)
+				ctx.Errorf("Delete() failed: %v", deleteErr)
 			}
 			return false, err
 		}
@@ -288,12 +287,12 @@
 	offset, whence := int64(0), 2
 	size, err := r.Seek(offset, whence)
 	if err != nil {
-		vlog.Errorf("Seek(%v, %v) failed: %v", offset, whence, err)
+		ctx.Errorf("Seek(%v, %v) failed: %v", offset, whence, err)
 		return nil, verror.New(errOperationFailed, ctx)
 	}
 	nparts := (size-1)/partSize + 1
 	if err := client.Create(ctx, int32(nparts), mediaInfo); err != nil {
-		vlog.Errorf("Create() failed: %v", err)
+		ctx.Errorf("Create() failed: %v", err)
 		return nil, err
 	}
 	h := sha256.New()
@@ -309,7 +308,7 @@
 	hash := h.Sum(nil)
 	sig, err := v23.GetPrincipal(ctx).Sign(hash[:])
 	if err != nil {
-		vlog.Errorf("Sign() of hash failed:%v", err)
+		ctx.Errorf("Sign() of hash failed:%v", err)
 		return nil, err
 	}
 	return &sig, nil
@@ -331,7 +330,7 @@
 func UploadFromFile(ctx *context.T, von, path string) (*security.Signature, error) {
 	file, err := os.Open(path)
 	if err != nil {
-		vlog.Errorf("Open(%v) failed: %v", path, err)
+		ctx.Errorf("Open(%v) failed: %v", path, err)
 		return nil, verror.New(errOperationFailed, ctx)
 	}
 	defer file.Close()
diff --git a/services/internal/binarylib/client_test.go b/services/internal/binarylib/client_test.go
index 48e6820..e06b912 100644
--- a/services/internal/binarylib/client_test.go
+++ b/services/internal/binarylib/client_test.go
@@ -17,7 +17,6 @@
 	"v.io/v23/context"
 	"v.io/v23/naming"
 	"v.io/v23/services/repository"
-	"v.io/x/lib/vlog"
 
 	"v.io/x/ref/lib/xrpc"
 	"v.io/x/ref/test"
@@ -38,7 +37,7 @@
 	}
 	path, perm := filepath.Join(rootDir, VersionFile), os.FileMode(0600)
 	if err := ioutil.WriteFile(path, []byte(Version), perm); err != nil {
-		vlog.Fatalf("WriteFile(%v, %v, %v) failed: %v", path, Version, perm, err)
+		ctx.Fatalf("WriteFile(%v, %v, %v) failed: %v", path, Version, perm, err)
 	}
 	// Setup and start the binary repository server.
 	depth := 2
@@ -46,7 +45,7 @@
 	if err != nil {
 		t.Fatalf("NewState(%v, %v) failed: %v", rootDir, depth, err)
 	}
-	dispatcher, err := NewDispatcher(v23.GetPrincipal(ctx), state)
+	dispatcher, err := NewDispatcher(ctx, state)
 	if err != nil {
 		t.Fatalf("NewDispatcher() failed: %v\n", err)
 	}
diff --git a/services/internal/binarylib/dispatcher.go b/services/internal/binarylib/dispatcher.go
index 3a138c7..f6e7dea 100644
--- a/services/internal/binarylib/dispatcher.go
+++ b/services/internal/binarylib/dispatcher.go
@@ -7,6 +7,7 @@
 import (
 	"path/filepath"
 
+	"v.io/v23/context"
 	"v.io/v23/rpc"
 	"v.io/v23/security"
 	"v.io/v23/services/repository"
@@ -25,10 +26,10 @@
 }
 
 // NewDispatcher is the dispatcher factory.
-func NewDispatcher(principal security.Principal, state *state) (rpc.Dispatcher, error) {
+func NewDispatcher(ctx *context.T, state *state) (rpc.Dispatcher, error) {
 	return &dispatcher{
 		state:      state,
-		permsStore: pathperms.NewPathStore(principal),
+		permsStore: pathperms.NewPathStore(ctx),
 	}, nil
 }
 
diff --git a/services/internal/binarylib/fs_utils.go b/services/internal/binarylib/fs_utils.go
index 4165a87..6545a6b 100644
--- a/services/internal/binarylib/fs_utils.go
+++ b/services/internal/binarylib/fs_utils.go
@@ -12,8 +12,8 @@
 	"strconv"
 	"strings"
 
+	"v.io/v23/context"
 	"v.io/v23/verror"
-	"v.io/x/lib/vlog"
 )
 
 const (
@@ -29,12 +29,12 @@
 // the path dir to determine whether the part is valid, and the
 // existence of checksum to determine whether the binary part
 // exists.
-func checksumExists(path string) error {
+func checksumExists(ctx *context.T, path string) error {
 	switch _, err := os.Stat(path); {
 	case os.IsNotExist(err):
 		return verror.New(ErrInvalidPart, nil, path)
 	case err != nil:
-		vlog.Errorf("Stat(%v) failed: %v", path, err)
+		ctx.Errorf("Stat(%v) failed: %v", path, err)
 		return verror.New(ErrOperationFailed, nil, path)
 	}
 	checksumFile := filepath.Join(path, checksumFileName)
@@ -43,7 +43,7 @@
 	case os.IsNotExist(err):
 		return verror.New(verror.ErrNoExist, nil, path)
 	case err != nil:
-		vlog.Errorf("Stat(%v) failed: %v", checksumFile, err)
+		ctx.Errorf("Stat(%v) failed: %v", checksumFile, err)
 		return verror.New(ErrOperationFailed, nil, path)
 	default:
 		return nil
@@ -60,10 +60,10 @@
 }
 
 // getParts returns a collection of paths to the parts of the binary.
-func getParts(path string) ([]string, error) {
+func getParts(ctx *context.T, path string) ([]string, error) {
 	infos, err := ioutil.ReadDir(path)
 	if err != nil {
-		vlog.Errorf("ReadDir(%v) failed: %v", path, err)
+		ctx.Errorf("ReadDir(%v) failed: %v", path, err)
 		return []string{}, verror.New(ErrOperationFailed, nil, path)
 	}
 	nDirs := 0
@@ -78,7 +78,7 @@
 			partName := info.Name()
 			idx, err := strconv.Atoi(partName)
 			if err != nil {
-				vlog.Errorf("Atoi(%v) failed: %v", partName, err)
+				ctx.Errorf("Atoi(%v) failed: %v", partName, err)
 				return []string{}, verror.New(ErrOperationFailed, nil, path)
 			}
 			if idx < 0 || idx >= len(infos) || result[idx] != "" {
diff --git a/services/internal/binarylib/http.go b/services/internal/binarylib/http.go
index 7d53bf3..a7e10d8 100644
--- a/services/internal/binarylib/http.go
+++ b/services/internal/binarylib/http.go
@@ -10,19 +10,19 @@
 	"path/filepath"
 	"strings"
 
+	"v.io/v23/context"
 	"v.io/v23/verror"
-	"v.io/x/lib/vlog"
-
 	"v.io/x/ref/services/internal/multipart"
 )
 
 // NewHTTPRoot returns an implementation of http.FileSystem that can be used
 // to serve the content in the binary service.
-func NewHTTPRoot(state *state) http.FileSystem {
-	return &httpRoot{state}
+func NewHTTPRoot(ctx *context.T, state *state) http.FileSystem {
+	return &httpRoot{ctx: ctx, state: state}
 }
 
 type httpRoot struct {
+	ctx   *context.T
 	state *state
 }
 
@@ -33,20 +33,20 @@
 // to wrap the content parts into one logical file.
 func (r httpRoot) Open(name string) (http.File, error) {
 	name = strings.TrimPrefix(name, "/")
-	vlog.Infof("HTTP handler opening %s", name)
-	parts, err := getParts(r.state.dir(name))
+	r.ctx.Infof("HTTP handler opening %s", name)
+	parts, err := getParts(r.ctx, r.state.dir(name))
 	if err != nil {
 		return nil, err
 	}
 	partFiles := make([]*os.File, len(parts))
 	for i, part := range parts {
-		if err := checksumExists(part); err != nil {
+		if err := checksumExists(r.ctx, part); err != nil {
 			return nil, err
 		}
 		dataPath := filepath.Join(part, dataFileName)
 		var err error
 		if partFiles[i], err = os.Open(dataPath); err != nil {
-			vlog.Errorf("Open(%v) failed: %v", dataPath, err)
+			r.ctx.Errorf("Open(%v) failed: %v", dataPath, err)
 			return nil, verror.New(ErrOperationFailed, nil, dataPath)
 		}
 	}
diff --git a/services/internal/binarylib/impl_test.go b/services/internal/binarylib/impl_test.go
index e80062a..e46bcbf 100644
--- a/services/internal/binarylib/impl_test.go
+++ b/services/internal/binarylib/impl_test.go
@@ -19,7 +19,6 @@
 	"v.io/v23/naming"
 	"v.io/v23/services/repository"
 	"v.io/v23/verror"
-	"v.io/x/lib/vlog"
 
 	"v.io/x/ref/lib/xrpc"
 	_ "v.io/x/ref/runtime/factories/static"
@@ -48,13 +47,13 @@
 		t.Fatalf("NewState(%v, %v, %v) failed: %v", rootDir, listener.Addr().String(), depth, err)
 	}
 	go func() {
-		if err := http.Serve(listener, http.FileServer(binarylib.NewHTTPRoot(state))); err != nil {
-			vlog.Fatalf("Serve() failed: %v", err)
+		if err := http.Serve(listener, http.FileServer(binarylib.NewHTTPRoot(ctx, state))); err != nil {
+			ctx.Fatalf("Serve() failed: %v", err)
 		}
 	}()
 
 	// Setup and start the binary repository server.
-	dispatcher, err := binarylib.NewDispatcher(v23.GetPrincipal(ctx), state)
+	dispatcher, err := binarylib.NewDispatcher(ctx, state)
 	if err != nil {
 		t.Fatalf("NewDispatcher failed: %v", err)
 	}
diff --git a/services/internal/binarylib/perms_test.go b/services/internal/binarylib/perms_test.go
index 9d3308d..b627b1a 100644
--- a/services/internal/binarylib/perms_test.go
+++ b/services/internal/binarylib/perms_test.go
@@ -18,7 +18,6 @@
 	"v.io/v23/security/access"
 	"v.io/v23/services/repository"
 	"v.io/v23/verror"
-	"v.io/x/lib/vlog"
 	vsecurity "v.io/x/ref/lib/security"
 	"v.io/x/ref/lib/signals"
 	"v.io/x/ref/lib/xrpc"
@@ -32,32 +31,31 @@
 //go:generate v23 test generate
 
 var binaryd = modules.Register(func(env *modules.Env, args ...string) error {
+	ctx, shutdown := test.V23Init()
 	if len(args) < 2 {
-		vlog.Fatalf("binaryd expected at least name and store arguments and optionally AccessList flags per PermissionsFromFlag")
+		ctx.Fatalf("binaryd expected at least name and store arguments and optionally AccessList flags per PermissionsFromFlag")
 	}
 	publishName := args[0]
 	storedir := args[1]
 
-	ctx, shutdown := test.V23Init()
-
 	defer fmt.Fprintf(env.Stdout, "%v terminating\n", publishName)
-	defer vlog.VI(1).Infof("%v terminating", publishName)
+	defer ctx.VI(1).Infof("%v terminating", publishName)
 	defer shutdown()
 
 	depth := 2
 	state, err := binarylib.NewState(storedir, "", depth)
 	if err != nil {
-		vlog.Fatalf("NewState(%v, %v, %v) failed: %v", storedir, "", depth, err)
+		ctx.Fatalf("NewState(%v, %v, %v) failed: %v", storedir, "", depth, err)
 	}
-	dispatcher, err := binarylib.NewDispatcher(v23.GetPrincipal(ctx), state)
+	dispatcher, err := binarylib.NewDispatcher(ctx, state)
 	if err != nil {
-		vlog.Fatalf("Failed to create binaryd dispatcher: %v", err)
+		ctx.Fatalf("Failed to create binaryd dispatcher: %v", err)
 	}
 	server, err := xrpc.NewDispatchingServer(ctx, publishName, dispatcher)
 	if err != nil {
-		vlog.Fatalf("NewDispatchingServer(%v) failed: %v", publishName, err)
+		ctx.Fatalf("NewDispatchingServer(%v) failed: %v", publishName, err)
 	}
-	vlog.VI(1).Infof("binaryd name: %v", server.Status().Endpoints[0].Name())
+	ctx.VI(1).Infof("binaryd name: %v", server.Status().Endpoints[0].Name())
 
 	fmt.Fprintf(env.Stdout, "ready:%d\n", os.Getpid())
 	<-signals.ShutdownOnSignals(ctx)
@@ -111,7 +109,7 @@
 	pid := servicetest.ReadPID(t, nmh)
 	defer syscall.Kill(pid, syscall.SIGINT)
 
-	vlog.VI(2).Infof("Self uploads a shared and private binary.")
+	ctx.VI(2).Infof("Self uploads a shared and private binary.")
 	if err := b("bini/private").Create(childCtx, 1, repository.MediaInfo{Type: "application/octet-stream"}); err != nil {
 		t.Fatalf("Create() failed %v", err)
 	}
@@ -120,7 +118,7 @@
 		t.Fatalf("invokeUpload() failed %v, %v", err, streamErr)
 	}
 
-	vlog.VI(2).Infof("Validate that the AccessList also allows Self")
+	ctx.VI(2).Infof("Validate that the AccessList also allows Self")
 	perms, _, err := b("bini/private").GetPermissions(selfCtx)
 	if err != nil {
 		t.Fatalf("GetPermissions failed: %v", err)
@@ -168,7 +166,7 @@
 	pid := servicetest.ReadPID(t, nmh)
 	defer syscall.Kill(pid, syscall.SIGINT)
 
-	vlog.VI(2).Infof("Self uploads a shared and private binary.")
+	ctx.VI(2).Infof("Self uploads a shared and private binary.")
 	if err := b("bini/private").Create(selfCtx, 1, repository.MediaInfo{Type: "application/octet-stream"}); err != nil {
 		t.Fatalf("Create() failed %v", err)
 	}
@@ -185,7 +183,7 @@
 		t.Fatalf("invokeUpload() failed %v, %v", err, streamErr)
 	}
 
-	vlog.VI(2).Infof("Verify that in the beginning other can't access bini/private or bini/shared")
+	ctx.VI(2).Infof("Verify that in the beginning other can't access bini/private or bini/shared")
 	if _, _, err := b("bini/private").Stat(otherCtx); verror.ErrorID(err) != verror.ErrNoAccess.ID {
 		t.Fatalf("Stat() should have failed but didn't: %v", err)
 	}
@@ -193,7 +191,7 @@
 		t.Fatalf("Stat() should have failed but didn't: %v", err)
 	}
 
-	vlog.VI(2).Infof("Validate the AccessList file on bini/private.")
+	ctx.VI(2).Infof("Validate the AccessList file on bini/private.")
 	perms, _, err := b("bini/private").GetPermissions(selfCtx)
 	if err != nil {
 		t.Fatalf("GetPermissions failed: %v", err)
@@ -209,7 +207,7 @@
 		t.Errorf("got %#v, expected %#v ", got, want)
 	}
 
-	vlog.VI(2).Infof("Validate the AccessList file on bini/private.")
+	ctx.VI(2).Infof("Validate the AccessList file on bini/private.")
 	perms, version, err := b("bini/private").GetPermissions(selfCtx)
 	if err != nil {
 		t.Fatalf("GetPermissions failed: %v", err)
@@ -218,7 +216,7 @@
 		t.Errorf("got %#v, expected %#v ", got, want)
 	}
 
-	vlog.VI(2).Infof("self blesses other as self/other and locks the bini/private binary to itself.")
+	ctx.VI(2).Infof("self blesses other as self/other and locks the bini/private binary to itself.")
 	selfBlessing := selfPrincipal.BlessingStore().Default()
 	otherBlessing, err := selfPrincipal.Bless(otherPrincipal.PublicKey(), selfBlessing, "other", security.UnconstrainedUse())
 	if err != nil {
@@ -228,7 +226,7 @@
 		t.Fatalf("otherPrincipal.BlessingStore() failed: %v", err)
 	}
 
-	vlog.VI(2).Infof("Self modifies the AccessList file on bini/private.")
+	ctx.VI(2).Infof("Self modifies the AccessList file on bini/private.")
 	for _, tag := range access.AllTypicalTags() {
 		perms.Clear("self", string(tag))
 		perms.Add("self/$", string(tag))
@@ -237,7 +235,7 @@
 		t.Fatalf("SetPermissions failed: %v", err)
 	}
 
-	vlog.VI(2).Infof(" Verify that bini/private's perms are updated.")
+	ctx.VI(2).Infof(" Verify that bini/private's perms are updated.")
 	updated := access.Permissions{
 		"Admin":   access.AccessList{In: []security.BlessingPattern{"self/$"}},
 		"Read":    access.AccessList{In: []security.BlessingPattern{"self/$"}},
@@ -256,12 +254,12 @@
 	// Other still can't access bini/shared because there's no AccessList file at the
 	// root level. Self has to set one explicitly to enable sharing. This way, self
 	// can't accidentally expose the server without setting a root AccessList.
-	vlog.VI(2).Infof(" Verify that other still can't access bini/shared.")
+	ctx.VI(2).Infof(" Verify that other still can't access bini/shared.")
 	if _, _, err := b("bini/shared").Stat(otherCtx); verror.ErrorID(err) != verror.ErrNoAccess.ID {
 		t.Fatalf("Stat() should have failed but didn't: %v", err)
 	}
 
-	vlog.VI(2).Infof("Self sets a root AccessList.")
+	ctx.VI(2).Infof("Self sets a root AccessList.")
 	newRootAccessList := make(access.Permissions)
 	for _, tag := range access.AllTypicalTags() {
 		newRootAccessList.Add("self/$", string(tag))
@@ -270,7 +268,7 @@
 		t.Fatalf("SetPermissions failed: %v", err)
 	}
 
-	vlog.VI(2).Infof("Verify that other can access bini/shared now but not access bini/private.")
+	ctx.VI(2).Infof("Verify that other can access bini/shared now but not access bini/private.")
 	if _, _, err := b("bini/shared").Stat(otherCtx); err != nil {
 		t.Fatalf("Stat() shouldn't have failed: %v", err)
 	}
@@ -278,7 +276,7 @@
 		t.Fatalf("Stat() should have failed but didn't: %v", err)
 	}
 
-	vlog.VI(2).Infof("Other still can't create so Self gives Other right to Create.")
+	ctx.VI(2).Infof("Other still can't create so Self gives Other right to Create.")
 	perms, tag, err := b("bini").GetPermissions(selfCtx)
 	if err != nil {
 		t.Fatalf("GetPermissions() failed: %v", err)
@@ -303,7 +301,7 @@
 		t.Fatalf("SetPermissions() failed: %v", err)
 	}
 
-	vlog.VI(2).Infof("Other creates bini/otherbinary")
+	ctx.VI(2).Infof("Other creates bini/otherbinary")
 	if err := b("bini/otherbinary").Create(otherCtx, 1, repository.MediaInfo{Type: "application/octet-stream"}); err != nil {
 		t.Fatalf("Create() failed %v", err)
 	}
@@ -312,7 +310,7 @@
 		t.FailNow()
 	}
 
-	vlog.VI(2).Infof("Other can read perms for bini/otherbinary.")
+	ctx.VI(2).Infof("Other can read perms for bini/otherbinary.")
 	updated = access.Permissions{
 		"Admin":   access.AccessList{In: []security.BlessingPattern{"self/$", "self/other"}},
 		"Read":    access.AccessList{In: []security.BlessingPattern{"self/$", "self/other"}},
@@ -328,7 +326,7 @@
 		t.Errorf("got %#v, expected %#v ", got, want)
 	}
 
-	vlog.VI(2).Infof("Other tries to exclude self by removing self from the AccessList set")
+	ctx.VI(2).Infof("Other tries to exclude self by removing self from the AccessList set")
 	perms, tag, err = b("bini/otherbinary").GetPermissions(otherCtx)
 	if err != nil {
 		t.Fatalf("GetPermissions() failed: %v", err)
@@ -339,7 +337,7 @@
 		t.Fatalf("SetPermissions() failed: %v", err)
 	}
 
-	vlog.VI(2).Infof("Verify that other can make this change.")
+	ctx.VI(2).Infof("Verify that other can make this change.")
 	updated = access.Permissions{
 		"Admin":   access.AccessList{In: []security.BlessingPattern{"self/other"}},
 		"Read":    access.AccessList{In: []security.BlessingPattern{"self/other"}},
@@ -355,12 +353,12 @@
 		t.Errorf("got %#v, expected %#v ", got, want)
 	}
 
-	vlog.VI(2).Infof("But self's rights are inherited from root so self can still access despite this.")
+	ctx.VI(2).Infof("But self's rights are inherited from root so self can still access despite this.")
 	if _, _, err := b("bini/otherbinary").Stat(selfCtx); err != nil {
 		t.Fatalf("Stat() shouldn't have failed: %v", err)
 	}
 
-	vlog.VI(2).Infof("Self petulantly blacklists other back.")
+	ctx.VI(2).Infof("Self petulantly blacklists other back.")
 	perms, tag, err = b("bini").GetPermissions(selfCtx)
 	if err != nil {
 		t.Fatalf("GetPermissions() failed: %v", err)
@@ -373,17 +371,17 @@
 		t.Fatalf("SetPermissions() failed: %v", err)
 	}
 
-	vlog.VI(2).Infof("And now other can do nothing at affecting the root. Other should be penitent.")
+	ctx.VI(2).Infof("And now other can do nothing at affecting the root. Other should be penitent.")
 	if err := b("bini/nototherbinary").Create(otherCtx, 1, repository.MediaInfo{Type: "application/octet-stream"}); verror.ErrorID(err) != verror.ErrNoAccess.ID {
 		t.Fatalf("Create() should have failed %v", err)
 	}
 
-	vlog.VI(2).Infof("But other can still access shared.")
+	ctx.VI(2).Infof("But other can still access shared.")
 	if _, _, err := b("bini/shared").Stat(otherCtx); err != nil {
 		t.Fatalf("Stat() should not have failed but did: %v", err)
 	}
 
-	vlog.VI(2).Infof("Self petulantly blacklists other's binary too.")
+	ctx.VI(2).Infof("Self petulantly blacklists other's binary too.")
 	perms, tag, err = b("bini/shared").GetPermissions(selfCtx)
 	if err != nil {
 		t.Fatalf("GetPermissions() failed: %v", err)
@@ -395,14 +393,14 @@
 	if err != nil {
 		t.Fatalf("SetPermissions() failed: %v", err)
 	}
-	vlog.VI(2).Infof("And now other can't access shared either.")
+	ctx.VI(2).Infof("And now other can't access shared either.")
 	if _, _, err := b("bini/shared").Stat(otherCtx); verror.ErrorID(err) != verror.ErrNoAccess.ID {
 		t.Fatalf("Stat() should have failed but didn't: %v", err)
 	}
 	// TODO(rjkroege): Extend the test with a third principal and verify that
 	// new principals can be given Admin perimission at the root.
 
-	vlog.VI(2).Infof("Self feels guilty for petulance and disempowers itself")
+	ctx.VI(2).Infof("Self feels guilty for petulance and disempowers itself")
 	// TODO(rjkroege,caprita): This is a one-way transition for self. Perhaps it
 	// should not be. Consider adding a factory-reset facility.
 	perms, tag, err = b("bini").GetPermissions(selfCtx)
@@ -415,7 +413,7 @@
 		t.Fatalf("SetPermissions() failed: %v", err)
 	}
 
-	vlog.VI(2).Info("Self can't access other's binary now")
+	ctx.VI(2).Info("Self can't access other's binary now")
 	if _, _, err := b("bini/otherbinary").Stat(selfCtx); err == nil {
 		t.Fatalf("Stat() should have failed but didn't")
 	}
diff --git a/services/internal/binarylib/service.go b/services/internal/binarylib/service.go
index 75e6718..e9bf201 100644
--- a/services/internal/binarylib/service.go
+++ b/services/internal/binarylib/service.go
@@ -47,7 +47,6 @@
 	"v.io/v23/services/binary"
 	"v.io/v23/services/repository"
 	"v.io/v23/verror"
-	"v.io/x/lib/vlog"
 	"v.io/x/ref/services/internal/pathperms"
 )
 
@@ -94,24 +93,24 @@
 const BufferLength = 4096
 
 func (i *binaryService) Create(ctx *context.T, call rpc.ServerCall, nparts int32, mediaInfo repository.MediaInfo) error {
-	vlog.Infof("%v.Create(%v, %v)", i.suffix, nparts, mediaInfo)
+	ctx.Infof("%v.Create(%v, %v)", i.suffix, nparts, mediaInfo)
 	if nparts < 1 {
 		return verror.New(ErrInvalidParts, ctx)
 	}
 	parent, perm := filepath.Dir(i.path), os.FileMode(0700)
 	if err := os.MkdirAll(parent, perm); err != nil {
-		vlog.Errorf("MkdirAll(%v, %v) failed: %v", parent, perm, err)
+		ctx.Errorf("MkdirAll(%v, %v) failed: %v", parent, perm, err)
 		return verror.New(ErrOperationFailed, ctx)
 	}
 	prefix := "creating-"
 	tmpDir, err := ioutil.TempDir(parent, prefix)
 	if err != nil {
-		vlog.Errorf("TempDir(%v, %v) failed: %v", parent, prefix, err)
+		ctx.Errorf("TempDir(%v, %v) failed: %v", parent, prefix, err)
 		return verror.New(ErrOperationFailed, ctx)
 	}
 	nameFile := filepath.Join(tmpDir, nameFileName)
 	if err := ioutil.WriteFile(nameFile, []byte(i.suffix), os.FileMode(0600)); err != nil {
-		vlog.Errorf("WriteFile(%q) failed: %v", nameFile, err)
+		ctx.Errorf("WriteFile(%q) failed: %v", nameFile, err)
 		return verror.New(ErrOperationFailed, ctx)
 	}
 
@@ -121,26 +120,26 @@
 		return verror.New(ErrNotAuthorized, ctx)
 	}
 	if err := i.permsStore.Set(permsPath(i.state.rootDir, i.suffix), pathperms.PermissionsForBlessings(rb), ""); err != nil {
-		vlog.Errorf("insertPermissions(%v) failed: %v", rb, err)
+		ctx.Errorf("insertPermissions(%v) failed: %v", rb, err)
 		return verror.New(ErrOperationFailed, ctx)
 	}
 
 	infoFile := filepath.Join(tmpDir, mediaInfoFileName)
 	jInfo, err := json.Marshal(mediaInfo)
 	if err != nil {
-		vlog.Errorf("json.Marshal(%v) failed: %v", mediaInfo, err)
+		ctx.Errorf("json.Marshal(%v) failed: %v", mediaInfo, err)
 		return verror.New(ErrOperationFailed, ctx)
 	}
 	if err := ioutil.WriteFile(infoFile, jInfo, os.FileMode(0600)); err != nil {
-		vlog.Errorf("WriteFile(%q) failed: %v", infoFile, err)
+		ctx.Errorf("WriteFile(%q) failed: %v", infoFile, err)
 		return verror.New(ErrOperationFailed, ctx)
 	}
 	for j := 0; j < int(nparts); j++ {
 		partPath, partPerm := generatePartPath(tmpDir, j), os.FileMode(0700)
 		if err := os.MkdirAll(partPath, partPerm); err != nil {
-			vlog.Errorf("MkdirAll(%v, %v) failed: %v", partPath, partPerm, err)
+			ctx.Errorf("MkdirAll(%v, %v) failed: %v", partPath, partPerm, err)
 			if err := os.RemoveAll(tmpDir); err != nil {
-				vlog.Errorf("RemoveAll(%v) failed: %v", tmpDir, err)
+				ctx.Errorf("RemoveAll(%v) failed: %v", tmpDir, err)
 			}
 			return verror.New(ErrOperationFailed, ctx)
 		}
@@ -150,36 +149,36 @@
 	if err := os.Rename(tmpDir, i.path); err != nil {
 		defer func() {
 			if err := os.RemoveAll(tmpDir); err != nil {
-				vlog.Errorf("RemoveAll(%v) failed: %v", tmpDir, err)
+				ctx.Errorf("RemoveAll(%v) failed: %v", tmpDir, err)
 			}
 		}()
 		if linkErr, ok := err.(*os.LinkError); ok && linkErr.Err == syscall.ENOTEMPTY {
 			return verror.New(verror.ErrExist, ctx, i.path)
 		}
-		vlog.Errorf("Rename(%v, %v) failed: %v", tmpDir, i.path, err)
+		ctx.Errorf("Rename(%v, %v) failed: %v", tmpDir, i.path, err)
 		return verror.New(ErrOperationFailed, ctx, i.path)
 	}
 	return nil
 }
 
 func (i *binaryService) Delete(ctx *context.T, _ rpc.ServerCall) error {
-	vlog.Infof("%v.Delete()", i.suffix)
+	ctx.Infof("%v.Delete()", i.suffix)
 	if _, err := os.Stat(i.path); err != nil {
 		if os.IsNotExist(err) {
 			return verror.New(verror.ErrNoExist, ctx, i.path)
 		}
-		vlog.Errorf("Stat(%v) failed: %v", i.path, err)
+		ctx.Errorf("Stat(%v) failed: %v", i.path, err)
 		return verror.New(ErrOperationFailed, ctx)
 	}
 	// Use os.Rename() to atomically remove the binary directory
 	// structure.
 	path := filepath.Join(filepath.Dir(i.path), "removing-"+filepath.Base(i.path))
 	if err := os.Rename(i.path, path); err != nil {
-		vlog.Errorf("Rename(%v, %v) failed: %v", i.path, path, err)
+		ctx.Errorf("Rename(%v, %v) failed: %v", i.path, path, err)
 		return verror.New(ErrOperationFailed, ctx, i.path)
 	}
 	if err := os.RemoveAll(path); err != nil {
-		vlog.Errorf("Remove(%v) failed: %v", path, err)
+		ctx.Errorf("Remove(%v) failed: %v", path, err)
 		return verror.New(ErrOperationFailed, ctx)
 	}
 	for {
@@ -193,7 +192,7 @@
 			if err.(*os.PathError).Err.Error() == syscall.ENOTEMPTY.Error() {
 				break
 			}
-			vlog.Errorf("Remove(%v) failed: %v", path, err)
+			ctx.Errorf("Remove(%v) failed: %v", path, err)
 			return verror.New(ErrOperationFailed, ctx)
 		}
 	}
@@ -201,15 +200,15 @@
 }
 
 func (i *binaryService) Download(ctx *context.T, call repository.BinaryDownloadServerCall, part int32) error {
-	vlog.Infof("%v.Download(%v)", i.suffix, part)
+	ctx.Infof("%v.Download(%v)", i.suffix, part)
 	path := i.generatePartPath(int(part))
-	if err := checksumExists(path); err != nil {
+	if err := checksumExists(ctx, path); err != nil {
 		return err
 	}
 	dataPath := filepath.Join(path, dataFileName)
 	file, err := os.Open(dataPath)
 	if err != nil {
-		vlog.Errorf("Open(%v) failed: %v", dataPath, err)
+		ctx.Errorf("Open(%v) failed: %v", dataPath, err)
 		return verror.New(ErrOperationFailed, ctx)
 	}
 	defer file.Close()
@@ -218,14 +217,14 @@
 	for {
 		n, err := file.Read(buffer)
 		if err != nil && err != io.EOF {
-			vlog.Errorf("Read() failed: %v", err)
+			ctx.Errorf("Read() failed: %v", err)
 			return verror.New(ErrOperationFailed, ctx)
 		}
 		if n == 0 {
 			break
 		}
 		if err := sender.Send(buffer[:n]); err != nil {
-			vlog.Errorf("Send() failed: %v", err)
+			ctx.Errorf("Send() failed: %v", err)
 			return verror.New(ErrOperationFailed, ctx)
 		}
 	}
@@ -234,15 +233,15 @@
 
 // TODO(jsimsa): Design and implement an access control mechanism for
 // the URL-based downloads.
-func (i *binaryService) DownloadUrl(*context.T, rpc.ServerCall) (string, int64, error) {
-	vlog.Infof("%v.DownloadUrl()", i.suffix)
+func (i *binaryService) DownloadUrl(ctx *context.T, _ rpc.ServerCall) (string, int64, error) {
+	ctx.Infof("%v.DownloadUrl()", i.suffix)
 	return i.state.rootURL + "/" + i.suffix, 0, nil
 }
 
 func (i *binaryService) Stat(ctx *context.T, _ rpc.ServerCall) ([]binary.PartInfo, repository.MediaInfo, error) {
-	vlog.Infof("%v.Stat()", i.suffix)
+	ctx.Infof("%v.Stat()", i.suffix)
 	result := make([]binary.PartInfo, 0)
-	parts, err := getParts(i.path)
+	parts, err := getParts(ctx, i.path)
 	if err != nil {
 		return []binary.PartInfo{}, repository.MediaInfo{}, err
 	}
@@ -254,7 +253,7 @@
 				result = append(result, MissingPart)
 				continue
 			}
-			vlog.Errorf("ReadFile(%v) failed: %v", checksumFile, err)
+			ctx.Errorf("ReadFile(%v) failed: %v", checksumFile, err)
 			return []binary.PartInfo{}, repository.MediaInfo{}, verror.New(ErrOperationFailed, ctx)
 		}
 		dataFile := filepath.Join(part, dataFileName)
@@ -264,7 +263,7 @@
 				result = append(result, MissingPart)
 				continue
 			}
-			vlog.Errorf("Stat(%v) failed: %v", dataFile, err)
+			ctx.Errorf("Stat(%v) failed: %v", dataFile, err)
 			return []binary.PartInfo{}, repository.MediaInfo{}, verror.New(ErrOperationFailed, ctx)
 		}
 		result = append(result, binary.PartInfo{Checksum: string(bytes), Size: fi.Size()})
@@ -272,21 +271,21 @@
 	infoFile := filepath.Join(i.path, mediaInfoFileName)
 	jInfo, err := ioutil.ReadFile(infoFile)
 	if err != nil {
-		vlog.Errorf("ReadFile(%q) failed: %v", infoFile, err)
+		ctx.Errorf("ReadFile(%q) failed: %v", infoFile, err)
 		return []binary.PartInfo{}, repository.MediaInfo{}, verror.New(ErrOperationFailed, ctx)
 	}
 	var mediaInfo repository.MediaInfo
 	if err := json.Unmarshal(jInfo, &mediaInfo); err != nil {
-		vlog.Errorf("json.Unmarshal(%v) failed: %v", jInfo, err)
+		ctx.Errorf("json.Unmarshal(%v) failed: %v", jInfo, err)
 		return []binary.PartInfo{}, repository.MediaInfo{}, verror.New(ErrOperationFailed, ctx)
 	}
 	return result, mediaInfo, nil
 }
 
 func (i *binaryService) Upload(ctx *context.T, call repository.BinaryUploadServerCall, part int32) error {
-	vlog.Infof("%v.Upload(%v)", i.suffix, part)
+	ctx.Infof("%v.Upload(%v)", i.suffix, part)
 	path, suffix := i.generatePartPath(int(part)), ""
-	err := checksumExists(path)
+	err := checksumExists(ctx, path)
 	if err == nil {
 		return verror.New(verror.ErrExist, ctx, path)
 	} else if verror.ErrorID(err) != verror.ErrNoExist.ID {
@@ -299,14 +298,14 @@
 		if os.IsExist(err) {
 			return verror.New(ErrInProgress, ctx, path)
 		}
-		vlog.Errorf("OpenFile(%v, %v, %v) failed: %v", lockPath, flags, suffix, err)
+		ctx.Errorf("OpenFile(%v, %v, %v) failed: %v", lockPath, flags, suffix, err)
 		return verror.New(ErrOperationFailed, ctx)
 	}
 	defer os.Remove(lockFile.Name())
 	defer lockFile.Close()
 	file, err := ioutil.TempFile(path, suffix)
 	if err != nil {
-		vlog.Errorf("TempFile(%v, %v) failed: %v", path, suffix, err)
+		ctx.Errorf("TempFile(%v, %v) failed: %v", path, suffix, err)
 		return verror.New(ErrOperationFailed, ctx)
 	}
 	defer file.Close()
@@ -315,9 +314,9 @@
 	for rStream.Advance() {
 		bytes := rStream.Value()
 		if _, err := file.Write(bytes); err != nil {
-			vlog.Errorf("Write() failed: %v", err)
+			ctx.Errorf("Write() failed: %v", err)
 			if err := os.Remove(file.Name()); err != nil {
-				vlog.Errorf("Remove(%v) failed: %v", file.Name(), err)
+				ctx.Errorf("Remove(%v) failed: %v", file.Name(), err)
 			}
 			return verror.New(ErrOperationFailed, ctx)
 		}
@@ -325,9 +324,9 @@
 	}
 
 	if err := rStream.Err(); err != nil {
-		vlog.Errorf("Advance() failed: %v", err)
+		ctx.Errorf("Advance() failed: %v", err)
 		if err := os.Remove(file.Name()); err != nil {
-			vlog.Errorf("Remove(%v) failed: %v", file.Name(), err)
+			ctx.Errorf("Remove(%v) failed: %v", file.Name(), err)
 		}
 		return verror.New(ErrOperationFailed, ctx)
 	}
@@ -335,17 +334,17 @@
 	hash := hex.EncodeToString(h.Sum(nil))
 	checksumFile, perm := filepath.Join(path, checksumFileName), os.FileMode(0600)
 	if err := ioutil.WriteFile(checksumFile, []byte(hash), perm); err != nil {
-		vlog.Errorf("WriteFile(%v, %v, %v) failed: %v", checksumFile, hash, perm, err)
+		ctx.Errorf("WriteFile(%v, %v, %v) failed: %v", checksumFile, hash, perm, err)
 		if err := os.Remove(file.Name()); err != nil {
-			vlog.Errorf("Remove(%v) failed: %v", file.Name(), err)
+			ctx.Errorf("Remove(%v) failed: %v", file.Name(), err)
 		}
 		return verror.New(ErrOperationFailed, ctx)
 	}
 	dataFile := filepath.Join(path, dataFileName)
 	if err := os.Rename(file.Name(), dataFile); err != nil {
-		vlog.Errorf("Rename(%v, %v) failed: %v", file.Name(), dataFile, err)
+		ctx.Errorf("Rename(%v, %v) failed: %v", file.Name(), dataFile, err)
 		if err := os.Remove(file.Name()); err != nil {
-			vlog.Errorf("Remove(%v) failed: %v", file.Name(), err)
+			ctx.Errorf("Remove(%v) failed: %v", file.Name(), err)
 		}
 		return verror.New(ErrOperationFailed, ctx)
 	}
diff --git a/services/internal/binarylib/setup.go b/services/internal/binarylib/setup.go
index aad59eb..e01ab2b 100644
--- a/services/internal/binarylib/setup.go
+++ b/services/internal/binarylib/setup.go
@@ -9,7 +9,7 @@
 	"os"
 	"path/filepath"
 
-	"v.io/x/lib/vlog"
+	"v.io/x/ref/internal/logger"
 )
 
 const defaultRootPrefix = "veyron_binary_repository"
@@ -20,12 +20,12 @@
 	if root == "" {
 		var err error
 		if root, err = ioutil.TempDir("", defaultRootPrefix); err != nil {
-			vlog.Errorf("TempDir() failed: %v\n", err)
+			logger.Global().Errorf("TempDir() failed: %v\n", err)
 			return "", err
 		}
 		path, perm := filepath.Join(root, VersionFile), os.FileMode(0600)
 		if err := ioutil.WriteFile(path, []byte(Version), perm); err != nil {
-			vlog.Errorf("WriteFile(%v, %v, %v) failed: %v", path, Version, perm, err)
+			logger.Global().Errorf("WriteFile(%v, %v, %v) failed: %v", path, Version, perm, err)
 			return "", err
 		}
 		return root, nil
@@ -37,16 +37,16 @@
 	case os.IsNotExist(err):
 		perm := os.FileMode(0700)
 		if err := os.MkdirAll(root, perm); err != nil {
-			vlog.Errorf("MkdirAll(%v, %v) failed: %v", root, perm, err)
+			logger.Global().Errorf("MkdirAll(%v, %v) failed: %v", root, perm, err)
 			return "", err
 		}
 		path, perm := filepath.Join(root, VersionFile), os.FileMode(0600)
 		if err := ioutil.WriteFile(path, []byte(Version), perm); err != nil {
-			vlog.Errorf("WriteFile(%v, %v, %v) failed: %v", path, Version, perm, err)
+			logger.Global().Errorf("WriteFile(%v, %v, %v) failed: %v", path, Version, perm, err)
 			return "", err
 		}
 	default:
-		vlog.Errorf("Stat(%v) failed: %v", root, err)
+		logger.Global().Errorf("Stat(%v) failed: %v", root, err)
 		return "", err
 	}
 	return root, nil
diff --git a/services/internal/logreaderlib/logfile.go b/services/internal/logreaderlib/logfile.go
index dafd11d..3f24a21 100644
--- a/services/internal/logreaderlib/logfile.go
+++ b/services/internal/logreaderlib/logfile.go
@@ -19,7 +19,6 @@
 	"v.io/v23/rpc"
 	"v.io/v23/services/logreader"
 	"v.io/v23/verror"
-	"v.io/x/lib/vlog"
 )
 
 const pkgPath = "v.io/x/ref/services/internal/logreaderlib"
@@ -58,7 +57,7 @@
 
 // Size returns the size of the log file, in bytes.
 func (i *logfileService) Size(ctx *context.T, _ rpc.ServerCall) (int64, error) {
-	vlog.VI(1).Infof("%v.Size()", i.suffix)
+	ctx.VI(1).Infof("%v.Size()", i.suffix)
 	fname, err := translateNameToFilename(i.root, i.suffix)
 	if err != nil {
 		return 0, err
@@ -68,7 +67,7 @@
 		if os.IsNotExist(err) {
 			return 0, verror.New(verror.ErrNoExist, ctx, fname)
 		}
-		vlog.Errorf("Stat(%v) failed: %v", fname, err)
+		ctx.Errorf("Stat(%v) failed: %v", fname, err)
 		return 0, verror.New(errOperationFailed, ctx, fname)
 	}
 	if fi.IsDir() {
@@ -79,7 +78,7 @@
 
 // ReadLog returns log entries from the log file.
 func (i *logfileService) ReadLog(ctx *context.T, call logreader.LogFileReadLogServerCall, startpos int64, numEntries int32, follow bool) (int64, error) {
-	vlog.VI(1).Infof("%v.ReadLog(%v, %v, %v)", i.suffix, startpos, numEntries, follow)
+	ctx.VI(1).Infof("%v.ReadLog(%v, %v, %v)", i.suffix, startpos, numEntries, follow)
 	fname, err := translateNameToFilename(i.root, i.suffix)
 	if err != nil {
 		return 0, err
@@ -116,7 +115,7 @@
 // GlobChildren__ returns the list of files in a directory streamed on a
 // channel. The list is empty if the object is a file.
 func (i *logfileService) GlobChildren__(ctx *context.T, _ rpc.ServerCall) (<-chan string, error) {
-	vlog.VI(1).Infof("%v.GlobChildren__()", i.suffix)
+	ctx.VI(1).Infof("%v.GlobChildren__()", i.suffix)
 	dirName, err := translateNameToFilename(i.root, i.suffix)
 	if err != nil {
 		return nil, err
diff --git a/services/internal/pathperms/hierarchical_authorizer.go b/services/internal/pathperms/hierarchical_authorizer.go
index 3d6c5f1..617ef11 100644
--- a/services/internal/pathperms/hierarchical_authorizer.go
+++ b/services/internal/pathperms/hierarchical_authorizer.go
@@ -8,7 +8,6 @@
 	"v.io/v23/context"
 	"v.io/v23/security"
 	"v.io/v23/security/access"
-	"v.io/x/lib/vlog"
 )
 
 // hierarchicalAuthorizer contains the state needed to implement
@@ -45,7 +44,7 @@
 	if err != nil {
 		return err
 	} else if intentionallyEmpty {
-		vlog.VI(2).Infof("PermsForPath(%s) is intentionally empty", ha.rootDir)
+		ctx.VI(2).Infof("PermsForPath(%s) is intentionally empty", ha.rootDir)
 		return security.DefaultAuthorizer().Authorize(ctx, call)
 	}
 
diff --git a/services/internal/pathperms/permsaccess.go b/services/internal/pathperms/permsaccess.go
index 006a717..4a5eede 100644
--- a/services/internal/pathperms/permsaccess.go
+++ b/services/internal/pathperms/permsaccess.go
@@ -14,11 +14,12 @@
 	"path/filepath"
 	"sync"
 
+	"v.io/v23"
 	"v.io/v23/context"
 	"v.io/v23/security"
 	"v.io/v23/security/access"
 	"v.io/v23/verror"
-	"v.io/x/lib/vlog"
+
 	"v.io/x/ref/lib/security/serialization"
 )
 
@@ -43,13 +44,14 @@
 type PathStore struct {
 	pthlks    map[string]*pathEntry
 	lk        sync.Mutex
+	ctx       *context.T
 	principal security.Principal
 }
 
 // NewPathStore creates a new instance of the lock map that uses
 // principal to sign stored Permissions files.
-func NewPathStore(principal security.Principal) *PathStore {
-	return &PathStore{pthlks: make(map[string]*pathEntry), principal: principal}
+func NewPathStore(ctx *context.T) *PathStore {
+	return &PathStore{pthlks: make(map[string]*pathEntry), ctx: ctx, principal: v23.GetPrincipal(ctx)}
 }
 
 // Get returns the Permissions from the data file in dir.
@@ -57,7 +59,7 @@
 	permspath := filepath.Join(dir, permsName)
 	sigpath := filepath.Join(dir, sigName)
 	defer store.lockPath(dir)()
-	return getCore(store.principal, permspath, sigpath)
+	return getCore(store.ctx, permspath, sigpath)
 }
 
 // TODO(rjkroege): Improve lock handling.
@@ -83,18 +85,19 @@
 	}
 }
 
-func getCore(principal security.Principal, permspath, sigpath string) (access.Permissions, string, error) {
+func getCore(ctx *context.T, permspath, sigpath string) (access.Permissions, string, error) {
+	principal := v23.GetPrincipal(ctx)
 	f, err := os.Open(permspath)
 	if err != nil {
 		// This path is rarely a fatal error so log informationally only.
-		vlog.VI(2).Infof("os.Open(%s) failed: %v", permspath, err)
+		ctx.VI(2).Infof("os.Open(%s) failed: %v", permspath, err)
 		return nil, "", err
 	}
 	defer f.Close()
 
 	s, err := os.Open(sigpath)
 	if err != nil {
-		vlog.Errorf("Signatures for Permissions are required: %s unavailable: %v", permspath, err)
+		ctx.Errorf("Signatures for Permissions are required: %s unavailable: %v", permspath, err)
 		return nil, "", verror.New(ErrOperationFailed, nil)
 	}
 	defer s.Close()
@@ -102,18 +105,18 @@
 	// read and verify the signature of the perms file
 	vf, err := serialization.NewVerifyingReader(f, s, principal.PublicKey())
 	if err != nil {
-		vlog.Errorf("NewVerifyingReader() failed: %v (perms=%s, sig=%s)", err, permspath, sigpath)
+		ctx.Errorf("NewVerifyingReader() failed: %v (perms=%s, sig=%s)", err, permspath, sigpath)
 		return nil, "", verror.New(ErrOperationFailed, nil)
 	}
 
 	perms, err := access.ReadPermissions(vf)
 	if err != nil {
-		vlog.Errorf("ReadPermissions(%s) failed: %v", permspath, err)
+		ctx.Errorf("ReadPermissions(%s) failed: %v", permspath, err)
 		return nil, "", err
 	}
 	version, err := ComputeVersion(perms)
 	if err != nil {
-		vlog.Errorf("pathperms.ComputeVersion failed: %v", err)
+		ctx.Errorf("pathperms.ComputeVersion failed: %v", err)
 		return nil, "", err
 	}
 	return perms, version, nil
@@ -133,19 +136,20 @@
 	permspath := filepath.Join(dir, permsName)
 	sigpath := filepath.Join(dir, sigName)
 	defer store.lockPath(dir)()
-	_, oversion, err := getCore(store.principal, permspath, sigpath)
+	_, oversion, err := getCore(store.ctx, permspath, sigpath)
 	if err != nil && !os.IsNotExist(err) {
 		return verror.New(ErrOperationFailed, nil)
 	}
 	if len(version) > 0 && version != oversion {
 		return verror.NewErrBadVersion(nil)
 	}
-	return write(store.principal, permspath, sigpath, dir, perms, shareable)
+	return write(store.ctx, permspath, sigpath, dir, perms, shareable)
 }
 
 // write writes the specified Permissions to the permsFile with a
 // signature in sigFile.
-func write(principal security.Principal, permsFile, sigFile, dir string, perms access.Permissions, shareable bool) error {
+func write(ctx *context.T, permsFile, sigFile, dir string, perms access.Permissions, shareable bool) error {
+	principal := v23.GetPrincipal(ctx)
 	filemode := os.FileMode(0600)
 	dirmode := os.FileMode(0700)
 	if shareable {
@@ -159,43 +163,43 @@
 	// those files to the actual data and signature file.
 	data, err := ioutil.TempFile(dir, permsName)
 	if err != nil {
-		vlog.Errorf("Failed to open tmpfile data:%v", err)
+		ctx.Errorf("Failed to open tmpfile data:%v", err)
 		return verror.New(ErrOperationFailed, nil)
 	}
 	defer os.Remove(data.Name())
 	sig, err := ioutil.TempFile(dir, sigName)
 	if err != nil {
-		vlog.Errorf("Failed to open tmpfile sig:%v", err)
+		ctx.Errorf("Failed to open tmpfile sig:%v", err)
 		return verror.New(ErrOperationFailed, nil)
 	}
 	defer os.Remove(sig.Name())
 	writer, err := serialization.NewSigningWriteCloser(data, sig, principal, nil)
 	if err != nil {
-		vlog.Errorf("Failed to create NewSigningWriteCloser:%v", err)
+		ctx.Errorf("Failed to create NewSigningWriteCloser:%v", err)
 		return verror.New(ErrOperationFailed, nil)
 	}
 	if err = perms.WriteTo(writer); err != nil {
-		vlog.Errorf("Failed to SavePermissions:%v", err)
+		ctx.Errorf("Failed to SavePermissions:%v", err)
 		return verror.New(ErrOperationFailed, nil)
 	}
 	if err = writer.Close(); err != nil {
-		vlog.Errorf("Failed to Close() SigningWriteCloser:%v", err)
+		ctx.Errorf("Failed to Close() SigningWriteCloser:%v", err)
 		return verror.New(ErrOperationFailed, nil)
 	}
 	if err := os.Rename(data.Name(), permsFile); err != nil {
-		vlog.Errorf("os.Rename() failed:%v", err)
+		ctx.Errorf("os.Rename() failed:%v", err)
 		return verror.New(ErrOperationFailed, nil)
 	}
 	if err := os.Chmod(permsFile, filemode); err != nil {
-		vlog.Errorf("os.Chmod() failed:%v", err)
+		ctx.Errorf("os.Chmod() failed:%v", err)
 		return verror.New(ErrOperationFailed, nil)
 	}
 	if err := os.Rename(sig.Name(), sigFile); err != nil {
-		vlog.Errorf("os.Rename() failed:%v", err)
+		ctx.Errorf("os.Rename() failed:%v", err)
 		return verror.New(ErrOperationFailed, nil)
 	}
 	if err := os.Chmod(sigFile, filemode); err != nil {
-		vlog.Errorf("os.Chmod() failed:%v", err)
+		ctx.Errorf("os.Chmod() failed:%v", err)
 		return verror.New(ErrOperationFailed, nil)
 	}
 	return nil
diff --git a/services/internal/servicetest/modules.go b/services/internal/servicetest/modules.go
index dcd226b..ee13fa5 100644
--- a/services/internal/servicetest/modules.go
+++ b/services/internal/servicetest/modules.go
@@ -16,8 +16,8 @@
 	"v.io/v23/context"
 	"v.io/v23/options"
 	"v.io/v23/security"
-	"v.io/x/lib/vlog"
 	"v.io/x/ref"
+	"v.io/x/ref/internal/logger"
 	"v.io/x/ref/lib/xrpc"
 	"v.io/x/ref/services/mounttable/mounttablelib"
 	"v.io/x/ref/test/modules"
@@ -36,7 +36,7 @@
 	ctx, shutdown := v23.Init()
 	defer shutdown()
 
-	mt, err := mounttablelib.NewMountTableDispatcher("", "", "mounttable")
+	mt, err := mounttablelib.NewMountTableDispatcher(ctx, "", "", "mounttable")
 	if err != nil {
 		return fmt.Errorf("mounttablelib.NewMountTableDispatcher failed: %s", err)
 	}
@@ -88,20 +88,20 @@
 	sh.ClearVar(ref.EnvCredentials)
 
 	mtName, _ := startRootMT(t, sh)
-	vlog.VI(1).Infof("Started shell mounttable with name %v", mtName)
+	ctx.VI(1).Infof("Started shell mounttable with name %v", mtName)
 
 	// TODO(caprita): Define a GetNamespaceRootsCommand in modules/core and
 	// use that?
 
 	oldNamespaceRoots := v23.GetNamespace(ctx).Roots()
 	fn := func() {
-		vlog.VI(1).Info("------------ CLEANUP ------------")
-		vlog.VI(1).Info("---------------------------------")
-		vlog.VI(1).Info("--(cleaning up shell)------------")
+		ctx.VI(1).Info("------------ CLEANUP ------------")
+		ctx.VI(1).Info("---------------------------------")
+		ctx.VI(1).Info("--(cleaning up shell)------------")
 		if err := sh.Cleanup(os.Stdout, os.Stderr); err != nil {
 			t.Errorf(testutil.FormatLogLine(2, "sh.Cleanup failed with %v", err))
 		}
-		vlog.VI(1).Info("--(done cleaning up shell)-------")
+		ctx.VI(1).Info("--(done cleaning up shell)-------")
 		setNSRoots(t, ctx, oldNamespaceRoots...)
 	}
 	setNSRoots(t, ctx, mtName)
@@ -147,7 +147,7 @@
 	// evaluate the symlink.
 	rootDir, err = filepath.EvalSymlinks(rootDir)
 	if err != nil {
-		vlog.Fatalf("EvalSymlinks(%v) failed: %v", rootDir, err)
+		logger.Global().Fatalf("EvalSymlinks(%v) failed: %v", rootDir, err)
 	}
 
 	return rootDir, func() {
diff --git a/services/internal/statslib/stats.go b/services/internal/statslib/stats.go
index e2d375e..6fc9b49 100644
--- a/services/internal/statslib/stats.go
+++ b/services/internal/statslib/stats.go
@@ -17,7 +17,6 @@
 	"v.io/v23/services/watch"
 	"v.io/v23/vdl"
 	"v.io/v23/verror"
-	"v.io/x/lib/vlog"
 	libstats "v.io/x/ref/lib/stats"
 )
 
@@ -40,7 +39,7 @@
 
 // Glob__ returns the name of all objects that match pattern.
 func (i *statsService) Glob__(ctx *context.T, call rpc.ServerCall, pattern string) (<-chan naming.GlobReply, error) {
-	vlog.VI(1).Infof("%v.Glob__(%q)", i.suffix, pattern)
+	ctx.VI(1).Infof("%v.Glob__(%q)", i.suffix, pattern)
 
 	ch := make(chan naming.GlobReply)
 	go func() {
@@ -50,7 +49,7 @@
 			ch <- naming.GlobReplyEntry{naming.MountEntry{Name: it.Value().Key}}
 		}
 		if err := it.Err(); err != nil {
-			vlog.VI(1).Infof("libstats.Glob(%q, %q) failed: %v", i.suffix, pattern, err)
+			ctx.VI(1).Infof("libstats.Glob(%q, %q) failed: %v", i.suffix, pattern, err)
 		}
 	}()
 	return ch, nil
@@ -59,7 +58,7 @@
 // WatchGlob returns the name and value of the objects that match the request,
 // followed by periodic updates when values change.
 func (i *statsService) WatchGlob(ctx *context.T, call watch.GlobWatcherWatchGlobServerCall, req watch.GlobRequest) error {
-	vlog.VI(1).Infof("%v.WatchGlob(%+v)", i.suffix, req)
+	ctx.VI(1).Infof("%v.WatchGlob(%+v)", i.suffix, req)
 
 	var t time.Time
 Loop:
@@ -99,7 +98,7 @@
 
 // Value returns the value of the receiver object.
 func (i *statsService) Value(ctx *context.T, _ rpc.ServerCall) (*vdl.Value, error) {
-	vlog.VI(1).Infof("%v.Value()", i.suffix)
+	ctx.VI(1).Infof("%v.Value()", i.suffix)
 
 	rv, err := libstats.Value(i.suffix)
 	switch {
diff --git a/services/mounttable/mounttabled/mounttable.go b/services/mounttable/mounttabled/mounttable.go
index 2bc4363..72b8cef 100644
--- a/services/mounttable/mounttabled/mounttable.go
+++ b/services/mounttable/mounttabled/mounttable.go
@@ -13,7 +13,6 @@
 	"v.io/v23"
 	"v.io/v23/context"
 	"v.io/x/lib/cmdline"
-	"v.io/x/lib/vlog"
 	"v.io/x/ref/lib/signals"
 	"v.io/x/ref/lib/v23cmd"
 	_ "v.io/x/ref/runtime/factories/roaming"
@@ -54,6 +53,6 @@
 	fmt.Printf("NAME=%s\n", name)
 
 	// Wait until signal is received.
-	vlog.Info("Received signal ", <-signals.ShutdownOnSignals(ctx))
+	ctx.Info("Received signal ", <-signals.ShutdownOnSignals(ctx))
 	return nil
 }
diff --git a/services/mounttable/mounttablelib/mounttable.go b/services/mounttable/mounttablelib/mounttable.go
index 2885228..358c57f 100644
--- a/services/mounttable/mounttablelib/mounttable.go
+++ b/services/mounttable/mounttablelib/mounttable.go
@@ -21,8 +21,6 @@
 	"v.io/v23/services/mounttable"
 	"v.io/v23/verror"
 
-	"v.io/x/lib/vlog"
-
 	"v.io/x/ref/lib/glob"
 	"v.io/x/ref/lib/stats"
 )
@@ -62,6 +60,7 @@
 // mountTable represents a namespace.  One exists per server instance.
 type mountTable struct {
 	sync.Mutex
+	ctx                *context.T
 	root               *node
 	superUsers         access.AccessList
 	persisting         bool
@@ -114,8 +113,9 @@
 // persistDir is the directory for persisting Permissions.
 //
 // statsPrefix is the prefix for for exported statistics objects.
-func NewMountTableDispatcher(permsFile, persistDir, statsPrefix string) (rpc.Dispatcher, error) {
+func NewMountTableDispatcher(ctx *context.T, permsFile, persistDir, statsPrefix string) (rpc.Dispatcher, error) {
 	mt := &mountTable{
+		ctx:                ctx,
 		root:               new(node),
 		nodeCounter:        stats.NewInteger(naming.Join(statsPrefix, "num-nodes")),
 		serverCounter:      stats.NewInteger(naming.Join(statsPrefix, "num-mounted-servers")),
@@ -124,10 +124,10 @@
 	}
 	mt.root.parent = mt.newNode() // just for its lock
 	if persistDir != "" {
-		mt.persist = newPersistentStore(mt, persistDir)
+		mt.persist = newPersistentStore(ctx, mt, persistDir)
 		mt.persisting = mt.persist != nil
 	}
-	if err := mt.parsePermFile(permsFile); err != nil && !os.IsNotExist(err) {
+	if err := mt.parsePermFile(ctx, permsFile); err != nil && !os.IsNotExist(err) {
 		return nil, err
 	}
 	return mt, nil
@@ -178,7 +178,7 @@
 
 // Lookup implements rpc.Dispatcher.Lookup.
 func (mt *mountTable) Lookup(name string) (interface{}, security.Authorizer, error) {
-	vlog.VI(2).Infof("*********************Lookup %s", name)
+	mt.ctx.VI(2).Infof("*********************Lookup %s", name)
 	ms := &mountContext{
 		name: name,
 		mt:   mt,
@@ -292,7 +292,7 @@
 	cur.parent.Lock()
 	cur.Lock()
 	for i, e := range elems {
-		vlog.VI(2).Infof("satisfying %v %v", elems[0:i], *cur)
+		ctx.VI(2).Infof("satisfying %v %v", elems[0:i], *cur)
 		if call != nil {
 			if err := cur.satisfies(mt, ctx, call, traverseTags); err != nil {
 				cur.parent.Unlock()
@@ -413,7 +413,7 @@
 		// If we removed the node, see if we can remove any of its
 		// ascendants.
 		if removed && len(elems) > 0 {
-			mt.removeUselessRecursive(elems[:len(elems)-1])
+			mt.removeUselessRecursive(ctx, elems[:len(elems)-1])
 		}
 		return nil, nil, nil
 	}
@@ -429,7 +429,7 @@
 // ResolveStep returns the next server in a resolution in the form of a MountEntry.  The name
 // in the mount entry is the name relative to the server's root.
 func (ms *mountContext) ResolveStep(ctx *context.T, call rpc.ServerCall) (entry naming.MountEntry, err error) {
-	vlog.VI(2).Infof("ResolveStep %q", ms.name)
+	ctx.VI(2).Infof("ResolveStep %q", ms.name)
 	mt := ms.mt
 	// Find the next mount point for the name.
 	n, elems, werr := mt.findMountPoint(ctx, call.Security(), ms.elems)
@@ -480,7 +480,7 @@
 	if ttlsecs == 0 {
 		ttlsecs = 10 * 365 * 24 * 60 * 60 // a really long time
 	}
-	vlog.VI(2).Infof("*********************Mount %q -> %s", ms.name, server)
+	ctx.VI(2).Infof("*********************Mount %q -> %s", ms.name, server)
 
 	// Make sure the server address is reasonable.
 	epString := server
@@ -561,9 +561,9 @@
 }
 
 // removeUselessRecursive removes any useless nodes on the tail of the path.
-func (mt *mountTable) removeUselessRecursive(elems []string) {
+func (mt *mountTable) removeUselessRecursive(ctx *context.T, elems []string) {
 	for i := len(elems); i > 0; i-- {
-		n, nelems, _ := mt.traverse(nil, nil, elems[:i], false)
+		n, nelems, _ := mt.traverse(ctx, nil, elems[:i], false)
 		if n == nil {
 			break
 		}
@@ -584,7 +584,7 @@
 // Unmount removes servers from the name in the receiver. If server is specified, only that
 // server is removed.
 func (ms *mountContext) Unmount(ctx *context.T, call rpc.ServerCall, server string) error {
-	vlog.VI(2).Infof("*********************Unmount %q, %s", ms.name, server)
+	ctx.VI(2).Infof("*********************Unmount %q, %s", ms.name, server)
 	mt := ms.mt
 	n, err := mt.findNode(ctx, call.Security(), ms.elems, false, mountTags, nil)
 	if err != nil {
@@ -606,14 +606,14 @@
 	if removed {
 		// If we removed the node, see if we can also remove
 		// any of its ascendants.
-		mt.removeUselessRecursive(ms.elems[:len(ms.elems)-1])
+		mt.removeUselessRecursive(ctx, ms.elems[:len(ms.elems)-1])
 	}
 	return nil
 }
 
 // Delete removes the receiver.  If all is true, any subtree is also removed.
 func (ms *mountContext) Delete(ctx *context.T, call rpc.ServerCall, deleteSubTree bool) error {
-	vlog.VI(2).Infof("*********************Delete %q, %v", ms.name, deleteSubTree)
+	ctx.VI(2).Infof("*********************Delete %q, %v", ms.name, deleteSubTree)
 	if len(ms.elems) == 0 {
 		// We can't delete the root.
 		return verror.New(errCantDeleteRoot, ctx)
@@ -648,7 +648,7 @@
 
 // globStep is called with n and n.parent locked.  Returns with both unlocked.
 func (mt *mountTable) globStep(ctx *context.T, call security.Call, n *node, name string, pattern *glob.Glob, ch chan<- naming.GlobReply) {
-	vlog.VI(2).Infof("globStep(%s, %s)", name, pattern)
+	ctx.VI(2).Infof("globStep(%s, %s)", name, pattern)
 
 	// If this is a mount point, we're done.
 	if m := n.mount; m != nil {
@@ -753,7 +753,7 @@
 // adds a/b while a Glob is in progress, the Glob may return a set of nodes that includes both
 // c/d and a/b.
 func (ms *mountContext) Glob__(ctx *context.T, call rpc.ServerCall, pattern string) (<-chan naming.GlobReply, error) {
-	vlog.VI(2).Infof("mt.Glob %v", ms.elems)
+	ctx.VI(2).Infof("mt.Glob %v", ms.elems)
 	scall := call.Security()
 
 	g, err := glob.Parse(pattern)
@@ -797,7 +797,7 @@
 }
 
 func (ms *mountContext) SetPermissions(ctx *context.T, call rpc.ServerCall, perms access.Permissions, version string) error {
-	vlog.VI(2).Infof("SetPermissions %q", ms.name)
+	ctx.VI(2).Infof("SetPermissions %q", ms.name)
 	mt := ms.mt
 
 	// Find/create node in namespace and add the mount.
@@ -843,7 +843,7 @@
 }
 
 func (ms *mountContext) GetPermissions(ctx *context.T, call rpc.ServerCall) (access.Permissions, string, error) {
-	vlog.VI(2).Infof("GetPermissions %q", ms.name)
+	ctx.VI(2).Infof("GetPermissions %q", ms.name)
 	mt := ms.mt
 
 	// Find node in namespace and add the mount.
diff --git a/services/mounttable/mounttablelib/mounttable_test.go b/services/mounttable/mounttablelib/mounttable_test.go
index 4e08341..9d9df27 100644
--- a/services/mounttable/mounttablelib/mounttable_test.go
+++ b/services/mounttable/mounttablelib/mounttable_test.go
@@ -25,8 +25,8 @@
 	"v.io/v23/security/access"
 	"v.io/v23/services/stats"
 	"v.io/v23/vdl"
-	"v.io/x/lib/vlog"
 
+	"v.io/x/ref/internal/logger"
 	libstats "v.io/x/ref/lib/stats"
 	"v.io/x/ref/lib/xrpc"
 	"v.io/x/ref/services/debug/debuglib"
@@ -187,11 +187,11 @@
 }
 
 func newMT(t *testing.T, permsFile, persistDir, statsDir string, rootCtx *context.T) (func() error, string) {
-	reservedDisp := debuglib.NewDispatcher(vlog.Log.LogDir, nil)
+	reservedDisp := debuglib.NewDispatcher(logger.Manager(logger.Global()).LogDir, nil)
 	ctx := v23.WithReservedNameDispatcher(rootCtx, reservedDisp)
 
 	// Add mount table service.
-	mt, err := mounttablelib.NewMountTableDispatcher(permsFile, persistDir, statsDir)
+	mt, err := mounttablelib.NewMountTableDispatcher(ctx, permsFile, persistDir, statsDir)
 	if err != nil {
 		boom(t, "mounttablelib.NewMountTableDispatcher: %v", err)
 	}
@@ -231,15 +231,15 @@
 	collectionName := naming.JoinAddressName(collectionAddr, "collection")
 
 	// Mount the collection server into the mount table.
-	vlog.Infof("Mount the collection server into the mount table.")
+	rootCtx.Infof("Mount the collection server into the mount table.")
 	doMount(t, rootCtx, mtAddr, "stuff", collectionName, true)
 
 	// Create a few objects and make sure we can read them.
-	vlog.Infof("Create a few objects.")
+	rootCtx.Infof("Create a few objects.")
 	export(t, rootCtx, naming.JoinAddressName(mtAddr, "stuff/the/rain"), "the rain")
 	export(t, rootCtx, naming.JoinAddressName(mtAddr, "stuff/in/spain"), "in spain")
 	export(t, rootCtx, naming.JoinAddressName(mtAddr, "stuff/falls"), "falls mainly on the plain")
-	vlog.Infof("Make sure we can read them.")
+	rootCtx.Infof("Make sure we can read them.")
 	checkContents(t, rootCtx, naming.JoinAddressName(mtAddr, "stuff/the/rain"), "the rain", true)
 	checkContents(t, rootCtx, naming.JoinAddressName(mtAddr, "stuff/in/spain"), "in spain", true)
 	checkContents(t, rootCtx, naming.JoinAddressName(mtAddr, "stuff/falls"), "falls mainly on the plain", true)
@@ -249,11 +249,11 @@
 	checkContents(t, aliceCtx, naming.JoinAddressName(mtAddr, "stuff/the/rain"), "the rain", false)
 
 	// Test multiple mounts.
-	vlog.Infof("Multiple mounts.")
+	rootCtx.Infof("Multiple mounts.")
 	doMount(t, rootCtx, mtAddr, "a/b", collectionName, true)
 	doMount(t, rootCtx, mtAddr, "x/y", collectionName, true)
 	doMount(t, rootCtx, mtAddr, "alpha//beta", collectionName, true)
-	vlog.Infof("Make sure we can read them.")
+	rootCtx.Infof("Make sure we can read them.")
 	checkContents(t, rootCtx, naming.JoinAddressName(mtAddr, "stuff/falls"), "falls mainly on the plain", true)
 	checkContents(t, rootCtx, naming.JoinAddressName(mtAddr, "a/b/falls"), "falls mainly on the plain", true)
 	checkContents(t, rootCtx, naming.JoinAddressName(mtAddr, "x/y/falls"), "falls mainly on the plain", true)
@@ -296,18 +296,18 @@
 	}
 
 	// Test generic unmount.
-	vlog.Info("Test generic unmount.")
+	rootCtx.Info("Test generic unmount.")
 	doUnmount(t, rootCtx, mtAddr, "a/b", "", true)
 	checkContents(t, rootCtx, naming.JoinAddressName(mtAddr, "a/b/falls"), "falls mainly on the plain", false)
 
 	// Test specific unmount.
-	vlog.Info("Test specific unmount.")
+	rootCtx.Info("Test specific unmount.")
 	doMount(t, rootCtx, mtAddr, "a/b", collectionName, true)
 	doUnmount(t, rootCtx, mtAddr, "a/b", collectionName, true)
 	checkContents(t, rootCtx, naming.JoinAddressName(mtAddr, "a/b/falls"), "falls mainly on the plain", false)
 
 	// Try timing out a mount.
-	vlog.Info("Try timing out a mount.")
+	rootCtx.Info("Try timing out a mount.")
 	ft := mounttablelib.NewFakeTimeClock()
 	mounttablelib.SetServerListClock(ft)
 	doMount(t, rootCtx, mtAddr, "stuffWithTTL", collectionName, true)
@@ -316,7 +316,7 @@
 	checkContents(t, rootCtx, naming.JoinAddressName(mtAddr, "stuffWithTTL/the/rain"), "the rain", false)
 
 	// Test unauthorized mount.
-	vlog.Info("Test unauthorized mount.")
+	rootCtx.Info("Test unauthorized mount.")
 	doMount(t, bobCtx, mtAddr, "/a/b", collectionName, false)
 	doMount(t, aliceCtx, mtAddr, "/a/b", collectionName, false)
 
@@ -648,11 +648,13 @@
 }
 
 func TestBadAccessLists(t *testing.T) {
-	_, err := mounttablelib.NewMountTableDispatcher("testdata/invalid.perms", "", "mounttable")
+	ctx, shutdown := test.V23InitWithParams(test.InitParams{})
+	defer shutdown()
+	_, err := mounttablelib.NewMountTableDispatcher(ctx, "testdata/invalid.perms", "", "mounttable")
 	if err == nil {
 		boom(t, "Expected json parse error in permissions file")
 	}
-	_, err = mounttablelib.NewMountTableDispatcher("testdata/doesntexist.perms", "", "mounttable")
+	_, err = mounttablelib.NewMountTableDispatcher(ctx, "testdata/doesntexist.perms", "", "mounttable")
 	if err != nil {
 		boom(t, "Missing permissions file should not cause an error")
 	}
diff --git a/services/mounttable/mounttablelib/neighborhood.go b/services/mounttable/mounttablelib/neighborhood.go
index ac82af2..ef5b672 100644
--- a/services/mounttable/mounttablelib/neighborhood.go
+++ b/services/mounttable/mounttablelib/neighborhood.go
@@ -22,7 +22,8 @@
 	"v.io/v23/services/mounttable"
 	vdltime "v.io/v23/vdlroot/time"
 	"v.io/v23/verror"
-	"v.io/x/lib/vlog"
+
+	"v.io/x/ref/internal/logger"
 
 	mdns "github.com/presotto/go-mdns-sd"
 )
@@ -110,10 +111,10 @@
 	// Start up MDNS, subscribe to the vanadium service, and add us as a vanadium service provider.
 	mdns, err := mdns.NewMDNS(host, "", "", loopback, false)
 	if err != nil {
-		vlog.Errorf("mdns startup failed: %s", err)
+		logger.Global().Errorf("mdns startup failed: %s", err)
 		return nil, err
 	}
-	vlog.VI(2).Infof("listening for service vanadium on port %d", port)
+	logger.Global().VI(2).Infof("listening for service vanadium on port %d", port)
 	mdns.SubscribeToService("vanadium")
 	if host != AnonymousNeighbor {
 		mdns.AddService("vanadium", "", port, txt...)
@@ -128,7 +129,7 @@
 	// interfaces when the network changes.
 	nh.nw, err = netconfig.NewNetConfigWatcher()
 	if err != nil {
-		vlog.Errorf("nighborhood can't watch network: %s", err)
+		logger.Global().Errorf("nighborhood can't watch network: %s", err)
 		return nh, nil
 	}
 	go func() {
@@ -136,7 +137,7 @@
 			return
 		}
 		if _, err := nh.mdns.ScanInterfaces(); err != nil {
-			vlog.Errorf("nighborhood can't scan interfaces: %s", err)
+			logger.Global().Errorf("nighborhood can't scan interfaces: %s", err)
 		}
 	}()
 
@@ -157,7 +158,7 @@
 
 // Lookup implements rpc.Dispatcher.Lookup.
 func (nh *neighborhood) Lookup(name string) (interface{}, security.Authorizer, error) {
-	vlog.VI(1).Infof("*********************LookupServer '%s'\n", name)
+	logger.Global().VI(1).Infof("*********************LookupServer '%s'\n", name)
 	elems := strings.Split(name, "/")[nh.nelems:]
 	if name == "" {
 		elems = nil
@@ -225,14 +226,14 @@
 			neighbors[m.Name] = neighbor
 		}
 	}
-	vlog.VI(2).Infof("members %v neighbors %v", members, neighbors)
+	logger.Global().VI(2).Infof("members %v neighbors %v", members, neighbors)
 	return neighbors
 }
 
 // ResolveStep implements ResolveStep
 func (ns *neighborhoodService) ResolveStep(ctx *context.T, _ rpc.ServerCall) (entry naming.MountEntry, err error) {
 	nh := ns.nh
-	vlog.VI(2).Infof("ResolveStep %v\n", ns.elems)
+	ctx.VI(2).Infof("ResolveStep %v\n", ns.elems)
 	if len(ns.elems) == 0 {
 		//nothing can be mounted at the root
 		err = verror.New(naming.ErrNoSuchNameRoot, ctx, ns.elems)
diff --git a/services/mounttable/mounttablelib/neighborhood_test.go b/services/mounttable/mounttablelib/neighborhood_test.go
index bf0c918..b5c1ff1 100644
--- a/services/mounttable/mounttablelib/neighborhood_test.go
+++ b/services/mounttable/mounttablelib/neighborhood_test.go
@@ -14,7 +14,6 @@
 	"v.io/v23"
 	"v.io/v23/naming"
 	"v.io/v23/options"
-	"v.io/x/lib/vlog"
 
 	_ "v.io/x/ref/runtime/factories/generic"
 	"v.io/x/ref/services/mounttable/mounttablelib"
@@ -37,7 +36,7 @@
 	rootCtx, shutdown := test.V23Init()
 	defer shutdown()
 
-	vlog.Infof("TestNeighborhood")
+	rootCtx.Infof("TestNeighborhood")
 	server, err := v23.NewServer(rootCtx)
 	if err != nil {
 		boom(t, "r.NewServer: %s", err)
diff --git a/services/mounttable/mounttablelib/persistentstore.go b/services/mounttable/mounttablelib/persistentstore.go
index a96eb19..3132e59 100644
--- a/services/mounttable/mounttablelib/persistentstore.go
+++ b/services/mounttable/mounttablelib/persistentstore.go
@@ -12,7 +12,9 @@
 	"strings"
 	"sync"
 
-	"v.io/x/lib/vlog"
+	"v.io/v23/context"
+
+	"v.io/x/ref/internal/logger"
 )
 
 type store struct {
@@ -43,7 +45,7 @@
 //      it will be renamed persistent.perms becoming the new log.
 //   old.permslog - the previous version of persistent.perms.  This is left around primarily for debugging
 //      and as an emergency backup.
-func newPersistentStore(mt *mountTable, dir string) persistence {
+func newPersistentStore(ctx *context.T, mt *mountTable, dir string) persistence {
 	s := &store{mt: mt, dir: dir}
 	file := path.Join(dir, "persistent.permslog")
 	tmp := path.Join(dir, "tmp.permslog")
@@ -53,11 +55,11 @@
 	f, err := os.Open(file)
 	if err != nil {
 		if !os.IsNotExist(err) {
-			vlog.Fatalf("cannot open %s: %s", file, err)
+			logger.Global().Fatalf("cannot open %s: %s", file, err)
 		}
 		os.Rename(tmp, file)
 		if f, err = os.Open(file); err != nil && !os.IsNotExist(err) {
-			vlog.Fatalf("cannot open %s: %s", file, err)
+			logger.Global().Fatalf("cannot open %s: %s", file, err)
 		}
 	} else {
 		os.Remove(tmp)
@@ -65,10 +67,10 @@
 
 	// Parse the permissions file and apply it to the in memory tree.
 	if f != nil {
-		if err := s.parseLogFile(f); err != nil {
+		if err := s.parseLogFile(ctx, f); err != nil {
 			f.Close()
 			// Log the error but keep going.  There's not much else we can do.
-			vlog.Infof("parsing old persistent permissions file %s: %s", file, err)
+			logger.Global().Infof("parsing old persistent permissions file %s: %s", file, err)
 		}
 		f.Close()
 	}
@@ -78,9 +80,9 @@
 	f, err = os.OpenFile(tmp, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0600)
 	if err != nil {
 		// Log the error but keep going, don't compress, just append to the current file.
-		vlog.Infof("can't rewrite persistent permissions file %s: %s", file, err)
+		logger.Global().Infof("can't rewrite persistent permissions file %s: %s", file, err)
 		if f, err = os.OpenFile(file, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0600); err != nil {
-			vlog.Fatalf("can't append to log %s: %s", file, err)
+			logger.Global().Fatalf("can't append to log %s: %s", file, err)
 		}
 		f.Seek(0, 2)
 		s.enc = json.NewEncoder(f)
@@ -92,13 +94,13 @@
 
 	// Switch names and remove the old file.
 	if err := os.Remove(old); err != nil {
-		vlog.Infof("removing %s: %s", old, err)
+		ctx.Infof("removing %s: %s", old, err)
 	}
 	if err := os.Rename(file, old); err != nil {
-		vlog.Infof("renaming %s to %s: %s", file, old, err)
+		ctx.Infof("renaming %s to %s: %s", file, old, err)
 	}
 	if err := os.Rename(tmp, file); err != nil {
-		vlog.Fatalf("renaming %s to %s: %s", tmp, file, err)
+		ctx.Fatalf("renaming %s to %s: %s", tmp, file, err)
 	}
 
 	// Reopen the new log file.  We could have just kept around the encoder used
@@ -106,7 +108,7 @@
 	// points to the same file.  Only true on Unix like file systems.
 	f, err = os.OpenFile(file, os.O_WRONLY|os.O_APPEND, 0600)
 	if err != nil {
-		vlog.Fatalf("can't open %s: %s", file, err)
+		ctx.Fatalf("can't open %s: %s", file, err)
 	}
 	f.Seek(0, 2)
 	s.enc = json.NewEncoder(f)
@@ -114,11 +116,11 @@
 }
 
 // parseLogFile reads a file and parses the contained VersionedPermissions .
-func (s *store) parseLogFile(f *os.File) error {
+func (s *store) parseLogFile(ctx *context.T, f *os.File) error {
 	if f == nil {
 		return nil
 	}
-	vlog.VI(2).Infof("parseLogFile(%s)", f.Name())
+	ctx.VI(2).Infof("parseLogFile(%s)", f.Name())
 	mt := s.mt
 	decoder := json.NewDecoder(f)
 	for {
@@ -131,16 +133,16 @@
 		}
 
 		elems := strings.Split(e.N, "/")
-		n, err := mt.findNode(nil, nil, elems, true, nil, nil)
+		n, err := mt.findNode(ctx, nil, elems, true, nil, nil)
 		if n != nil || err == nil {
 			n.creator = e.C
 			if e.D {
 				mt.deleteNode(n.parent, elems[len(elems)-1])
-				vlog.VI(2).Infof("deleted %s", e.N)
+				ctx.VI(2).Infof("deleted %s", e.N)
 			} else {
 				n.vPerms = &e.V
 				n.explicitPermissions = true
-				vlog.VI(2).Infof("added versions permissions %v to %s", e.V, e.N)
+				ctx.VI(2).Infof("added versions permissions %v to %s", e.V, e.N)
 			}
 		}
 		n.parent.Unlock()
diff --git a/services/mounttable/mounttablelib/servers.go b/services/mounttable/mounttablelib/servers.go
index ef8c550..9b84375 100644
--- a/services/mounttable/mounttablelib/servers.go
+++ b/services/mounttable/mounttablelib/servers.go
@@ -12,6 +12,7 @@
 	"v.io/v23/naming"
 	"v.io/v23/options"
 	"v.io/v23/rpc"
+
 	"v.io/x/lib/vlog"
 	"v.io/x/ref/lib/xrpc"
 )
@@ -24,20 +25,22 @@
 		}
 	}
 
-	mt, err := NewMountTableDispatcher(permsFile, persistDir, debugPrefix)
+	mt, err := NewMountTableDispatcher(ctx, permsFile, persistDir, debugPrefix)
 	if err != nil {
 		vlog.Errorf("NewMountTable failed: %v", err)
 		return "", nil, err
 	}
+	ctx = v23.WithListenSpec(ctx, listenSpec)
 	mtServer, err := xrpc.NewDispatchingServer(ctx, mountName, mt, options.ServesMountTable(true))
 	if err != nil {
-		vlog.Errorf("v23.NewServer failed: %v", err)
+
+		ctx.Errorf("v23.NewServer failed: %v", err)
 		return "", nil, err
 	}
 	stopFuncs = append(stopFuncs, mtServer.Stop)
 	mtEndpoints := mtServer.Status().Endpoints
 	mtName := mtEndpoints[0].Name()
-	vlog.Infof("Mount table service at: %q endpoint: %s", mountName, mtName)
+	ctx.Infof("Mount table service at: %q endpoint: %s", mountName, mtName)
 
 	if len(nhName) > 0 {
 		// The ListenSpec code ensures that we have a valid address here.
@@ -61,7 +64,7 @@
 
 		nhServer, err := xrpc.NewDispatchingServer(ctx, naming.Join(mtName, "nh"), nh, options.ServesMountTable(true))
 		if err != nil {
-			vlog.Errorf("v23.NewServer failed: %v", err)
+			ctx.Errorf("v23.NewServer failed: %v", err)
 			stop()
 			return "", nil, err
 		}
diff --git a/services/mounttable/mounttablelib/versionedpermissions.go b/services/mounttable/mounttablelib/versionedpermissions.go
index d4da750..661f9bb 100644
--- a/services/mounttable/mounttablelib/versionedpermissions.go
+++ b/services/mounttable/mounttablelib/versionedpermissions.go
@@ -18,7 +18,6 @@
 	"v.io/v23/security/access"
 	"v.io/v23/services/mounttable"
 	"v.io/v23/verror"
-	"v.io/x/lib/vlog"
 )
 
 // Blessings can't include a comma so we use them in made up user ids.  The following distinctions are
@@ -89,8 +88,8 @@
 }
 
 // parsePermFile reads a file and parses the contained permissions.
-func (mt *mountTable) parsePermFile(path string) error {
-	vlog.VI(2).Infof("parsePermFile(%s)", path)
+func (mt *mountTable) parsePermFile(ctx *context.T, path string) error {
+	ctx.VI(2).Infof("parsePermFile(%s)", path)
 	if path == "" {
 		return nil
 	}
@@ -143,9 +142,9 @@
 			}
 
 			// Create name and add the Permissions map to it.
-			n, err := mt.findNode(nil, nil, elems, true, nil, nil)
+			n, err := mt.findNode(ctx, nil, elems, true, nil, nil)
 			if n != nil || err == nil {
-				vlog.VI(2).Infof("added perms %v to %s", perms, name)
+				ctx.VI(2).Infof("added perms %v to %s", perms, name)
 				if isPattern {
 					n.permsTemplate = perms
 				} else {
diff --git a/services/profile/profile/impl_test.go b/services/profile/profile/impl_test.go
index e3695fb..98debf6 100644
--- a/services/profile/profile/impl_test.go
+++ b/services/profile/profile/impl_test.go
@@ -17,7 +17,6 @@
 	"v.io/v23/services/build"
 
 	"v.io/x/lib/cmdline"
-	"v.io/x/lib/vlog"
 	"v.io/x/ref/lib/v23cmd"
 	"v.io/x/ref/lib/xrpc"
 	_ "v.io/x/ref/runtime/factories/generic"
@@ -44,37 +43,37 @@
 	suffix string
 }
 
-func (s *server) Label(*context.T, rpc.ServerCall) (string, error) {
-	vlog.VI(2).Infof("%v.Label() was called", s.suffix)
+func (s *server) Label(ctx *context.T, _ rpc.ServerCall) (string, error) {
+	ctx.VI(2).Infof("%v.Label() was called", s.suffix)
 	if s.suffix != "exists" {
 		return "", fmt.Errorf("profile doesn't exist: %v", s.suffix)
 	}
 	return spec.Label, nil
 }
 
-func (s *server) Description(*context.T, rpc.ServerCall) (string, error) {
-	vlog.VI(2).Infof("%v.Description() was called", s.suffix)
+func (s *server) Description(ctx *context.T, _ rpc.ServerCall) (string, error) {
+	ctx.VI(2).Infof("%v.Description() was called", s.suffix)
 	if s.suffix != "exists" {
 		return "", fmt.Errorf("profile doesn't exist: %v", s.suffix)
 	}
 	return spec.Description, nil
 }
 
-func (s *server) Specification(*context.T, rpc.ServerCall) (profile.Specification, error) {
-	vlog.VI(2).Infof("%v.Specification() was called", s.suffix)
+func (s *server) Specification(ctx *context.T, _ rpc.ServerCall) (profile.Specification, error) {
+	ctx.VI(2).Infof("%v.Specification() was called", s.suffix)
 	if s.suffix != "exists" {
 		return profile.Specification{}, fmt.Errorf("profile doesn't exist: %v", s.suffix)
 	}
 	return spec, nil
 }
 
-func (s *server) Put(_ *context.T, _ rpc.ServerCall, _ profile.Specification) error {
-	vlog.VI(2).Infof("%v.Put() was called", s.suffix)
+func (s *server) Put(ctx *context.T, _ rpc.ServerCall, _ profile.Specification) error {
+	ctx.VI(2).Infof("%v.Put() was called", s.suffix)
 	return nil
 }
 
-func (s *server) Remove(*context.T, rpc.ServerCall) error {
-	vlog.VI(2).Infof("%v.Remove() was called", s.suffix)
+func (s *server) Remove(ctx *context.T, _ rpc.ServerCall) error {
+	ctx.VI(2).Infof("%v.Remove() was called", s.suffix)
 	if s.suffix != "exists" {
 		return fmt.Errorf("profile doesn't exist: %v", s.suffix)
 	}
diff --git a/services/profile/profiled/main.go b/services/profile/profiled/main.go
index 72518f7..93cf635 100644
--- a/services/profile/profiled/main.go
+++ b/services/profile/profiled/main.go
@@ -12,7 +12,6 @@
 
 	"v.io/v23/context"
 	"v.io/x/lib/cmdline"
-	"v.io/x/lib/vlog"
 	"v.io/x/ref/lib/security/securityflag"
 	"v.io/x/ref/lib/signals"
 	"v.io/x/ref/lib/v23cmd"
@@ -54,7 +53,7 @@
 	if err != nil {
 		return fmt.Errorf("NewServer() failed: %v", err)
 	}
-	vlog.Infof("Profile repository running at endpoint=%v", server.Status().Endpoints[0])
+	ctx.Infof("Profile repository running at endpoint=%v", server.Status().Endpoints[0])
 
 	// Wait until shutdown.
 	<-signals.ShutdownOnSignals(ctx)
diff --git a/services/profile/profiled/service.go b/services/profile/profiled/service.go
index d30613f..9f8f689 100644
--- a/services/profile/profiled/service.go
+++ b/services/profile/profiled/service.go
@@ -14,7 +14,6 @@
 	"v.io/v23/context"
 	"v.io/v23/naming"
 	"v.io/v23/rpc"
-	"v.io/x/lib/vlog"
 )
 
 // profileService implements the Profile server interface.
@@ -40,7 +39,7 @@
 // STORE MANAGEMENT INTERFACE IMPLEMENTATION
 
 func (i *profileService) Put(ctx *context.T, call rpc.ServerCall, profile profile.Specification) error {
-	vlog.VI(0).Infof("%v.Put(%v)", i.suffix, profile)
+	ctx.VI(0).Infof("%v.Put(%v)", i.suffix, profile)
 	// Transaction is rooted at "", so tname == tid.
 	i.store.Lock()
 	defer i.store.Unlock()
@@ -60,7 +59,7 @@
 }
 
 func (i *profileService) Remove(ctx *context.T, call rpc.ServerCall) error {
-	vlog.VI(0).Infof("%v.Remove()", i.suffix)
+	ctx.VI(0).Infof("%v.Remove()", i.suffix)
 	i.store.Lock()
 	defer i.store.Unlock()
 	// Transaction is rooted at "", so tname == tid.
@@ -107,7 +106,7 @@
 }
 
 func (i *profileService) Label(ctx *context.T, call rpc.ServerCall) (string, error) {
-	vlog.VI(0).Infof("%v.Label()", i.suffix)
+	ctx.VI(0).Infof("%v.Label()", i.suffix)
 	s, err := i.lookup(call)
 	if err != nil {
 		return "", err
@@ -116,7 +115,7 @@
 }
 
 func (i *profileService) Description(ctx *context.T, call rpc.ServerCall) (string, error) {
-	vlog.VI(0).Infof("%v.Description()", i.suffix)
+	ctx.VI(0).Infof("%v.Description()", i.suffix)
 	s, err := i.lookup(call)
 	if err != nil {
 		return "", err
@@ -125,6 +124,6 @@
 }
 
 func (i *profileService) Specification(ctx *context.T, call rpc.ServerCall) (profile.Specification, error) {
-	vlog.VI(0).Infof("%v.Specification()", i.suffix)
+	ctx.VI(0).Infof("%v.Specification()", i.suffix)
 	return i.lookup(call)
 }
diff --git a/services/proxy/proxyd/main.go b/services/proxy/proxyd/main.go
index 42053e9..1333581 100644
--- a/services/proxy/proxyd/main.go
+++ b/services/proxy/proxyd/main.go
@@ -14,13 +14,15 @@
 	"net/http"
 	"time"
 
+	"v.io/x/lib/cmdline"
+
 	"v.io/v23"
 	"v.io/v23/context"
+	"v.io/v23/logging"
 	"v.io/v23/rpc"
 	"v.io/v23/security"
 	"v.io/v23/security/access"
-	"v.io/x/lib/cmdline"
-	"v.io/x/lib/vlog"
+
 	"v.io/x/ref/lib/signals"
 	"v.io/x/ref/lib/v23cmd"
 	"v.io/x/ref/lib/xrpc"
@@ -66,7 +68,7 @@
 		// Always add ourselves, for the the reserved methods server
 		// started below.
 		list.In = append(list.In, security.DefaultBlessingPatterns(v23.GetPrincipal(ctx))...)
-		vlog.Infof("Using access list to control proxy use: %v", list)
+		ctx.Infof("Using access list to control proxy use: %v", list)
 		authorizer = list
 	}
 
@@ -85,7 +87,7 @@
 	}
 
 	if len(healthzAddr) != 0 {
-		go startHealthzServer(healthzAddr)
+		go startHealthzServer(ctx, healthzAddr)
 	}
 
 	// Start an RPC Server that listens through the proxy itself. This
@@ -120,7 +122,7 @@
 // startHealthzServer starts a HTTP server that simply returns "ok" to every
 // request. This is needed to let the load balancer know that the proxy server
 // is running.
-func startHealthzServer(addr string) {
+func startHealthzServer(logger logging.Logger, addr string) {
 	s := http.Server{
 		Addr:         addr,
 		Handler:      healthzHandler{},
@@ -128,6 +130,6 @@
 		WriteTimeout: 10 * time.Second,
 	}
 	if err := s.ListenAndServe(); err != nil {
-		vlog.Fatal(err)
+		logger.Fatal(err)
 	}
 }
diff --git a/services/role/roled/internal/discharger.go b/services/role/roled/internal/discharger.go
index 2a624cc..d6db009 100644
--- a/services/role/roled/internal/discharger.go
+++ b/services/role/roled/internal/discharger.go
@@ -14,13 +14,11 @@
 	"v.io/v23/verror"
 
 	"v.io/x/ref/services/discharger"
-
-	"v.io/x/lib/vlog"
 )
 
 func init() {
-	security.RegisterCaveatValidator(LoggingCaveat, func(_ *context.T, _ security.Call, params []string) error {
-		vlog.Infof("Params: %#v", params)
+	security.RegisterCaveatValidator(LoggingCaveat, func(ctx *context.T, _ security.Call, params []string) error {
+		ctx.Infof("Params: %#v", params)
 		return nil
 	})
 
@@ -39,7 +37,7 @@
 		return security.Discharge{}, err
 	}
 	// TODO(rthellend,ashankar): Do proper logging when the API allows it.
-	vlog.Infof("Discharge() impetus: %#v", impetus)
+	ctx.Infof("Discharge() impetus: %#v", impetus)
 
 	expiry, err := security.NewExpiryCaveat(time.Now().Add(5 * time.Minute))
 	if err != nil {
diff --git a/services/role/roled/internal/dispatcher.go b/services/role/roled/internal/dispatcher.go
index 475beb5..f741d34 100644
--- a/services/role/roled/internal/dispatcher.go
+++ b/services/role/roled/internal/dispatcher.go
@@ -16,10 +16,9 @@
 	"v.io/v23/security"
 	"v.io/v23/verror"
 
+	"v.io/x/ref/internal/logger"
 	"v.io/x/ref/services/discharger"
 	"v.io/x/ref/services/role"
-
-	"v.io/x/lib/vlog"
 )
 
 const requiredSuffix = security.ChainSeparator + role.RoleSuffix
@@ -58,7 +57,7 @@
 	if err != nil && !os.IsNotExist(err) {
 		// The config file exists, but we failed to read it for some
 		// reason. This is likely a server configuration error.
-		vlog.Errorf("loadConfig(%q, %q): %v", d.config.root, suffix, err)
+		logger.Global().Errorf("loadConfig(%q, %q): %v", d.config.root, suffix, err)
 		return nil, nil, verror.Convert(verror.ErrInternal, nil, err)
 	}
 	obj := &roleService{serverConfig: d.config, role: suffix, roleConfig: roleConfig}
@@ -112,7 +111,6 @@
 		f := filepath.Join(parentDir, filepath.FromSlash(imp+".conf"))
 		ic, err := loadExpandedConfig(f, seenFiles)
 		if err != nil {
-			vlog.Errorf("loadExpandedConfig(%q) failed: %v", f, err)
 			continue
 		}
 		if ic == nil {
diff --git a/services/role/roled/internal/role.go b/services/role/roled/internal/role.go
index 9d0e332..a46a31d 100644
--- a/services/role/roled/internal/role.go
+++ b/services/role/roled/internal/role.go
@@ -14,8 +14,6 @@
 	"v.io/v23/security"
 	"v.io/v23/verror"
 
-	"v.io/x/lib/vlog"
-
 	"v.io/x/ref/services/role"
 )
 
@@ -31,7 +29,7 @@
 
 func (i *roleService) SeekBlessings(ctx *context.T, call rpc.ServerCall) (security.Blessings, error) {
 	remoteBlessingNames, _ := security.RemoteBlessingNames(ctx, call.Security())
-	vlog.Infof("%q.SeekBlessings() called by %q", i.role, remoteBlessingNames)
+	ctx.Infof("%q.SeekBlessings() called by %q", i.role, remoteBlessingNames)
 
 	members := i.filterNonMembers(remoteBlessingNames)
 	if len(members) == 0 {
diff --git a/services/wspr/internal/app/app_test.go b/services/wspr/internal/app/app_test.go
index b9d242f..69cc32e 100644
--- a/services/wspr/internal/app/app_test.go
+++ b/services/wspr/internal/app/app_test.go
@@ -315,7 +315,7 @@
 }
 
 func serveServer(ctx *context.T, writer lib.ClientWriter, setController func(*Controller)) (*runningTest, error) {
-	mt, err := mounttablelib.NewMountTableDispatcher("", "", "mounttable")
+	mt, err := mounttablelib.NewMountTableDispatcher(ctx, "", "", "mounttable")
 	if err != nil {
 		return nil, fmt.Errorf("unable to start mounttable: %v", err)
 	}
diff --git a/services/wspr/internal/browspr/browspr_test.go b/services/wspr/internal/browspr/browspr_test.go
index 270d263..5841efa 100644
--- a/services/wspr/internal/browspr/browspr_test.go
+++ b/services/wspr/internal/browspr/browspr_test.go
@@ -77,7 +77,7 @@
 	}
 	defer proxyShutdown()
 
-	mt, err := mounttablelib.NewMountTableDispatcher("", "", "mounttable")
+	mt, err := mounttablelib.NewMountTableDispatcher(ctx, "", "", "mounttable")
 	if err != nil {
 		t.Fatalf("Failed to create mounttable: %v", err)
 	}
diff --git a/test/init.go b/test/init.go
index fae8ba3..0dc5cf7 100644
--- a/test/init.go
+++ b/test/init.go
@@ -39,7 +39,7 @@
 }
 
 // Init sets up state for running tests: Adjusting GOMAXPROCS,
-// configuring the vlog logging library, setting up the random number generator
+// configuring the logging library, setting up the random number generator
 // etc.
 //
 // Doing so requires flags to be parsed, so this function explicitly parses
@@ -96,7 +96,7 @@
 		}
 	}
 	if params.CreateMounttable {
-		disp, err := mounttablelib.NewMountTableDispatcher("", "", "mounttable")
+		disp, err := mounttablelib.NewMountTableDispatcher(ctx, "", "", "mounttable")
 		if err != nil {
 			panic(err)
 		}