Merge "veyron/tools/principal: Tweaks to work with the --veyron.credentials flag"
diff --git a/lib/flags/consts/consts.go b/lib/flags/consts/consts.go
new file mode 100644
index 0000000..7ed0112
--- /dev/null
+++ b/lib/flags/consts/consts.go
@@ -0,0 +1,12 @@
+// Package consts defines named constants whose values are interpreted by the flags package.
+package consts
+
+const (
+	// Environment variable whose value points to a directory containing
+	// the state of a Principal.  (Private key, blessings, recognized root
+	// certificates etc.)
+	VeyronCredentials = "VEYRON_CREDENTIALS"
+	// Prefix of all environment variables that point to roots of the
+	// veyron namespace, used to resolve non-rooted object names.
+	NamespaceRootPrefix = "NAMESPACE_ROOT"
+)
diff --git a/lib/flags/flags.go b/lib/flags/flags.go
index 0e664e4..b1313e1 100644
--- a/lib/flags/flags.go
+++ b/lib/flags/flags.go
@@ -5,6 +5,8 @@
 	"fmt"
 	"os"
 	"strings"
+
+	"veyron.io/veyron/veyron/lib/flags/consts"
 )
 
 // FlagGroup is the type for identifying groups of related flags.
@@ -164,12 +166,11 @@
 			continue
 		}
 		k, v := p[0], p[1]
-		if strings.HasPrefix(k, "NAMESPACE_ROOT") && len(v) > 0 {
+		if strings.HasPrefix(k, consts.NamespaceRootPrefix) && len(v) > 0 {
 			roots = append(roots, v)
 		}
 	}
-	creds := os.Getenv("VEYRON_CREDENTIALS")
-	return roots, creds
+	return roots, os.Getenv(consts.VeyronCredentials)
 }
 
 // Parse parses the supplied args, as per flag.Parse
diff --git a/lib/flags/flags_test.go b/lib/flags/flags_test.go
index 4e9c31a..c802942 100644
--- a/lib/flags/flags_test.go
+++ b/lib/flags/flags_test.go
@@ -8,6 +8,7 @@
 	"testing"
 
 	"veyron.io/veyron/veyron/lib/flags"
+	"veyron.io/veyron/veyron/lib/flags/consts"
 )
 
 func TestFlags(t *testing.T) {
@@ -74,20 +75,21 @@
 	}
 }
 
-const credEnvVar = "VEYRON_CREDENTIALS"
-const rootEnvVar = "NAMESPACE_ROOT"
-const rootEnvVar0 = "NAMESPACE_ROOT0"
+const (
+	rootEnvVar  = consts.NamespaceRootPrefix
+	rootEnvVar0 = consts.NamespaceRootPrefix + "0"
+)
 
 func TestEnvVars(t *testing.T) {
-	oldcreds := os.Getenv(credEnvVar)
-	defer os.Setenv(credEnvVar, oldcreds)
+	oldcreds := os.Getenv(consts.VeyronCredentials)
+	defer os.Setenv(consts.VeyronCredentials, oldcreds)
 
 	oldroot := os.Getenv(rootEnvVar)
 	oldroot0 := os.Getenv(rootEnvVar0)
 	defer os.Setenv(rootEnvVar, oldroot)
 	defer os.Setenv(rootEnvVar0, oldroot0)
 
-	os.Setenv(credEnvVar, "bar")
+	os.Setenv(consts.VeyronCredentials, "bar")
 	fl := flags.CreateAndRegister(flag.NewFlagSet("test", flag.ContinueOnError), flags.Runtime)
 	if err := fl.Parse([]string{}); err != nil {
 		t.Fatalf("unexpected error: %s", err)
diff --git a/lib/modules/core/core_test.go b/lib/modules/core/core_test.go
index 19ee38b..23037c0 100644
--- a/lib/modules/core/core_test.go
+++ b/lib/modules/core/core_test.go
@@ -14,6 +14,7 @@
 	"veyron.io/veyron/veyron2/vlog"
 
 	"veyron.io/veyron/veyron/lib/expect"
+	"veyron.io/veyron/veyron/lib/flags/consts"
 	"veyron.io/veyron/veyron/lib/modules"
 	"veyron.io/veyron/veyron/lib/modules/core"
 	"veyron.io/veyron/veyron/lib/testutil"
@@ -78,7 +79,7 @@
 	if t.Failed() {
 		return nil, nil, rootSession.Error()
 	}
-	sh.SetVar("NAMESPACE_ROOT", rootName)
+	sh.SetVar(consts.NamespaceRootPrefix, rootName)
 	mountAddrs := make(map[string]string)
 	mountAddrs["root"] = rootName
 
@@ -166,7 +167,7 @@
 		t.Errorf("got %v, want %v", got, want)
 	}
 
-	// Run the ls command in a subprocess, with NAMESPACE_ROOT as set above.
+	// Run the ls command in a subprocess, with consts.NamespaceRootPrefix as set above.
 	lse, err := sh.Start(core.LSExternalCommand, nil, "...")
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
@@ -180,9 +181,10 @@
 
 	pattern = ""
 	for _, n := range mountPoints {
-		// Since the LSExternalCommand runs in a subprocess with NAMESPACE_ROOT
-		// set to the name of the root mount table it sees to the relative name
-		// format of the mounted mount tables.
+		// Since the LSExternalCommand runs in a subprocess with
+		// consts.NamespaceRootPrefix set to the name of the root mount
+		// table it sees to the relative name format of the mounted
+		// mount tables.
 		pattern = pattern + "^R[\\d]+=(" + n + "$)|"
 	}
 	pattern = pattern[:len(pattern)-1]
diff --git a/lib/modules/core/echo.go b/lib/modules/core/echo.go
index f3adb9f..8cc7b33 100644
--- a/lib/modules/core/echo.go
+++ b/lib/modules/core/echo.go
@@ -22,7 +22,7 @@
 
 type treeDispatcher struct{ id string }
 
-func (d treeDispatcher) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
+func (d treeDispatcher) Lookup(suffix, method string) (interface{}, security.Authorizer, error) {
 	return ipc.ReflectInvoker(&echoServerObject{d.id, suffix}), nil, nil
 }
 
diff --git a/lib/modules/shell.go b/lib/modules/shell.go
index 1bf3e61..1f2a016 100644
--- a/lib/modules/shell.go
+++ b/lib/modules/shell.go
@@ -49,6 +49,7 @@
 	"sync"
 	"time"
 
+	"veyron.io/veyron/veyron/lib/flags/consts"
 	"veyron.io/veyron/veyron2/vlog"
 )
 
@@ -79,15 +80,14 @@
 
 var child = &childRegistrar{mains: make(map[string]*childEntryPoint)}
 
-// NewShell creates a new instance of Shell. If this new instance is
-// is a test and no credentials have been configured in the environment
-// via VEYRON_CREDENTIALS then CreateAndUseNewCredentials will be used to
-// configure a new ID for the shell and its children.
-// NewShell takes optional regexp patterns that can be used to specify
-// subprocess commands that are implemented in the same binary as this shell
-// (i.e. have been registered using modules.RegisterChild) to be
-// automatically added to it. If the patterns fail to match any such command
-// then they have no effect.
+// NewShell creates a new instance of Shell. If this new instance is is a test
+// and no credentials have been configured in the environment via
+// consts.VeyronCredentials then CreateAndUseNewCredentials will be used to
+// configure a new ID for the shell and its children.  NewShell takes optional
+// regexp patterns that can be used to specify subprocess commands that are
+// implemented in the same binary as this shell (i.e. have been registered
+// using modules.RegisterChild) to be automatically added to it. If the
+// patterns fail to match any such command then they have no effect.
 func NewShell(patterns ...string) *Shell {
 	// TODO(cnicolaou): should create a new identity if one doesn't
 	// already exist
@@ -97,7 +97,7 @@
 		handles:      make(map[Handle]struct{}),
 		startTimeout: time.Minute,
 	}
-	if flag.Lookup("test.run") != nil && os.Getenv("VEYRON_CREDENTIALS") == "" {
+	if flag.Lookup("test.run") != nil && os.Getenv(consts.VeyronCredentials) == "" {
 		if err := sh.CreateAndUseNewCredentials(); err != nil {
 			// TODO(cnicolaou): return an error rather than panic.
 			panic(err)
@@ -125,7 +125,7 @@
 		return err
 	}
 	sh.credDir = dir
-	sh.SetVar("VEYRON_CREDENTIALS", sh.credDir)
+	sh.SetVar(consts.VeyronCredentials, sh.credDir)
 	return nil
 }
 
diff --git a/lib/signals/signals_test.go b/lib/signals/signals_test.go
index b045ef9..abe2e27 100644
--- a/lib/signals/signals_test.go
+++ b/lib/signals/signals_test.go
@@ -19,6 +19,7 @@
 	"veyron.io/veyron/veyron2/services/mgmt/appcycle"
 
 	"veyron.io/veyron/veyron/lib/expect"
+	"veyron.io/veyron/veyron/lib/flags/consts"
 	"veyron.io/veyron/veyron/lib/modules"
 	"veyron.io/veyron/veyron/lib/testutil"
 	"veyron.io/veyron/veyron/lib/testutil/security"
@@ -338,7 +339,7 @@
 	defer os.RemoveAll(childcreds)
 	configServer, configServiceName, ch := createConfigServer(t)
 	defer configServer.Stop()
-	sh.SetVar("VEYRON_CREDENTIALS", childcreds)
+	sh.SetVar(consts.VeyronCredentials, childcreds)
 	sh.SetVar(mgmt.ParentNodeManagerConfigKey, configServiceName)
 	h, err := sh.Start("handleDefaults", nil)
 	if err != nil {
diff --git a/profiles/roaming/roaming.go b/profiles/roaming/roaming.go
index 816b4a1..a28feea 100644
--- a/profiles/roaming/roaming.go
+++ b/profiles/roaming/roaming.go
@@ -23,6 +23,9 @@
 	"veyron.io/veyron/veyron/lib/netstate"
 	"veyron.io/veyron/veyron/profiles"
 	"veyron.io/veyron/veyron/profiles/internal"
+	"veyron.io/veyron/veyron/services/mgmt/debug"
+	// TODO(cnicolaou,ashankar): move this into flags.
+	sflag "veyron.io/veyron/veyron/security/flag"
 )
 
 const (
@@ -69,6 +72,8 @@
 func (p *profile) Init(rt veyron2.Runtime, publisher *config.Publisher) error {
 	log := rt.Logger()
 
+	rt.ConfigureReservedName("__debug", debug.NewDispatcher(log.LogDir(), sflag.NewAuthorizerOrDie()))
+
 	lf := commonFlags.ListenFlags()
 	ListenSpec = ipc.ListenSpec{
 		Protocol: lf.ListenProtocol.Protocol,
diff --git a/profiles/static/static.go b/profiles/static/static.go
index ba90318..18b7625 100644
--- a/profiles/static/static.go
+++ b/profiles/static/static.go
@@ -15,6 +15,9 @@
 	"veyron.io/veyron/veyron/lib/netstate"
 	"veyron.io/veyron/veyron/profiles"
 	"veyron.io/veyron/veyron/profiles/internal"
+	"veyron.io/veyron/veyron/services/mgmt/debug"
+	// TODO(cnicolaou,ashankar): move this into flags.
+	sflag "veyron.io/veyron/veyron/security/flag"
 )
 
 var (
@@ -55,6 +58,8 @@
 func (p *static) Init(rt veyron2.Runtime, _ *config.Publisher) error {
 	log := rt.Logger()
 
+	rt.ConfigureReservedName("debug", debug.NewDispatcher(log.LogDir(), sflag.NewAuthorizerOrDie()))
+
 	lf := commonFlags.ListenFlags()
 	ListenSpec = ipc.ListenSpec{
 		Protocol: lf.ListenProtocol.Protocol,
diff --git a/runtimes/google/ipc/debug_test.go b/runtimes/google/ipc/debug_test.go
index 6292622..e05c185 100644
--- a/runtimes/google/ipc/debug_test.go
+++ b/runtimes/google/ipc/debug_test.go
@@ -9,12 +9,14 @@
 	"veyron.io/veyron/veyron2/naming"
 	"veyron.io/veyron/veyron2/options"
 	"veyron.io/veyron/veyron2/services/mounttable/types"
+	"veyron.io/veyron/veyron2/vlog"
 
 	"veyron.io/veyron/veyron/lib/stats"
 	"veyron.io/veyron/veyron/runtimes/google/ipc/stream/manager"
 	"veyron.io/veyron/veyron/runtimes/google/ipc/stream/sectest"
 	"veyron.io/veyron/veyron/runtimes/google/ipc/stream/vc"
 	tnaming "veyron.io/veyron/veyron/runtimes/google/testing/mocks/naming"
+	"veyron.io/veyron/veyron/services/mgmt/debug"
 )
 
 func TestDebugServer(t *testing.T) {
@@ -28,10 +30,13 @@
 	pclient.AddToRoots(bclient)                    // Client recognizes "server" as a root of blessings.
 	pclient.BlessingStore().Set(bclient, "server") // Client presents bclient to server
 
+	debugDisp := debug.NewDispatcher(vlog.Log.LogDir(), nil)
+
 	sm := manager.InternalNew(naming.FixedRoutingID(0x555555555))
 	defer sm.Shutdown()
 	ns := tnaming.NewSimpleNamespace()
-	server, err := InternalNewServer(testContext(), sm, ns, vc.LocalPrincipal{pserver})
+
+	server, err := InternalNewServer(testContext(), sm, ns, options.ReservedNameDispatcher{"__debug", debugDisp}, vc.LocalPrincipal{pserver})
 	if err != nil {
 		t.Fatalf("InternalNewServer failed: %v", err)
 	}
diff --git a/runtimes/google/ipc/default_authorizer.go b/runtimes/google/ipc/default_authorizer.go
new file mode 100644
index 0000000..bbaa7c9
--- /dev/null
+++ b/runtimes/google/ipc/default_authorizer.go
@@ -0,0 +1,34 @@
+package ipc
+
+import (
+	"fmt"
+
+	"veyron.io/veyron/veyron2/security"
+)
+
+// defaultAuthorizer implements a security.Authorizer with an authorization
+// policy that requires one end of the RPC to have a blessing that makes it a
+// delegate of the other.
+type defaultAuthorizer struct{}
+
+func (defaultAuthorizer) Authorize(ctx security.Context) error {
+	var (
+		local  = ctx.LocalBlessings().ForContext(ctx)
+		remote = ctx.RemoteBlessings().ForContext(ctx)
+	)
+	// Authorize if any element in local is a "delegate of" (i.e., has been
+	// blessed by) any element in remote, OR vice-versa.
+	for _, l := range local {
+		if security.BlessingPattern(l).MatchedBy(remote...) {
+			// l is a delegate of an element in remote.
+			return nil
+		}
+	}
+	for _, r := range remote {
+		if security.BlessingPattern(r).MatchedBy(local...) {
+			// r is a delegate of an element in local.
+			return nil
+		}
+	}
+	return fmt.Errorf("policy disallows %v", remote)
+}
diff --git a/runtimes/google/ipc/default_authorizer_test.go b/runtimes/google/ipc/default_authorizer_test.go
new file mode 100644
index 0000000..852fbab
--- /dev/null
+++ b/runtimes/google/ipc/default_authorizer_test.go
@@ -0,0 +1,96 @@
+package ipc
+
+import (
+	"testing"
+
+	vsecurity "veyron.io/veyron/veyron/security"
+	"veyron.io/veyron/veyron2/security"
+)
+
+func TestDefaultAuthorizer(t *testing.T) {
+	var (
+		pali, _ = vsecurity.NewPrincipal()
+		pbob, _ = vsecurity.NewPrincipal()
+		pche, _ = vsecurity.NewPrincipal()
+
+		che, _ = pche.BlessSelf("che")
+		ali, _ = pali.BlessSelf("ali")
+		bob, _ = pbob.BlessSelf("bob")
+
+		// bless(ali, bob, "friend") will generate a blessing for ali, calling him "bob/friend".
+		bless = func(target, extend security.Blessings, extension string) security.Blessings {
+			var p security.Principal
+			switch extend {
+			case ali:
+				p = pali
+			case bob:
+				p = pbob
+			case che:
+				p = pche
+			default:
+				panic(extend)
+			}
+			ret, err := p.Bless(target.PublicKey(), extend, extension, security.UnconstrainedUse())
+			if err != nil {
+				panic(err)
+			}
+			return ret
+		}
+
+		U = func(blessings ...security.Blessings) security.Blessings {
+			u, err := security.UnionOfBlessings(blessings...)
+			if err != nil {
+				panic(err)
+			}
+			return u
+		}
+
+		// Shorthands for getting blessings for Ali and Bob.
+		A = func(as security.Blessings, extension string) security.Blessings { return bless(ali, as, extension) }
+		B = func(as security.Blessings, extension string) security.Blessings { return bless(bob, as, extension) }
+
+		authorizer defaultAuthorizer
+	)
+	// Make ali, bob (the two ends) recognize all three blessings
+	for ip, p := range []security.Principal{pali, pbob} {
+		for _, b := range []security.Blessings{ali, bob, che} {
+			if err := p.AddToRoots(b); err != nil {
+				t.Fatalf("%d: %v - %v", ip, b, err)
+			}
+		}
+	}
+	// All tests are run as if "ali" is the local end and "bob" is the remote.
+	tests := []struct {
+		local, remote security.Blessings
+		authorized    bool
+	}{
+		{ali, ali, true},
+		{ali, bob, false},
+		{ali, B(ali, "friend"), true},               // ali talking to ali/friend
+		{A(bob, "friend"), bob, true},               // bob/friend talking to bob
+		{A(che, "friend"), B(che, "family"), false}, // che/friend talking to che/family
+		{U(ali, A(bob, "friend"), A(che, "friend")),
+			U(bob, B(che, "family")),
+			true}, // {ali, bob/friend, che/friend} talking to {bob, che/family}
+	}
+	for _, test := range tests {
+		err := authorizer.Authorize(&mockSecurityContext{
+			p: pali,
+			l: test.local,
+			r: test.remote,
+		})
+		if (err == nil) != test.authorized {
+			t.Errorf("Local:%v Remote:%v. Got %v", test.local, test.remote, err)
+		}
+	}
+}
+
+type mockSecurityContext struct {
+	security.Context
+	p    security.Principal
+	l, r security.Blessings
+}
+
+func (c *mockSecurityContext) LocalPrincipal() security.Principal  { return c.p }
+func (c *mockSecurityContext) LocalBlessings() security.Blessings  { return c.l }
+func (c *mockSecurityContext) RemoteBlessings() security.Blessings { return c.r }
diff --git a/runtimes/google/ipc/flow_test.go b/runtimes/google/ipc/flow_test.go
index b78a56f..97ca9cd 100644
--- a/runtimes/google/ipc/flow_test.go
+++ b/runtimes/google/ipc/flow_test.go
@@ -59,7 +59,7 @@
 	newInvoker func(suffix string) ipc.Invoker
 }
 
-func (td testDisp) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
+func (td testDisp) Lookup(suffix, method string) (interface{}, security.Authorizer, error) {
 	return td.newInvoker(suffix), testServerAuthorizer{}, nil
 }
 
diff --git a/runtimes/google/ipc/full_test.go b/runtimes/google/ipc/full_test.go
index 67638e1..1e0b892 100644
--- a/runtimes/google/ipc/full_test.go
+++ b/runtimes/google/ipc/full_test.go
@@ -146,7 +146,7 @@
 
 type testServerDisp struct{ server interface{} }
 
-func (t testServerDisp) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
+func (t testServerDisp) Lookup(suffix, method string) (interface{}, security.Authorizer, error) {
 	// If suffix is "nilAuth" we use default authorization, if it is "aclAuth" we
 	// use an ACL based authorizer, and otherwise we use the custom testServerAuthorizer.
 	var authorizer security.Authorizer
@@ -548,7 +548,7 @@
 }
 
 // Implements ipc.Dispatcher
-func (s *dischargeImpetusTester) Lookup(_, _ string) (ipc.Invoker, security.Authorizer, error) {
+func (s *dischargeImpetusTester) Lookup(_, _ string) (interface{}, security.Authorizer, error) {
 	return ipc.ReflectInvoker(s), testServerAuthorizer{}, nil
 }
 
diff --git a/runtimes/google/ipc/server.go b/runtimes/google/ipc/server.go
index 002a233..115615f 100644
--- a/runtimes/google/ipc/server.go
+++ b/runtimes/google/ipc/server.go
@@ -28,8 +28,6 @@
 	"veyron.io/veyron/veyron/runtimes/google/lib/publisher"
 	inaming "veyron.io/veyron/veyron/runtimes/google/naming"
 	ivtrace "veyron.io/veyron/veyron/runtimes/google/vtrace"
-	vsecurity "veyron.io/veyron/veyron/security"
-	"veyron.io/veyron/veyron/services/mgmt/debug"
 )
 
 var (
@@ -49,8 +47,7 @@
 	stoppedChan      chan struct{}                     // closed when the server has been stopped.
 	ns               naming.Namespace
 	servesMountTable bool
-	debugAuthorizer  security.Authorizer
-	debugDisp        ipc.Dispatcher
+	reservedOpt      options.ReservedNameDispatcher
 	// TODO(cnicolaou): add roaming stats to ipcStats
 	stats *ipcStats // stats for this server.
 }
@@ -83,11 +80,10 @@
 			s.listenerOpts = append(s.listenerOpts, opt)
 		case options.ServesMountTable:
 			s.servesMountTable = bool(opt)
-		case options.DebugAuthorizer:
-			s.debugAuthorizer = opt.Authorizer
+		case options.ReservedNameDispatcher:
+			s.reservedOpt = opt
 		}
 	}
-	s.debugDisp = debug.NewDispatcher(vlog.Log.LogDir(), s.debugAuthorizer)
 	return s, nil
 }
 
@@ -537,7 +533,33 @@
 	}
 }
 
-func (s *server) Serve(name string, disp ipc.Dispatcher) error {
+func (s *server) Serve(name string, obj interface{}) error {
+	if obj == nil {
+		// nil is an allowed value for obj.
+		return s.ServeDispatcher(name, ipc.Dispatcher(nil))
+	}
+	// TRANSITION: this will be disallowed when the transition is complete.
+	if disp, ok := obj.(ipc.Dispatcher); ok {
+		return s.ServeDispatcher(name, disp)
+	}
+	// TRANSITION: We may fail the dispatcher type test, but still be a
+	// dispatcher becase our Lookup method returns ipc.Invoker and not a
+	// raw object. This code here will detect that case and panic as an aid
+	// to catching these cases early.
+	typ := reflect.TypeOf(obj)
+	if lookup, found := typ.MethodByName("Lookup"); found {
+		if lookup.Type.NumIn() == 3 && lookup.Type.NumOut() == 3 {
+			inv := lookup.Type.Out(0)
+			if inv.Name() == "Invoker" {
+				panic(fmt.Sprintf("%q has a Lookup that returns an Invoker", lookup.Name))
+			}
+		}
+	}
+	// TRANSITION: this will go away in the transition.
+	panic("should never get here")
+}
+
+func (s *server) ServeDispatcher(name string, disp ipc.Dispatcher) error {
 	defer vlog.LogCall()()
 	s.Lock()
 	defer s.Unlock()
@@ -623,12 +645,12 @@
 // flow that's already connected to the client.
 type flowServer struct {
 	context.T
-	server    *server        // ipc.Server that this flow server belongs to
-	disp      ipc.Dispatcher // ipc.Dispatcher that will serve RPCs on this flow
-	dec       *vom.Decoder   // to decode requests and args from the client
-	enc       *vom.Encoder   // to encode responses and results to the client
-	flow      stream.Flow    // underlying flow
-	debugDisp ipc.Dispatcher // internal debug dispatcher
+	server      *server        // ipc.Server that this flow server belongs to
+	disp        ipc.Dispatcher // ipc.Dispatcher that will serve RPCs on this flow
+	dec         *vom.Decoder   // to decode requests and args from the client
+	enc         *vom.Encoder   // to encode responses and results to the client
+	flow        stream.Flow    // underlying flow
+	reservedOpt options.ReservedNameDispatcher
 
 	// Fields filled in during the server invocation.
 	blessings      security.Blessings
@@ -653,11 +675,11 @@
 		server: server,
 		disp:   disp,
 		// TODO(toddw): Support different codecs
-		dec:        vom.NewDecoder(flow),
-		enc:        vom.NewEncoder(flow),
-		flow:       flow,
-		debugDisp:  server.debugDisp,
-		discharges: make(map[string]security.Discharge),
+		dec:         vom.NewDecoder(flow),
+		enc:         vom.NewEncoder(flow),
+		flow:        flow,
+		reservedOpt: server.reservedOpt,
+		discharges:  make(map[string]security.Discharge),
 	}
 }
 
@@ -688,15 +710,6 @@
 	return v
 }
 
-func defaultAuthorizer(ctx security.Context) security.Authorizer {
-	blessings := ctx.LocalBlessings().ForContext(ctx)
-	acl := security.ACL{In: make(map[security.BlessingPattern]security.LabelSet)}
-	for _, b := range blessings {
-		acl.In[security.BlessingPattern(b).MakeGlob()] = security.AllLabels
-	}
-	return vsecurity.NewACLAuthorizer(acl)
-}
-
 func (fs *flowServer) serve() error {
 	defer fs.flow.Close()
 
@@ -759,6 +772,20 @@
 	return &req, nil
 }
 
+func lookupInvoker(d ipc.Dispatcher, name, method string) (ipc.Invoker, security.Authorizer, error) {
+	obj, auth, err := d.Lookup(name, method)
+	switch {
+	case err != nil:
+		return nil, nil, err
+	case obj == nil:
+		return nil, auth, nil
+	}
+	if invoker, ok := obj.(ipc.Invoker); ok {
+		return invoker, auth, nil
+	}
+	return ipc.ReflectInvoker(obj), auth, nil
+}
+
 func (fs *flowServer) processRequest() ([]interface{}, verror.E) {
 	start := time.Now()
 
@@ -864,19 +891,22 @@
 // with ipc.DebugKeyword, we use the internal debug dispatcher to look up the
 // invoker. Otherwise, and we use the server's dispatcher. The (stripped) name
 // and dispatch suffix are also returned.
+// TODO(cnicolaou): change this back returning in ipc.Invoker in the pt2 CL.
 func (fs *flowServer) lookup(name, method string) (ipc.Invoker, security.Authorizer, string, verror.E) {
 	name = strings.TrimLeft(name, "/")
 	if method == "Glob" && len(name) == 0 {
-		return ipc.ReflectInvoker(&globInvoker{fs}), &acceptAllAuthorizer{}, name, nil
+		return ipc.ReflectInvoker(&globInvoker{fs.reservedOpt.Prefix, fs}), &acceptAllAuthorizer{}, name, nil
 	}
 	disp := fs.disp
-	if name == ipc.DebugKeyword || strings.HasPrefix(name, ipc.DebugKeyword+"/") {
-		name = strings.TrimPrefix(name, ipc.DebugKeyword)
+	prefix := fs.reservedOpt.Prefix
+	if len(prefix) > 0 && (name == prefix || strings.HasPrefix(name, prefix+"/")) {
+		name = strings.TrimPrefix(name, prefix)
 		name = strings.TrimLeft(name, "/")
-		disp = fs.debugDisp
+		disp = fs.reservedOpt.Dispatcher
 	}
+
 	if disp != nil {
-		invoker, auth, err := disp.Lookup(name, method)
+		invoker, auth, err := lookupInvoker(disp, name, method)
 		switch {
 		case err != nil:
 			return nil, nil, "", verror.Convert(err)
@@ -894,7 +924,8 @@
 }
 
 type globInvoker struct {
-	fs *flowServer
+	prefix string
+	fs     *flowServer
 }
 
 // Glob matches the pattern against internal object names if the double-
@@ -905,15 +936,12 @@
 	if err != nil {
 		return err
 	}
-	if strings.HasPrefix(pattern, "__") {
+	if strings.HasPrefix(pattern, naming.ReservedNamePrefix) {
 		var err error
 		// Match against internal object names.
-		internalLeaves := []string{ipc.DebugKeyword}
-		for _, leaf := range internalLeaves {
-			if ok, _, left := g.MatchInitialSegment(leaf); ok {
-				if ierr := i.invokeGlob(call, i.fs.debugDisp, leaf, left.String()); ierr != nil {
-					err = ierr
-				}
+		if ok, _, left := g.MatchInitialSegment(i.prefix); ok {
+			if ierr := i.invokeGlob(call, i.fs.reservedOpt.Dispatcher, i.prefix, left.String()); ierr != nil {
+				err = ierr
 			}
 		}
 		return err
@@ -926,11 +954,16 @@
 	if d == nil {
 		return nil
 	}
-	invoker, auth, err := d.Lookup("", "Glob")
+	obj, auth, err := d.Lookup("", "Glob")
 	if err != nil {
 		return err
 	}
-	if invoker == nil {
+	// TODO(cnicolaou): ipc.Serve TRANSITION
+	invoker, ok := obj.(ipc.Invoker)
+	if !ok {
+		panic("Lookup should have returned an ipc.Invoker")
+	}
+	if obj == nil || !ok {
 		return verror.NoExistf("ipc: invoker not found for Glob")
 	}
 
@@ -948,6 +981,7 @@
 	if err != nil {
 		return err
 	}
+
 	if len(results) != 1 {
 		return verror.BadArgf("unexpected number of results. Got %d, want 1", len(results))
 	}
@@ -955,7 +989,7 @@
 	if res == nil {
 		return nil
 	}
-	err, ok := res.(error)
+	err, ok = res.(error)
 	if !ok {
 		return verror.BadArgf("unexpected result type. Got %T, want error", res)
 	}
@@ -984,11 +1018,11 @@
 
 func (fs *flowServer) authorize(auth security.Authorizer) verror.E {
 	if auth == nil {
-		auth = defaultAuthorizer(fs)
+		auth = defaultAuthorizer{}
 	}
 	if err := auth.Authorize(fs); err != nil {
 		// TODO(ataly, ashankar): For privacy reasons, should we hide the authorizer error?
-		return verror.NoAccessf("ipc: %v not authorized to call %q.%q (%v)", fs.RemoteBlessings(), fs.Name(), fs.Method(), err)
+		return verror.NoAccessf("ipc: not authorized to call %q.%q (%v)", fs.Name(), fs.Method(), err)
 	}
 	return nil
 }
@@ -1005,7 +1039,7 @@
 func (fs *flowServer) authorizeForDebug(auth security.Authorizer) error {
 	dc := debugContext{fs}
 	if auth == nil {
-		auth = defaultAuthorizer(dc)
+		auth = defaultAuthorizer{}
 	}
 	return auth.Authorize(dc)
 }
diff --git a/runtimes/google/naming/namespace/all_test.go b/runtimes/google/naming/namespace/all_test.go
index 9c29b25..87c80da 100644
--- a/runtimes/google/naming/namespace/all_test.go
+++ b/runtimes/google/naming/namespace/all_test.go
@@ -118,7 +118,7 @@
 
 type dispatcher struct{}
 
-func (d *dispatcher) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
+func (d *dispatcher) Lookup(suffix, method string) (interface{}, security.Authorizer, error) {
 	return ipc.ReflectInvoker(&testServer{suffix}), allowEveryoneAuthorizer{}, nil
 }
 
diff --git a/runtimes/google/rt/ipc.go b/runtimes/google/rt/ipc.go
index 293657a..4923176 100644
--- a/runtimes/google/rt/ipc.go
+++ b/runtimes/google/rt/ipc.go
@@ -93,6 +93,11 @@
 	}
 	// Add the option that provides the principal to the server.
 	otherOpts = append(otherOpts, vc.LocalPrincipal{rt.principal})
+	if rt.reservedDisp != nil {
+		ropts := options.ReservedNameDispatcher{rt.reservedPrefix, rt.reservedDisp}
+		otherOpts = append(otherOpts, ropts)
+		otherOpts = append(otherOpts, rt.reservedOpts...)
+	}
 	ctx := rt.NewContext()
 	return iipc.InternalNewServer(ctx, sm, ns, otherOpts...)
 }
diff --git a/runtimes/google/rt/mgmt_test.go b/runtimes/google/rt/mgmt_test.go
index 0737a1e..4eea73d 100644
--- a/runtimes/google/rt/mgmt_test.go
+++ b/runtimes/google/rt/mgmt_test.go
@@ -17,6 +17,7 @@
 	"veyron.io/veyron/veyron2/services/mgmt/appcycle"
 
 	"veyron.io/veyron/veyron/lib/expect"
+	"veyron.io/veyron/veyron/lib/flags/consts"
 	"veyron.io/veyron/veyron/lib/modules"
 	"veyron.io/veyron/veyron/lib/testutil"
 	"veyron.io/veyron/veyron/lib/testutil/security"
@@ -284,12 +285,12 @@
 	// refer to the global rt.R() function), but we take care to make sure
 	// that the "google" runtime we are trying to test in this package is
 	// the one being used.
-	r, _ := rt.New(profileOpt, options.GoogleRuntime)
+	r, _ := rt.New(profileOpt)
 
 	childcreds := security.NewVeyronCredentials(r.Principal(), appCmd)
 	configServer, configServiceName, ch := createConfigServer(t, r)
 	sh := modules.NewShell(appCmd)
-	sh.SetVar("VEYRON_CREDENTIALS", childcreds)
+	sh.SetVar(consts.VeyronCredentials, childcreds)
 	sh.SetVar(mgmt.ParentNodeManagerConfigKey, configServiceName)
 	h, err := sh.Start("app", nil)
 	if err != nil {
diff --git a/runtimes/google/rt/rt.go b/runtimes/google/rt/rt.go
index 24cacf3..7bb5e3b 100644
--- a/runtimes/google/rt/rt.go
+++ b/runtimes/google/rt/rt.go
@@ -5,6 +5,7 @@
 	"fmt"
 	"os"
 	"path/filepath"
+	"strings"
 	"sync"
 
 	"veyron.io/veyron/veyron2"
@@ -30,17 +31,20 @@
 type vrt struct {
 	mu sync.Mutex
 
-	profile    veyron2.Profile
-	publisher  *config.Publisher
-	sm         []stream.Manager // GUARDED_BY(mu)
-	ns         naming.Namespace
-	signals    chan os.Signal
-	principal  security.Principal
-	client     ipc.Client
-	mgmt       *mgmtImpl
-	flags      flags.RuntimeFlags
-	nServers   int  // GUARDED_BY(mu)
-	cleaningUp bool // GUARDED_BY(mu)
+	profile        veyron2.Profile
+	publisher      *config.Publisher
+	sm             []stream.Manager // GUARDED_BY(mu)
+	ns             naming.Namespace
+	signals        chan os.Signal
+	principal      security.Principal
+	client         ipc.Client
+	mgmt           *mgmtImpl
+	flags          flags.RuntimeFlags
+	reservedDisp   ipc.Dispatcher
+	reservedPrefix string
+	reservedOpts   []ipc.ServerOpt
+	nServers       int  // GUARDED_BY(mu)
+	cleaningUp     bool // GUARDED_BY(mu)
 
 	lang    i18n.LangID // Language, from environment variables.
 	program string      // Program name, from os.Args[0].
@@ -70,10 +74,6 @@
 			rt.principal = v.Principal
 		case options.Profile:
 			rt.profile = v.Profile
-		case options.RuntimeName:
-			if v != "google" && v != "" {
-				return nil, fmt.Errorf("%q is the wrong name for this runtime", v)
-			}
 		default:
 			return nil, fmt.Errorf("option has wrong type %T", o)
 		}
@@ -122,6 +122,11 @@
 		return nil, fmt.Errorf("failed to get child handle: %s", err)
 	}
 
+	rt.publisher = config.NewPublisher()
+	if err := rt.profile.Init(rt, rt.publisher); err != nil {
+		return nil, err
+	}
+
 	// TODO(caprita, cnicolaou): how is this to be configured?
 	// Can it ever be anything other than a localhost/loopback address?
 	listenSpec := ipc.ListenSpec{Protocol: "tcp", Address: "127.0.0.1:0"}
@@ -129,11 +134,6 @@
 		return nil, err
 	}
 
-	rt.publisher = config.NewPublisher()
-	if err := rt.profile.Init(rt, rt.publisher); err != nil {
-		return nil, err
-	}
-
 	vlog.VI(2).Infof("rt.Init done")
 	return rt, nil
 }
@@ -142,8 +142,18 @@
 	return rt.publisher
 }
 
-func (r *vrt) Profile() veyron2.Profile {
-	return r.profile
+func (rt *vrt) Profile() veyron2.Profile {
+	return rt.profile
+}
+
+func (rt *vrt) ConfigureReservedName(prefix string, server ipc.Dispatcher, opts ...ipc.ServerOpt) {
+	rt.mu.Lock()
+	defer rt.mu.Unlock()
+	rt.reservedDisp = server
+	prefix = strings.TrimLeft(prefix, "_")
+	rt.reservedPrefix = naming.ReservedNamePrefix + prefix
+	rt.reservedOpts = make([]ipc.ServerOpt, 0, len(opts))
+	copy(rt.reservedOpts, opts)
 }
 
 func (rt *vrt) Cleanup() {
diff --git a/runtimes/google/rt/rt_test.go b/runtimes/google/rt/rt_test.go
index 07bf6fd..e76dcd5 100644
--- a/runtimes/google/rt/rt_test.go
+++ b/runtimes/google/rt/rt_test.go
@@ -17,6 +17,7 @@
 	"veyron.io/veyron/veyron2/vlog"
 
 	"veyron.io/veyron/veyron/lib/expect"
+	"veyron.io/veyron/veyron/lib/flags/consts"
 	"veyron.io/veyron/veyron/lib/modules"
 	"veyron.io/veyron/veyron/lib/testutil"
 	vsecurity "veyron.io/veyron/veyron/security"
@@ -26,10 +27,6 @@
 	local security.Principal
 }
 
-// Environment variable pointing to a directory where information about a
-// principal (private key, blessing store, blessing roots etc.) is stored.
-const veyronCredentialsEnvVar = "VEYRON_CREDENTIALS"
-
 func (*context) Method() string                            { return "" }
 func (*context) Name() string                              { return "" }
 func (*context) Suffix() string                            { return "" }
@@ -223,7 +220,7 @@
 	principal := createCredentialsInDir(t, cdir)
 
 	// directory supplied by the environment.
-	credEnv := []string{veyronCredentialsEnvVar + "=" + cdir}
+	credEnv := []string{consts.VeyronCredentials + "=" + cdir}
 
 	h, err := sh.Start("runner", credEnv)
 	if err != nil {
@@ -268,12 +265,12 @@
 
 	// A credentials directory may, or may, not have been already specified.
 	// Either way, we want to use our own, so we set it aside and use our own.
-	origCredentialsDir := os.Getenv(veyronCredentialsEnvVar)
-	defer os.Setenv(veyronCredentialsEnvVar, origCredentialsDir)
+	origCredentialsDir := os.Getenv(consts.VeyronCredentials)
+	defer os.Setenv(consts.VeyronCredentials, origCredentialsDir)
 
 	// Test that with VEYRON_CREDENTIALS unset the runtime's Principal
 	// is correctly initialized.
-	if err := os.Setenv(veyronCredentialsEnvVar, ""); err != nil {
+	if err := os.Setenv(consts.VeyronCredentials, ""); err != nil {
 		t.Fatal(err)
 	}
 
@@ -293,7 +290,7 @@
 	defer os.RemoveAll(cdir1)
 	principal := createCredentialsInDir(t, cdir1)
 	// directory supplied by the environment.
-	credEnv := []string{veyronCredentialsEnvVar + "=" + cdir1}
+	credEnv := []string{consts.VeyronCredentials + "=" + cdir1}
 
 	pubkey, err = collect(sh, "principal", credEnv)
 	if err != nil {
diff --git a/runtimes/google/rt/signal_test.go b/runtimes/google/rt/signal_test.go
index e37f883..e698e77 100644
--- a/runtimes/google/rt/signal_test.go
+++ b/runtimes/google/rt/signal_test.go
@@ -9,6 +9,8 @@
 	"testing"
 	"time"
 
+	"veyron.io/veyron/veyron2"
+	"veyron.io/veyron/veyron2/config"
 	"veyron.io/veyron/veyron2/options"
 	"veyron.io/veyron/veyron2/rt"
 
@@ -21,6 +23,29 @@
 	modules.RegisterChild("withoutRuntime", "", withoutRuntime)
 }
 
+// A fack profile to explicitly request the Google runtime.
+type myprofile struct{}
+
+func (mp *myprofile) Name() string {
+	return "test"
+}
+
+func (mp *myprofile) Runtime() string {
+	return "google"
+}
+
+func (mp *myprofile) Platform() *veyron2.Platform {
+	return &veyron2.Platform{"google", nil, "v1", "any", "rel1", ".2", "who knows", "this host"}
+}
+
+func (mp *myprofile) String() string {
+	return "myprofile on " + mp.Platform().String()
+}
+
+func (mp *myprofile) Init(veyron2.Runtime, *config.Publisher) error {
+	return nil
+}
+
 func simpleEchoProgram(stdin io.Reader, stdout io.Writer) {
 	fmt.Fprintf(stdout, "ready\n")
 	scanner := bufio.NewScanner(stdin)
@@ -34,7 +59,7 @@
 	// Make sure that we use "google" runtime implementation in this
 	// package even though we have to use the public API which supports
 	// arbitrary runtime implementations.
-	rt.Init(options.GoogleRuntime)
+	rt.Init(options.Profile{&myprofile{}})
 	simpleEchoProgram(stdin, stdout)
 	return nil
 }
diff --git a/runtimes/google/testing/mocks/runtime/panic_runtime.go b/runtimes/google/testing/mocks/runtime/panic_runtime.go
index 215fb5c..cccc4d7 100644
--- a/runtimes/google/testing/mocks/runtime/panic_runtime.go
+++ b/runtimes/google/testing/mocks/runtime/panic_runtime.go
@@ -45,4 +45,7 @@
 func (*PanicRuntime) AdvanceGoal(delta int)         { panic(badRuntime) }
 func (*PanicRuntime) AdvanceProgress(delta int)     { panic(badRuntime) }
 func (*PanicRuntime) TrackTask(chan<- veyron2.Task) { panic(badRuntime) }
-func (*PanicRuntime) Cleanup()                      { panic(badRuntime) }
+func (*PanicRuntime) ConfigureReservedName(string, ipc.Dispatcher, ...ipc.ServerOpt) {
+	panic(badRuntime)
+}
+func (*PanicRuntime) Cleanup() { panic(badRuntime) }
diff --git a/security/agent/agentd/main.go b/security/agent/agentd/main.go
index 28e448d..7efffbe 100644
--- a/security/agent/agentd/main.go
+++ b/security/agent/agentd/main.go
@@ -8,6 +8,7 @@
 	"os/exec"
 	"os/signal"
 	"syscall"
+	"veyron.io/veyron/veyron/lib/flags/consts"
 	_ "veyron.io/veyron/veyron/profiles"
 	vsecurity "veyron.io/veyron/veyron/security"
 	"veyron.io/veyron/veyron/security/agent"
@@ -24,16 +25,18 @@
 	flag.Usage = func() {
 		fmt.Fprintf(os.Stderr, `Usage: %s [agent options] command command_args...
 
-Loads the private key specified in under privatekey.pem in VEYRON_CREDENTIALS into memory, then
+Loads the private key specified in under privatekey.pem in %v into memory, then
 starts the specified command with access to the private key via the
 agent protocol instead of directly reading from disk.
 
-`, os.Args[0])
+`, os.Args[0], consts.VeyronCredentials)
 		flag.PrintDefaults()
 	}
-	dir := os.Getenv("VEYRON_CREDENTIALS")
+	// TODO(ashankar,cnicolaou): Should flags.Parse be used instead? But that adds unnecessary
+	// flags like "--veyron.namespace.root", which has no meaning for this binary.
+	dir := os.Getenv(consts.VeyronCredentials)
 	if len(dir) == 0 {
-		vlog.Fatal("VEYRON_CREDENTIALS must be set to directory")
+		vlog.Fatalf("The %v environment variable must be set to a directory", consts.VeyronCredentials)
 	}
 
 	p, passphrase, err := newPrincipalFromDir(dir)
@@ -52,7 +55,7 @@
 	if err = os.Setenv(agent.FdVarName, "3"); err != nil {
 		log.Fatalf("setenv: %v", err)
 	}
-	if err = os.Setenv("VEYRON_CREDENTIALS", ""); err != nil {
+	if err = os.Setenv(consts.VeyronCredentials, ""); err != nil {
 		log.Fatalf("setenv: %v", err)
 	}
 
diff --git a/services/identity/identityd/main.go b/services/identity/identityd/main.go
index 2ba0fc2..8a9b860 100644
--- a/services/identity/identityd/main.go
+++ b/services/identity/identityd/main.go
@@ -159,7 +159,7 @@
 
 type dispatcher map[string]ipc.Invoker
 
-func (d dispatcher) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
+func (d dispatcher) Lookup(suffix, method string) (interface{}, security.Authorizer, error) {
 	if invoker := d[suffix]; invoker != nil {
 		return invoker, allowEveryoneAuthorizer{}, nil
 	}
diff --git a/services/mgmt/application/impl/dispatcher.go b/services/mgmt/application/impl/dispatcher.go
index f2b8793..48b6c4f 100644
--- a/services/mgmt/application/impl/dispatcher.go
+++ b/services/mgmt/application/impl/dispatcher.go
@@ -29,7 +29,7 @@
 
 // DISPATCHER INTERFACE IMPLEMENTATION
 
-func (d *dispatcher) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
+func (d *dispatcher) Lookup(suffix, method string) (interface{}, security.Authorizer, error) {
 	invoker := ipc.ReflectInvoker(repository.NewServerApplication(NewInvoker(d.store, d.storeRoot, suffix)))
 	return invoker, d.auth, nil
 }
diff --git a/services/mgmt/binary/impl/dispatcher.go b/services/mgmt/binary/impl/dispatcher.go
index dc6ddcb..7f54fb7 100644
--- a/services/mgmt/binary/impl/dispatcher.go
+++ b/services/mgmt/binary/impl/dispatcher.go
@@ -51,7 +51,7 @@
 
 // DISPATCHER INTERFACE IMPLEMENTATION
 
-func (d *dispatcher) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
+func (d *dispatcher) Lookup(suffix, method string) (interface{}, security.Authorizer, error) {
 	invoker := ipc.ReflectInvoker(repository.NewServerBinary(newInvoker(d.state, suffix)))
 	return invoker, d.auth, nil
 }
diff --git a/services/mgmt/debug/dispatcher.go b/services/mgmt/debug/dispatcher.go
index df7c301..9f03323 100644
--- a/services/mgmt/debug/dispatcher.go
+++ b/services/mgmt/debug/dispatcher.go
@@ -25,7 +25,7 @@
 	return &dispatcher{logsDir, authorizer}
 }
 
-func (d *dispatcher) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
+func (d *dispatcher) Lookup(suffix, method string) (interface{}, security.Authorizer, error) {
 	if method == "Signature" {
 		return NewSignatureInvoker(suffix), d.auth, nil
 	}
diff --git a/services/mgmt/lib/toplevelglob/invoker.go b/services/mgmt/lib/toplevelglob/invoker.go
index fd605a4..a73486e 100644
--- a/services/mgmt/lib/toplevelglob/invoker.go
+++ b/services/mgmt/lib/toplevelglob/invoker.go
@@ -42,10 +42,18 @@
 }
 
 func (i *invoker) leafGlob(call ipc.ServerCall, leaf string, pattern string) error {
-	invoker, _, err := i.d.Lookup(leaf, "Glob")
+	obj, _, err := i.d.Lookup(leaf, "Glob")
 	if err != nil {
 		return err
 	}
+	// Lookup must return an invoker if it implements its own glob
+	invoker, ok := obj.(ipc.Invoker)
+	if !ok {
+		return nil
+	}
+	if invoker == nil {
+		return verror.BadArgf("failed to find invoker for %q", leaf)
+	}
 	argptrs := []interface{}{&pattern}
 	leafCall := &localServerCall{call, leaf}
 	results, err := invoker.Invoke("Glob", leafCall, argptrs)
@@ -59,7 +67,7 @@
 	if res == nil {
 		return nil
 	}
-	err, ok := res.(error)
+	err, ok = res.(error)
 	if !ok {
 		return verror.BadArgf("unexpected result type. Got %T, want error", res)
 	}
diff --git a/services/mgmt/logreader/impl/logdir_invoker_test.go b/services/mgmt/logreader/impl/logdir_invoker_test.go
index 8bd99a3..0cba1db 100644
--- a/services/mgmt/logreader/impl/logdir_invoker_test.go
+++ b/services/mgmt/logreader/impl/logdir_invoker_test.go
@@ -10,7 +10,6 @@
 
 	"veyron.io/veyron/veyron/services/mgmt/logreader/impl"
 
-	"veyron.io/veyron/veyron2/ipc"
 	"veyron.io/veyron/veyron2/naming"
 	"veyron.io/veyron/veyron2/rt"
 	"veyron.io/veyron/veyron2/security"
@@ -22,7 +21,7 @@
 	root string
 }
 
-func (d *logDirectoryDispatcher) Lookup(suffix, _ string) (ipc.Invoker, security.Authorizer, error) {
+func (d *logDirectoryDispatcher) Lookup(suffix, _ string) (interface{}, security.Authorizer, error) {
 	return impl.NewLogDirectoryInvoker(d.root, suffix), nil, nil
 }
 
diff --git a/services/mgmt/logreader/impl/logfile_invoker_test.go b/services/mgmt/logreader/impl/logfile_invoker_test.go
index 06487e2..0cc7615 100644
--- a/services/mgmt/logreader/impl/logfile_invoker_test.go
+++ b/services/mgmt/logreader/impl/logfile_invoker_test.go
@@ -8,7 +8,6 @@
 
 	"veyron.io/veyron/veyron/services/mgmt/logreader/impl"
 
-	"veyron.io/veyron/veyron2/ipc"
 	"veyron.io/veyron/veyron2/naming"
 	"veyron.io/veyron/veyron2/rt"
 	"veyron.io/veyron/veyron2/security"
@@ -21,7 +20,7 @@
 	root string
 }
 
-func (d *logFileDispatcher) Lookup(suffix, _ string) (ipc.Invoker, security.Authorizer, error) {
+func (d *logFileDispatcher) Lookup(suffix, _ string) (interface{}, security.Authorizer, error) {
 	return impl.NewLogFileInvoker(d.root, suffix), nil, nil
 }
 
diff --git a/services/mgmt/node/config/config.go b/services/mgmt/node/config/config.go
index e7afa99..68f68e1 100644
--- a/services/mgmt/node/config/config.go
+++ b/services/mgmt/node/config/config.go
@@ -23,6 +23,7 @@
 	"path/filepath"
 	"strings"
 
+	"veyron.io/veyron/veyron/lib/flags/consts"
 	"veyron.io/veyron/veyron2/services/mgmt/application"
 )
 
@@ -122,7 +123,7 @@
 			continue
 		}
 		k, v := p[0], p[1]
-		if strings.HasPrefix(k, "NAMESPACE_ROOT") {
+		if strings.HasPrefix(k, consts.NamespaceRootPrefix) {
 			settings[k] = v
 		}
 	}
diff --git a/services/mgmt/node/impl/dispatcher.go b/services/mgmt/node/impl/dispatcher.go
index 684ce97..4d1865e 100644
--- a/services/mgmt/node/impl/dispatcher.go
+++ b/services/mgmt/node/impl/dispatcher.go
@@ -221,7 +221,7 @@
 
 // DISPATCHER INTERFACE IMPLEMENTATION
 
-func (d *dispatcher) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
+func (d *dispatcher) Lookup(suffix, method string) (interface{}, security.Authorizer, error) {
 	components := strings.Split(suffix, "/")
 	for i := 0; i < len(components); i++ {
 		if len(components[i]) == 0 {
diff --git a/services/mgmt/node/impl/proxy_invoker_test.go b/services/mgmt/node/impl/proxy_invoker_test.go
index 7f84099..b27c671 100644
--- a/services/mgmt/node/impl/proxy_invoker_test.go
+++ b/services/mgmt/node/impl/proxy_invoker_test.go
@@ -11,8 +11,6 @@
 	"veyron.io/veyron/veyron2/security"
 	"veyron.io/veyron/veyron2/services/mgmt/stats"
 	"veyron.io/veyron/veyron2/services/mounttable"
-
-	"veyron.io/veyron/veyron/profiles"
 )
 
 func TestProxyInvoker(t *testing.T) {
@@ -24,7 +22,8 @@
 		t.Fatalf("NewServer: %v", err)
 	}
 	defer server1.Stop()
-	ep1, err := server1.Listen(profiles.LocalListenSpec)
+	localSpec := ipc.ListenSpec{Protocol: "tcp", Address: "127.0.0.1:0"}
+	ep1, err := server1.Listen(localSpec)
 	if err != nil {
 		t.Fatalf("Listen: %v", err)
 	}
@@ -38,7 +37,7 @@
 		t.Fatalf("NewServer: %v", err)
 	}
 	defer server2.Stop()
-	ep2, err := server2.Listen(profiles.LocalListenSpec)
+	ep2, err := server2.Listen(localSpec)
 	if err != nil {
 		t.Fatalf("Listen: %v", err)
 	}
@@ -79,7 +78,7 @@
 	}
 	stream, err := c.Glob(rt.R().NewContext(), pattern)
 	if err != nil {
-		t.Errorf("Glob failed: %v", err)
+		t.Fatalf("Glob failed: %v", err)
 	}
 	results := []string{}
 	iterator := stream.RecvStream()
@@ -102,6 +101,6 @@
 	sigStub signatureStub
 }
 
-func (d *proxyDispatcher) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
+func (d *proxyDispatcher) Lookup(suffix, method string) (interface{}, security.Authorizer, error) {
 	return &proxyInvoker{naming.Join(d.remote, suffix), d.label, d.sigStub}, nil, nil
 }
diff --git a/services/mgmt/node/impl/util_test.go b/services/mgmt/node/impl/util_test.go
index c039bbd..91caa91 100644
--- a/services/mgmt/node/impl/util_test.go
+++ b/services/mgmt/node/impl/util_test.go
@@ -20,6 +20,7 @@
 	"veyron.io/veyron/veyron2/vlog"
 
 	"veyron.io/veyron/veyron/lib/expect"
+	"veyron.io/veyron/veyron/lib/flags/consts"
 	"veyron.io/veyron/veyron/lib/modules"
 	"veyron.io/veyron/veyron/lib/modules/core"
 	"veyron.io/veyron/veyron/lib/testutil/security"
@@ -53,13 +54,13 @@
 
 func credentialsForChild(blessing string) (string, []string) {
 	creds := security.NewVeyronCredentials(rt.R().Principal(), blessing)
-	return creds, []string{"VEYRON_CREDENTIALS=" + creds}
+	return creds, []string{consts.VeyronCredentials + "=" + creds}
 }
 
 func createShellAndMountTable(t *testing.T) (*modules.Shell, func()) {
 	sh := core.NewShell()
 	// The shell, will, by default share credentials with its children.
-	sh.ClearVar("VEYRON_CREDENTIALS")
+	sh.ClearVar(consts.VeyronCredentials)
 
 	mtName, mtHandle, _ := startRootMT(t, sh)
 	// Make sure the root mount table is the last process to be shutdown
@@ -78,7 +79,7 @@
 	if _, err := sh.Start(core.SetNamespaceRootsCommand, nil, mtName); err != nil {
 		t.Fatalf("%s: unexpected error: %s", loc(1), err)
 	}
-	sh.SetVar("NAMESPACE_ROOT", mtName)
+	sh.SetVar(consts.NamespaceRootPrefix, mtName)
 	return sh, fn
 }
 
diff --git a/services/mgmt/pprof/client/proxy_test.go b/services/mgmt/pprof/client/proxy_test.go
index 9c5f251..a563d9f 100644
--- a/services/mgmt/pprof/client/proxy_test.go
+++ b/services/mgmt/pprof/client/proxy_test.go
@@ -20,7 +20,7 @@
 	invoker ipc.Invoker
 }
 
-func (d *dispatcher) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
+func (d *dispatcher) Lookup(suffix, method string) (interface{}, security.Authorizer, error) {
 	return d.invoker, nil, nil
 }
 
diff --git a/services/mgmt/profile/impl/dispatcher.go b/services/mgmt/profile/impl/dispatcher.go
index 819688b..075fcdc 100644
--- a/services/mgmt/profile/impl/dispatcher.go
+++ b/services/mgmt/profile/impl/dispatcher.go
@@ -29,7 +29,7 @@
 
 // DISPATCHER INTERFACE IMPLEMENTATION
 
-func (d *dispatcher) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
+func (d *dispatcher) Lookup(suffix, method string) (interface{}, security.Authorizer, error) {
 	invoker := ipc.ReflectInvoker(repository.NewServerProfile(NewInvoker(d.store, d.storeRoot, suffix)))
 	return invoker, d.auth, nil
 }
diff --git a/services/mgmt/root/impl/dispatcher.go b/services/mgmt/root/impl/dispatcher.go
index a0058be..6cf5ee6 100644
--- a/services/mgmt/root/impl/dispatcher.go
+++ b/services/mgmt/root/impl/dispatcher.go
@@ -20,6 +20,6 @@
 
 // DISPATCHER INTERFACE IMPLEMENTATION
 
-func (d *dispatcher) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
+func (d *dispatcher) Lookup(suffix, method string) (interface{}, security.Authorizer, error) {
 	return ipc.ReflectInvoker(root.NewServerRoot(d.state)), nil, nil
 }
diff --git a/services/mgmt/stats/impl/stats_invoker_test.go b/services/mgmt/stats/impl/stats_invoker_test.go
index 2b5b4ae..d15c915 100644
--- a/services/mgmt/stats/impl/stats_invoker_test.go
+++ b/services/mgmt/stats/impl/stats_invoker_test.go
@@ -6,7 +6,6 @@
 	"testing"
 	"time"
 
-	"veyron.io/veyron/veyron2/ipc"
 	"veyron.io/veyron/veyron2/naming"
 	"veyron.io/veyron/veyron2/rt"
 	"veyron.io/veyron/veyron2/security"
@@ -23,7 +22,7 @@
 type statsDispatcher struct {
 }
 
-func (d *statsDispatcher) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
+func (d *statsDispatcher) Lookup(suffix, method string) (interface{}, security.Authorizer, error) {
 	return impl.NewStatsInvoker(suffix, 100*time.Millisecond), nil, nil
 }
 
diff --git a/services/mounttable/lib/collectionserver_test.go b/services/mounttable/lib/collectionserver_test.go
index 55fa7e6..90a0208 100644
--- a/services/mounttable/lib/collectionserver_test.go
+++ b/services/mounttable/lib/collectionserver_test.go
@@ -29,7 +29,7 @@
 }
 
 // Lookup implements ipc.Dispatcher.Lookup.
-func (d *collectionDispatcher) Lookup(name, method string) (ipc.Invoker, security.Authorizer, error) {
+func (d *collectionDispatcher) Lookup(name, method string) (interface{}, security.Authorizer, error) {
 	rpcc := &rpcContext{name: name, collectionServer: d.collectionServer}
 	return ipc.ReflectInvoker(rpcc), d, nil
 }
diff --git a/services/mounttable/lib/mounttable.go b/services/mounttable/lib/mounttable.go
index a854b70..a0955a5 100644
--- a/services/mounttable/lib/mounttable.go
+++ b/services/mounttable/lib/mounttable.go
@@ -95,7 +95,7 @@
 }
 
 // Lookup implements ipc.Dispatcher.Lookup.
-func (mt *mountTable) Lookup(name, method string) (ipc.Invoker, security.Authorizer, error) {
+func (mt *mountTable) Lookup(name, method string) (interface{}, security.Authorizer, error) {
 	vlog.VI(2).Infof("*********************Lookup %s", name)
 	mt.RLock()
 	defer mt.RUnlock()
diff --git a/services/mounttable/lib/neighborhood.go b/services/mounttable/lib/neighborhood.go
index 5300429..4f7fffa 100644
--- a/services/mounttable/lib/neighborhood.go
+++ b/services/mounttable/lib/neighborhood.go
@@ -123,7 +123,7 @@
 }
 
 // Lookup implements ipc.Dispatcher.Lookup.
-func (nh *neighborhood) Lookup(name, method string) (ipc.Invoker, security.Authorizer, error) {
+func (nh *neighborhood) Lookup(name, method string) (interface{}, security.Authorizer, error) {
 	vlog.VI(1).Infof("*********************LookupServer '%s'\n", name)
 	elems := strings.Split(name, "/")[nh.nelems:]
 	if name == "" {
diff --git a/tools/application/impl_test.go b/tools/application/impl_test.go
index b6d5d64..c55a5e9 100644
--- a/tools/application/impl_test.go
+++ b/tools/application/impl_test.go
@@ -68,7 +68,7 @@
 	return &dispatcher{}
 }
 
-func (d *dispatcher) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
+func (d *dispatcher) Lookup(suffix, method string) (interface{}, security.Authorizer, error) {
 	invoker := ipc.ReflectInvoker(repository.NewServerApplication(&server{suffix: suffix}))
 	return invoker, nil, nil
 }
diff --git a/tools/associate/impl_test.go b/tools/associate/impl_test.go
index 7043fcf..fff2ee5 100644
--- a/tools/associate/impl_test.go
+++ b/tools/associate/impl_test.go
@@ -62,18 +62,18 @@
 func (*mockNodeInvoker) IsRunnable(_ ipc.ServerContext, description binary.Description) (bool, error) {
 	return false, nil
 }
-func (*mockNodeInvoker) Reset(call ipc.ServerContext, deadline uint64) error               { return nil }
-func (*mockNodeInvoker) Install(ipc.ServerContext, string) (string, error)                 { return "", nil }
-func (*mockNodeInvoker) Refresh(ipc.ServerContext) error                                   { return nil }
-func (*mockNodeInvoker) Restart(ipc.ServerContext) error                                   { return nil }
-func (*mockNodeInvoker) Resume(ipc.ServerContext) error                                    { return nil }
-func (i *mockNodeInvoker) Revert(call ipc.ServerContext) error                             { return nil }
-func (*mockNodeInvoker) Start(ipc.ServerContext) ([]string, error)                         { return []string{}, nil }
-func (*mockNodeInvoker) Stop(ipc.ServerContext, uint32) error                              { return nil }
-func (*mockNodeInvoker) Suspend(ipc.ServerContext) error                                   { return nil }
-func (*mockNodeInvoker) Uninstall(ipc.ServerContext) error                                 { return nil }
-func (i *mockNodeInvoker) Update(ipc.ServerContext) error                                  { return nil }
-func (*mockNodeInvoker) UpdateTo(ipc.ServerContext, string) error                          { return nil }
+func (*mockNodeInvoker) Reset(call ipc.ServerContext, deadline uint64) error    { return nil }
+func (*mockNodeInvoker) Install(ipc.ServerContext, string) (string, error)      { return "", nil }
+func (*mockNodeInvoker) Refresh(ipc.ServerContext) error                        { return nil }
+func (*mockNodeInvoker) Restart(ipc.ServerContext) error                        { return nil }
+func (*mockNodeInvoker) Resume(ipc.ServerContext) error                         { return nil }
+func (i *mockNodeInvoker) Revert(call ipc.ServerContext) error                  { return nil }
+func (*mockNodeInvoker) Start(ipc.ServerContext) ([]string, error)              { return []string{}, nil }
+func (*mockNodeInvoker) Stop(ipc.ServerContext, uint32) error                   { return nil }
+func (*mockNodeInvoker) Suspend(ipc.ServerContext) error                        { return nil }
+func (*mockNodeInvoker) Uninstall(ipc.ServerContext) error                      { return nil }
+func (i *mockNodeInvoker) Update(ipc.ServerContext) error                       { return nil }
+func (*mockNodeInvoker) UpdateTo(ipc.ServerContext, string) error               { return nil }
 func (i *mockNodeInvoker) SetACL(ipc.ServerContext, security.ACL, string) error { return nil }
 func (i *mockNodeInvoker) GetACL(ipc.ServerContext) (security.ACL, string, error) {
 	return security.ACL{}, "", nil
@@ -91,7 +91,7 @@
 	return &dispatcher{tape: tape, t: t}
 }
 
-func (d *dispatcher) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
+func (d *dispatcher) Lookup(suffix, method string) (interface{}, security.Authorizer, error) {
 	invoker := ipc.ReflectInvoker(node.NewServerNode(&mockNodeInvoker{tape: d.tape, t: d.t}))
 	return invoker, nil, nil
 }
diff --git a/tools/binary/impl_test.go b/tools/binary/impl_test.go
index 3de1f9a..a924a93 100644
--- a/tools/binary/impl_test.go
+++ b/tools/binary/impl_test.go
@@ -77,7 +77,7 @@
 	return &dispatcher{}
 }
 
-func (d *dispatcher) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
+func (d *dispatcher) Lookup(suffix, method string) (interface{}, security.Authorizer, error) {
 	invoker := ipc.ReflectInvoker(repository.NewServerBinary(&server{suffix: suffix}))
 	return invoker, nil, nil
 }
diff --git a/tools/mounttable/impl_test.go b/tools/mounttable/impl_test.go
index 4e23910..9dfe601 100644
--- a/tools/mounttable/impl_test.go
+++ b/tools/mounttable/impl_test.go
@@ -56,7 +56,7 @@
 type dispatcher struct {
 }
 
-func (d *dispatcher) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
+func (d *dispatcher) Lookup(suffix, method string) (interface{}, security.Authorizer, error) {
 	invoker := ipc.ReflectInvoker(mounttable.NewServerMountTable(&server{suffix: suffix}))
 	return invoker, nil, nil
 }
diff --git a/tools/naming/simulator/driver.go b/tools/naming/simulator/driver.go
index 4f944ca..e27e4bb 100644
--- a/tools/naming/simulator/driver.go
+++ b/tools/naming/simulator/driver.go
@@ -19,6 +19,7 @@
 	"veyron.io/veyron/veyron2/rt"
 
 	"veyron.io/veyron/veyron/lib/expect"
+	"veyron.io/veyron/veyron/lib/flags/consts"
 	"veyron.io/veyron/veyron/lib/modules"
 	"veyron.io/veyron/veyron/lib/modules/core"
 	_ "veyron.io/veyron/veyron/profiles"
@@ -111,7 +112,7 @@
 
 	shell := modules.NewShell()
 	defer shell.Cleanup(os.Stderr, os.Stderr)
-	if os.Getenv("VEYRON_CREDENTIALS") == "" {
+	if os.Getenv(consts.VeyronCredentials) == "" {
 		shell.CreateAndUseNewCredentials()
 	}
 
diff --git a/tools/profile/impl_test.go b/tools/profile/impl_test.go
index 99f2562..0bfd27e 100644
--- a/tools/profile/impl_test.go
+++ b/tools/profile/impl_test.go
@@ -79,7 +79,7 @@
 	return &dispatcher{}
 }
 
-func (d *dispatcher) Lookup(suffix, method string) (ipc.Invoker, security.Authorizer, error) {
+func (d *dispatcher) Lookup(suffix, method string) (interface{}, security.Authorizer, error) {
 	invoker := ipc.ReflectInvoker(repository.NewServerProfile(&server{suffix: suffix}))
 	return invoker, nil, nil
 }
diff --git a/tools/servicerunner/main.go b/tools/servicerunner/main.go
index 6b3f501..c32a454 100644
--- a/tools/servicerunner/main.go
+++ b/tools/servicerunner/main.go
@@ -12,6 +12,7 @@
 	"veyron.io/veyron/veyron2/rt"
 
 	"veyron.io/veyron/veyron/lib/expect"
+	"veyron.io/veyron/veyron/lib/flags/consts"
 	"veyron.io/veyron/veyron/lib/modules"
 	"veyron.io/veyron/veyron/lib/modules/core"
 	_ "veyron.io/veyron/veyron/profiles"
@@ -67,7 +68,7 @@
 	defer sh.Cleanup(os.Stderr, os.Stderr)
 	// TODO(sadovsky): Shell only does this for tests. It would be better if it
 	// either always did it or never did it.
-	if os.Getenv("VEYRON_CREDENTIALS") == "" {
+	if os.Getenv(consts.VeyronCredentials) == "" {
 		panicOnError(sh.CreateAndUseNewCredentials())
 	}
 	// TODO(sadovsky): The following line will not be needed if the modules
@@ -80,10 +81,11 @@
 	panicOnError(err)
 	updateVars(h, vars, "MT_NAME")
 
-	// Set NAMESPACE_ROOT env var, consumed downstream by proxyd among others.
-	// NOTE(sadovsky): If this is not set, proxyd takes several seconds to start;
-	// if it is set, proxyd starts instantly. Fun!
-	sh.SetVar("NAMESPACE_ROOT", vars["MT_NAME"])
+	// Set consts.NamespaceRootPrefix env var, consumed downstream by proxyd
+	// among others.
+	// NOTE(sadovsky): If this is not set, proxyd takes several seconds to
+	// start; if it is set, proxyd starts instantly. Fun!
+	sh.SetVar(consts.NamespaceRootPrefix, vars["MT_NAME"])
 
 	// NOTE(sadovsky): The proxyd binary requires --protocol and --address flags
 	// while the proxyd command instead uses ListenSpec flags.