Merge "veyron/tools/associate: command line account association"
diff --git a/lib/exec/parent.go b/lib/exec/parent.go
index a3aebec..b0d995d 100644
--- a/lib/exec/parent.go
+++ b/lib/exec/parent.go
@@ -66,7 +66,6 @@
 // NewParentHandle creates a ParentHandle for the child process represented by
 // an instance of exec.Cmd.
 func NewParentHandle(c *exec.Cmd, opts ...ParentHandleOpt) *ParentHandle {
-
 	cfg, secret := NewConfig(), ""
 	tk := timekeeper.RealTime()
 	for _, opt := range opts {
@@ -92,7 +91,18 @@
 // Start starts the child process, sharing a secret with it and
 // setting up a communication channel over which to read its status.
 func (p *ParentHandle) Start() error {
-	p.c.Env = append(p.c.Env, VersionVariable+"="+version1)
+	// Make sure that there are no instances of the VersionVariable
+	// already in the environment (which can happen when a subprocess
+	// creates a subprocess etc)
+	nenv := make([]string, 0, len(p.c.Env)+1)
+	for _, e := range p.c.Env {
+		if strings.HasPrefix(e, VersionVariable+"=") {
+			continue
+		}
+		nenv = append(nenv, e)
+	}
+	p.c.Env = append(nenv, VersionVariable+"="+version1)
+
 	// Create anonymous pipe for communicating data between the child
 	// and the parent.
 	dataRead, dataWrite, err := os.Pipe()
diff --git a/lib/flags/flags.go b/lib/flags/flags.go
index f6c2ef1..102ae14 100644
--- a/lib/flags/flags.go
+++ b/lib/flags/flags.go
@@ -11,11 +11,11 @@
 type FlagGroup int
 
 const (
-	// Essential identifies the flags and associated environment variables
-	// required by all Vanadium processes. Namely:
+	// Runtime identifies the flags and associated environment variables
+	// used by the Vanadium process runtime. Namely:
 	// --veyron.namespace.root (which may be repeated to supply multiple values)
 	// --veyron.credentials
-	Essential FlagGroup = iota
+	Runtime FlagGroup = iota
 	// Listen identifies the flags typically required to configure
 	// ipc.ListenSpec. Namely:
 	// --veyron.tcp.protocol
@@ -44,8 +44,8 @@
 	return nil
 }
 
-// EssentialFlags contains the values of the Essential flag group.
-type EssentialFlags struct {
+// RuntimeFlags contains the values of the Runtime flag group.
+type RuntimeFlags struct {
 	// NamespaceRoots may be initialized by NAMESPACE_ROOT* enivornment
 	// variables as well as --veyron.namespace.root. The command line
 	// will override the environment.
@@ -65,10 +65,10 @@
 	ListenProxy    string
 }
 
-// createAndRegisterEssentialFlags creates and registers the EssentialFlags
+// createAndRegisterRuntimeFlags creates and registers the RuntimeFlags
 // group with the supplied flag.FlagSet.
-func createAndRegisterEssentialFlags(fs *flag.FlagSet) *EssentialFlags {
-	f := &EssentialFlags{}
+func createAndRegisterRuntimeFlags(fs *flag.FlagSet) *RuntimeFlags {
+	f := &RuntimeFlags{}
 	fs.Var(&f.namespaceRootsFlag, "veyron.namespace.root", "local namespace root; can be repeated to provided multiple roots")
 	fs.StringVar(&f.Credentials, "veyron.credentials", "", "directory to use for storing security credentials")
 	return f
@@ -88,14 +88,16 @@
 
 // CreateAndRegister creates a new set of flag groups as specified by the
 // supplied flag group parameters and registers them with the supplied
-// flag.Flagset. The Essential flag group is always included.
+// flag.Flagset.
 func CreateAndRegister(fs *flag.FlagSet, groups ...FlagGroup) *Flags {
+	if len(groups) == 0 {
+		return nil
+	}
 	f := &Flags{FlagSet: fs, groups: make(map[FlagGroup]interface{})}
-	f.groups[Essential] = createAndRegisterEssentialFlags(fs)
-	for _, s := range groups {
-		switch s {
-		case Essential:
-			// do nothing, always included
+	for _, g := range groups {
+		switch g {
+		case Runtime:
+			f.groups[Runtime] = createAndRegisterRuntimeFlags(fs)
 		case Listen:
 			f.groups[Listen] = createAndRegisterListenFlags(fs)
 		}
@@ -103,10 +105,13 @@
 	return f
 }
 
-// EssentialFlags returns the Essential flag subset stored in its Flags
+// RuntimeFlags returns the Runtime flag subset stored in its Flags
 // instance.
-func (f *Flags) EssentialFlags() EssentialFlags {
-	from := f.groups[Essential].(*EssentialFlags)
+func (f *Flags) RuntimeFlags() RuntimeFlags {
+	if p := f.groups[Runtime]; p == nil {
+		return RuntimeFlags{}
+	}
+	from := f.groups[Runtime].(*RuntimeFlags)
 	to := *from
 	to.NamespaceRoots = make([]string, len(from.NamespaceRoots))
 	copy(to.NamespaceRoots, from.NamespaceRoots)
@@ -138,7 +143,7 @@
 
 // legacyEnvInit provides support for the legacy NAMESPACE_ROOT? and
 // VEYRON_CREDENTIALS env vars.
-func (es *EssentialFlags) legacyEnvInit() {
+func (es *RuntimeFlags) legacyEnvInit() {
 	for _, ev := range os.Environ() {
 		p := strings.SplitN(ev, "=", 2)
 		if len(p) != 2 {
@@ -156,15 +161,22 @@
 
 // Parse parses the supplied args, as per flag.Parse
 func (f *Flags) Parse(args []string) error {
-	f.groups[Essential].(*EssentialFlags).legacyEnvInit()
+	hasrt := f.groups[Runtime] != nil
+	if hasrt {
+		f.groups[Runtime].(*RuntimeFlags).legacyEnvInit()
+	}
+
 	// TODO(cnicolaou): implement a single env var 'VANADIUM_OPTS'
 	// that can be used to specify any command line.
 	if err := f.FlagSet.Parse(args); err != nil {
 		return err
 	}
-	essential := f.groups[Essential].(*EssentialFlags)
-	if len(essential.namespaceRootsFlag.roots) > 0 {
-		essential.NamespaceRoots = essential.namespaceRootsFlag.roots
+
+	if hasrt {
+		runtime := f.groups[Runtime].(*RuntimeFlags)
+		if len(runtime.namespaceRootsFlag.roots) > 0 {
+			runtime.NamespaceRoots = runtime.namespaceRootsFlag.roots
+		}
 	}
 	return nil
 }
diff --git a/lib/flags/flags_test.go b/lib/flags/flags_test.go
index e8ca273..8d10c8a 100644
--- a/lib/flags/flags_test.go
+++ b/lib/flags/flags_test.go
@@ -11,25 +11,32 @@
 )
 
 func TestFlags(t *testing.T) {
-	fl := flags.CreateAndRegister(flag.NewFlagSet("test", flag.ContinueOnError))
+	fs := flag.NewFlagSet("test", flag.ContinueOnError)
+	if flags.CreateAndRegister(fs) != nil {
+		t.Errorf("should have failed")
+	}
+	fl := flags.CreateAndRegister(fs, flags.Runtime)
+	if fl == nil {
+		t.Fatalf("should have returned a non-nil value")
+	}
 	creds := "creddir"
 	roots := []string{"ab:cd:ef"}
 	args := []string{"--veyron.credentials=" + creds, "--veyron.namespace.root=" + roots[0]}
 	fl.Parse(args)
-	es := fl.EssentialFlags()
-	if got, want := es.NamespaceRoots, roots; !reflect.DeepEqual(got, want) {
+	rtf := fl.RuntimeFlags()
+	if got, want := rtf.NamespaceRoots, roots; !reflect.DeepEqual(got, want) {
 		t.Errorf("got %v, want %v", got, want)
 	}
-	if got, want := es.Credentials, creds; !reflect.DeepEqual(got, want) {
+	if got, want := rtf.Credentials, creds; !reflect.DeepEqual(got, want) {
 		t.Errorf("got %v, want %v", got, want)
 	}
 	if got, want := fl.HasGroup(flags.Listen), false; got != want {
 		t.Errorf("got %t, want %t", got, want)
 	}
 	// Make sure we have a deep copy.
-	es.NamespaceRoots[0] = "oooh"
-	es = fl.EssentialFlags()
-	if got, want := es.NamespaceRoots, roots; !reflect.DeepEqual(got, want) {
+	rtf.NamespaceRoots[0] = "oooh"
+	rtf = fl.RuntimeFlags()
+	if got, want := rtf.NamespaceRoots, roots; !reflect.DeepEqual(got, want) {
 		t.Errorf("got %v, want %v", got, want)
 	}
 }
@@ -37,7 +44,7 @@
 func TestFlagError(t *testing.T) {
 	fs := flag.NewFlagSet("test", flag.ContinueOnError)
 	fs.SetOutput(ioutil.Discard)
-	fl := flags.CreateAndRegister(fs)
+	fl := flags.CreateAndRegister(fs, flags.Runtime)
 	addr := "192.168.10.1:0"
 	args := []string{"--xxxveyron.tcp.address=" + addr, "not an arg"}
 	err := fl.Parse(args)
@@ -50,7 +57,7 @@
 }
 
 func TestFlagsGroups(t *testing.T) {
-	fl := flags.CreateAndRegister(flag.NewFlagSet("test", flag.ContinueOnError), flags.Listen)
+	fl := flags.CreateAndRegister(flag.NewFlagSet("test", flag.ContinueOnError), flags.Runtime, flags.Listen)
 	if got, want := fl.HasGroup(flags.Listen), true; got != want {
 		t.Errorf("got %t, want %t", got, want)
 	}
@@ -59,7 +66,7 @@
 	args := []string{"--veyron.tcp.address=" + addr, "--veyron.namespace.root=" + roots[0]}
 	fl.Parse(args)
 	lf := fl.ListenFlags()
-	if got, want := fl.EssentialFlags().NamespaceRoots, roots; !reflect.DeepEqual(got, want) {
+	if got, want := fl.RuntimeFlags().NamespaceRoots, roots; !reflect.DeepEqual(got, want) {
 		t.Errorf("got %v, want %v", got, want)
 	}
 	if got, want := lf.ListenAddress.String(), addr; got != want {
@@ -81,39 +88,41 @@
 	defer os.Setenv(rootEnvVar0, oldroot0)
 
 	os.Setenv(credEnvVar, "bar")
-	fl := flags.CreateAndRegister(flag.NewFlagSet("test", flag.ContinueOnError))
+	fl := flags.CreateAndRegister(flag.NewFlagSet("test", flag.ContinueOnError), flags.Runtime)
 	if err := fl.Parse([]string{}); err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
-	es := fl.EssentialFlags()
-	if got, want := es.Credentials, "bar"; got != want {
+	rtf := fl.RuntimeFlags()
+	if got, want := rtf.Credentials, "bar"; got != want {
 		t.Errorf("got %q, want %q", got, want)
 	}
 
 	if err := fl.Parse([]string{"--veyron.credentials=baz"}); err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
-	es = fl.EssentialFlags()
-	if got, want := es.Credentials, "baz"; got != want {
+	rtf = fl.RuntimeFlags()
+	if got, want := rtf.Credentials, "baz"; got != want {
 		t.Errorf("got %q, want %q", got, want)
 	}
 
 	os.Setenv(rootEnvVar, "a:1")
 	os.Setenv(rootEnvVar0, "a:2")
-	fl = flags.CreateAndRegister(flag.NewFlagSet("test", flag.ContinueOnError))
+	fl = flags.CreateAndRegister(flag.NewFlagSet("test", flag.ContinueOnError), flags.Runtime)
 	if err := fl.Parse([]string{}); err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
-	es = fl.EssentialFlags()
-	if got, want := es.NamespaceRoots, []string{"a:1", "a:2"}; !reflect.DeepEqual(got, want) {
+	rtf = fl.RuntimeFlags()
+	if got, want := rtf.NamespaceRoots, []string{"a:1", "a:2"}; !reflect.DeepEqual(got, want) {
 		t.Errorf("got %q, want %q", got, want)
 	}
-	if err := fl.Parse([]string{"--veyron.namespace.root=b:1", "--veyron.namespace.root=b:2", "--veyron.namespace.root=b:3"}); err != nil {
+	if err := fl.Parse([]string{"--veyron.namespace.root=b:1", "--veyron.namespace.root=b:2", "--veyron.namespace.root=b:3", "--veyron.credentials=b:4"}); err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
-	es = fl.EssentialFlags()
-	if got, want := es.NamespaceRoots, []string{"b:1", "b:2", "b:3"}; !reflect.DeepEqual(got, want) {
+	rtf = fl.RuntimeFlags()
+	if got, want := rtf.NamespaceRoots, []string{"b:1", "b:2", "b:3"}; !reflect.DeepEqual(got, want) {
 		t.Errorf("got %q, want %q", got, want)
 	}
-
+	if got, want := rtf.Credentials, "b:4"; got != want {
+		t.Errorf("got %q, want %q", got, want)
+	}
 }
diff --git a/lib/modules/core/core_test.go b/lib/modules/core/core_test.go
index c108b72..19ee38b 100644
--- a/lib/modules/core/core_test.go
+++ b/lib/modules/core/core_test.go
@@ -21,10 +21,10 @@
 )
 
 func TestCommands(t *testing.T) {
-	shell := core.NewShell()
-	defer shell.Cleanup(nil, os.Stderr)
+	sh := core.NewShell()
+	defer sh.Cleanup(nil, os.Stderr)
 	for _, c := range []string{core.RootMTCommand, core.MTCommand} {
-		if len(shell.Help(c)) == 0 {
+		if len(sh.Help(c)) == 0 {
 			t.Fatalf("missing command %q", c)
 		}
 	}
@@ -53,9 +53,9 @@
 }
 
 func TestRoot(t *testing.T) {
-	shell, fn := newShell()
+	sh, fn := newShell()
 	defer fn()
-	root, err := shell.Start(core.RootMTCommand, testArgs()...)
+	root, err := sh.Start(core.RootMTCommand, nil, testArgs()...)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
@@ -68,7 +68,7 @@
 
 func startMountTables(t *testing.T, sh *modules.Shell, mountPoints ...string) (map[string]string, func(), error) {
 	// Start root mount table
-	root, err := sh.Start(core.RootMTCommand, testArgs()...)
+	root, err := sh.Start(core.RootMTCommand, nil, testArgs()...)
 	if err != nil {
 		t.Fatalf("unexpected error for root mt: %s", err)
 	}
@@ -84,7 +84,7 @@
 
 	// Start the mount tables
 	for _, mp := range mountPoints {
-		h, err := sh.Start(core.MTCommand, testArgs(mp)...)
+		h, err := sh.Start(core.MTCommand, nil, testArgs(mp)...)
 		if err != nil {
 			return nil, nil, fmt.Errorf("unexpected error for mt %q: %s", mp, err)
 		}
@@ -126,18 +126,18 @@
 }
 
 func TestMountTableAndGlob(t *testing.T) {
-	shell, fn := newShell()
+	sh, fn := newShell()
 	defer fn()
 
 	mountPoints := []string{"a", "b", "c", "d", "e"}
-	mountAddrs, fn, err := startMountTables(t, shell, mountPoints...)
+	mountAddrs, fn, err := startMountTables(t, sh, mountPoints...)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
 	defer fn()
 
 	rootName := mountAddrs["root"]
-	ls, err := shell.Start(core.LSCommand, rootName+"/...")
+	ls, err := sh.Start(core.LSCommand, nil, rootName+"/...")
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
@@ -167,7 +167,7 @@
 	}
 
 	// Run the ls command in a subprocess, with NAMESPACE_ROOT as set above.
-	lse, err := shell.Start(core.LSExternalCommand, "...")
+	lse, err := sh.Start(core.LSExternalCommand, nil, "...")
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
@@ -198,10 +198,10 @@
 }
 
 func TestEcho(t *testing.T) {
-	shell, fn := newShell()
+	sh, fn := newShell()
 	defer fn()
 
-	srv, err := shell.Start(core.EchoServerCommand, testArgs("test", "")...)
+	srv, err := sh.Start(core.EchoServerCommand, nil, testArgs("test", "")...)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
@@ -210,7 +210,7 @@
 	if len(name) == 0 {
 		t.Fatalf("failed to get name")
 	}
-	clt, err := shell.Start(core.EchoClientCommand, name, "a message")
+	clt, err := sh.Start(core.EchoClientCommand, nil, name, "a message")
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
@@ -220,11 +220,11 @@
 }
 
 func TestResolve(t *testing.T) {
-	shell, fn := newShell()
+	sh, fn := newShell()
 	defer fn()
 
 	mountPoints := []string{"a", "b"}
-	mountAddrs, fn, err := startMountTables(t, shell, mountPoints...)
+	mountAddrs, fn, err := startMountTables(t, sh, mountPoints...)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
@@ -232,7 +232,7 @@
 	rootName := mountAddrs["root"]
 	mtName := "b"
 	echoName := naming.Join(mtName, "echo")
-	srv, err := shell.Start(core.EchoServerCommand, testArgs("test", echoName)...)
+	srv, err := sh.Start(core.EchoServerCommand, nil, testArgs("test", echoName)...)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
@@ -242,7 +242,7 @@
 	addr = naming.JoinAddressName(addr, "//")
 
 	// Resolve an object
-	resolver, err := shell.Start(core.ResolveCommand, rootName+"/"+echoName)
+	resolver, err := sh.Start(core.ResolveCommand, nil, rootName+"/"+echoName)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
@@ -259,7 +259,7 @@
 
 	// Resolve to a mount table using a rooted name.
 	addr = naming.JoinAddressName(mountAddrs[mtName], "//echo")
-	resolver, err = shell.Start(core.ResolveMTCommand, rootName+"/"+echoName)
+	resolver, err = sh.Start(core.ResolveMTCommand, nil, rootName+"/"+echoName)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
@@ -275,7 +275,7 @@
 	}
 
 	// Resolve to a mount table, but using a relative name.
-	nsroots, err := shell.Start(core.SetNamespaceRootsCommand, rootName)
+	nsroots, err := sh.Start(core.SetNamespaceRootsCommand, nil, rootName)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
@@ -283,7 +283,7 @@
 		t.Fatalf("unexpected error: %s", err)
 	}
 
-	resolver, err = shell.Start(core.ResolveMTCommand, echoName)
+	resolver, err = sh.Start(core.ResolveMTCommand, nil, echoName)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
diff --git a/lib/modules/exec.go b/lib/modules/exec.go
index e81d38b..26c8b61 100644
--- a/lib/modules/exec.go
+++ b/lib/modules/exec.go
@@ -101,7 +101,16 @@
 	newargs := []string{os.Args[0]}
 	newargs = append(newargs, testFlags()...)
 	newargs = append(newargs, args...)
-	return newargs, append(env, eh.entryPoint)
+	// Be careful to remove any existing ShellEntryPoint env vars. This
+	// can happen when subprocesses run other subprocesses etc.
+	cleaned := make([]string, 0, len(env)+1)
+	for _, e := range env {
+		if strings.HasPrefix(e, ShellEntryPoint+"=") {
+			continue
+		}
+		cleaned = append(cleaned, e)
+	}
+	return newargs, append(cleaned, eh.entryPoint)
 }
 
 func (eh *execHandle) start(sh *Shell, env []string, args ...string) (Handle, error) {
@@ -136,8 +145,8 @@
 	if err := handle.Start(); err != nil {
 		return nil, err
 	}
-	// TODO(cnicolaou): make this timeout configurable
-	err = handle.WaitForReady(time.Minute)
+	vlog.VI(1).Infof("Started: %q, pid %d", eh.name, cmd.Process.Pid)
+	err = handle.WaitForReady(sh.startTimeout)
 	return eh, err
 }
 
@@ -223,11 +232,17 @@
 }
 
 func (child *childRegistrar) dispatch() error {
-	ch, _ := vexec.GetChildHandle()
+	ch, err := vexec.GetChildHandle()
+	if err != nil {
+		// This is for debugging only. It's perfectly reasonable for this
+		// error to occur if the process is started by a means other
+		// than the exec library.
+		vlog.VI(1).Infof("failed to get child handle: %s", err)
+	}
+
 	// Only signal that the child is ready or failed if we successfully get
 	// a child handle. We most likely failed to get a child handle
 	// because the subprocess was run directly from the command line.
-
 	command := os.Getenv(ShellEntryPoint)
 	if len(command) == 0 {
 		err := fmt.Errorf("Failed to find entrypoint %q", ShellEntryPoint)
diff --git a/lib/modules/modules_internal_test.go b/lib/modules/modules_internal_test.go
index f60b2bb..07e76bc 100644
--- a/lib/modules/modules_internal_test.go
+++ b/lib/modules/modules_internal_test.go
@@ -35,9 +35,9 @@
 	sh.AddFunction("echof", Echo, "[args]*")
 	assertNumHandles(t, sh, 0)
 
-	_, _ = sh.Start("echonotregistered") // won't start.
-	hs, _ := sh.Start("echos", "a")
-	hf, _ := sh.Start("echof", "b")
+	_, _ = sh.Start("echonotregistered", nil) // won't start.
+	hs, _ := sh.Start("echos", nil, "a")
+	hf, _ := sh.Start("echof", nil, "b")
 	assertNumHandles(t, sh, 2)
 
 	for i, h := range []Handle{hs, hf} {
@@ -47,8 +47,8 @@
 	}
 	assertNumHandles(t, sh, 0)
 
-	hs, _ = sh.Start("echos", "a", "b")
-	hf, _ = sh.Start("echof", "c")
+	hs, _ = sh.Start("echos", nil, "a", "b")
+	hf, _ = sh.Start("echof", nil, "c")
 	assertNumHandles(t, sh, 2)
 
 	sh.Cleanup(nil, nil)
diff --git a/lib/modules/modules_test.go b/lib/modules/modules_test.go
index 0c611d6..e155934 100644
--- a/lib/modules/modules_test.go
+++ b/lib/modules/modules_test.go
@@ -75,7 +75,7 @@
 }
 
 func testCommand(t *testing.T, sh *modules.Shell, name, key, val string) {
-	h, err := sh.Start(name, key)
+	h, err := sh.Start(name, nil, key)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
@@ -124,7 +124,7 @@
 	key, val := "simpleVar", "foo & bar"
 	sh.SetVar(key, val)
 	testCommand(t, sh, "envtest", key, val)
-	_, err := sh.Start("non-existent-command", "random", "args")
+	_, err := sh.Start("non-existent-command", nil, "random", "args")
 	if err == nil || err.Error() != `Shell command "non-existent-command" not registered` {
 		t.Fatalf("unexpected error %v", err)
 	}
@@ -142,7 +142,7 @@
 func TestErrorChild(t *testing.T) {
 	sh := modules.NewShell("errortest")
 	defer sh.Cleanup(nil, nil)
-	h, err := sh.Start("errortest")
+	h, err := sh.Start("errortest", nil)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
@@ -154,7 +154,7 @@
 func testShutdown(t *testing.T, sh *modules.Shell, isfunc bool) {
 	result := ""
 	args := []string{"a", "b c", "ddd"}
-	if _, err := sh.Start("echo", args...); err != nil {
+	if _, err := sh.Start("echo", nil, args...); err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
 	var stdoutBuf bytes.Buffer
@@ -191,7 +191,7 @@
 	sh := modules.NewShell()
 	defer sh.Cleanup(nil, nil)
 	sh.AddFunction("errortest", ErrorMain, "")
-	h, err := sh.Start("errortest")
+	h, err := sh.Start("errortest", nil)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
@@ -215,7 +215,7 @@
 	sh.SetVar("a", "1")
 	sh.SetVar("b", "2")
 	args := []string{"oh", "ah"}
-	h, err := sh.Start("printenv", args...)
+	h, err := sh.Start("printenv", nil, args...)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
@@ -265,7 +265,7 @@
 	sh.SetVar("b", "2 also wrong")
 	os.Setenv("b", "wrong, should be 2")
 
-	h, err := sh.StartWithEnv("printenv", []string{"b=2"})
+	h, err := sh.Start("printenv", []string{"b=2"})
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
diff --git a/lib/modules/shell.go b/lib/modules/shell.go
index cb68856..1bf3e61 100644
--- a/lib/modules/shell.go
+++ b/lib/modules/shell.go
@@ -47,17 +47,19 @@
 	"os"
 	"strings"
 	"sync"
+	"time"
 
 	"veyron.io/veyron/veyron2/vlog"
 )
 
 // Shell represents the context within which commands are run.
 type Shell struct {
-	mu      sync.Mutex
-	env     map[string]string
-	cmds    map[string]*commandDesc
-	handles map[Handle]struct{}
-	credDir string
+	mu           sync.Mutex
+	env          map[string]string
+	cmds         map[string]*commandDesc
+	handles      map[Handle]struct{}
+	credDir      string
+	startTimeout time.Duration
 }
 
 type commandDesc struct {
@@ -90,9 +92,10 @@
 	// TODO(cnicolaou): should create a new identity if one doesn't
 	// already exist
 	sh := &Shell{
-		env:     make(map[string]string),
-		cmds:    make(map[string]*commandDesc),
-		handles: make(map[Handle]struct{}),
+		env:          make(map[string]string),
+		cmds:         make(map[string]*commandDesc),
+		handles:      make(map[Handle]struct{}),
+		startTimeout: time.Minute,
 	}
 	if flag.Lookup("test.run") != nil && os.Getenv("VEYRON_CREDENTIALS") == "" {
 		if err := sh.CreateAndUseNewCredentials(); err != nil {
@@ -176,8 +179,15 @@
 }
 
 // Start starts the specified command, it returns a Handle which can be used
-// for interacting with that command. The Shell tracks all of the Handles
-// that it creates so that it can shut them down when asked to.
+// for interacting with that command. The OS and shell environment variables
+// are merged with the ones supplied as a parameter; the parameter specified
+// ones override the Shell and the Shell ones override the OS ones.
+//
+// The Shell tracks all of the Handles that it creates so that it can shut
+// them down when asked to. The returned Handle may be non-nil even when an
+// error is returned, in which case it may be used to retrieve any output
+// from the failed command.
+//
 // Commands may have already been registered with the Shell using AddFunction
 // or AddSubprocess, but if not, they will treated as subprocess commands
 // and an attempt made to run them. Such 'dynamically' started subprocess
@@ -185,19 +195,15 @@
 // message etc; their handles are remembered and will be acted on by
 // the Cleanup method. If the non-registered subprocess command does not
 // exist then the Start command will return an error.
-func (sh *Shell) Start(name string, args ...string) (Handle, error) {
-	return sh.StartWithEnv(name, nil, args...)
-}
-
-// StartWithEnv is like Start except with a set of environment variables
-// that override those in the Shell and the OS' environment.
-func (sh *Shell) StartWithEnv(name string, env []string, args ...string) (Handle, error) {
+func (sh *Shell) Start(name string, env []string, args ...string) (Handle, error) {
 	cenv := sh.MergedEnv(env)
 	cmd := sh.getCommand(name)
 	expanded := append([]string{name}, sh.expand(args...)...)
 	h, err := cmd.factory().start(sh, cenv, expanded...)
 	if err != nil {
-		return nil, err
+		// If the error is a timeout, then h can be used to recover
+		// any output from the process.
+		return h, err
 	}
 	sh.mu.Lock()
 	sh.handles[h] = struct{}{}
@@ -215,6 +221,11 @@
 	return cmd
 }
 
+// SetStartTimeout sets the timeout for starting subcommands.
+func (sh *Shell) SetStartTimeout(d time.Duration) {
+	sh.startTimeout = d
+}
+
 // CommandEnvelope returns the command line and environment that would be
 // used for running the subprocess or function if it were started with the
 // specifed arguments.
diff --git a/lib/signals/signals_test.go b/lib/signals/signals_test.go
index 636bbdb..b045ef9 100644
--- a/lib/signals/signals_test.go
+++ b/lib/signals/signals_test.go
@@ -113,7 +113,7 @@
 func newShell(t *testing.T, command string) (*modules.Shell, modules.Handle, *expect.Session) {
 	sh := modules.NewShell()
 	sh.AddSubprocess(command, "")
-	handle, err := sh.Start(command)
+	handle, err := sh.Start(command, nil)
 	if err != nil {
 		sh.Cleanup(os.Stderr, os.Stderr)
 		t.Fatalf("unexpected error: %s", err)
@@ -340,7 +340,7 @@
 	defer configServer.Stop()
 	sh.SetVar("VEYRON_CREDENTIALS", childcreds)
 	sh.SetVar(mgmt.ParentNodeManagerConfigKey, configServiceName)
-	h, err := sh.Start("handleDefaults")
+	h, err := sh.Start("handleDefaults", nil)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
diff --git a/lib/textutil/line_writer.go b/lib/textutil/line_writer.go
index 0b70ae7..c7df3a5 100644
--- a/lib/textutil/line_writer.go
+++ b/lib/textutil/line_writer.go
@@ -155,7 +155,7 @@
 //
 // SetIndents() is equivalent to SetIndents(""), SetIndents("", ""), etc.
 //
-// A new LineWriter instance has no idents by default.
+// A new LineWriter instance has no indents by default.
 //
 // Calls Flush internally, and returns any Flush error.
 func (w *LineWriter) SetIndents(indents ...string) error {
diff --git a/runtimes/google/ipc/benchmarks/service.vdl.go b/runtimes/google/ipc/benchmarks/service.vdl.go
index 127b5d8..806dd55 100644
--- a/runtimes/google/ipc/benchmarks/service.vdl.go
+++ b/runtimes/google/ipc/benchmarks/service.vdl.go
@@ -16,8 +16,9 @@
 	_gen_wiretype "veyron.io/veyron/veyron2/wiretype"
 )
 
-// TODO(bprosnitz) Remove this line once signatures are updated to use typevals.
-// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only bootstrap types are used on interfaces.
+// TODO(toddw): Remove this line once the new signature support is done.
+// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only
+// bootstrap types are used on interfaces.
 const _ = _gen_wiretype.TypeIDInvalid
 
 // Benchmark is the interface the client binds and uses.
diff --git a/runtimes/google/ipc/server_test.go b/runtimes/google/ipc/server_test.go
index 9718c2a..8a8020f 100644
--- a/runtimes/google/ipc/server_test.go
+++ b/runtimes/google/ipc/server_test.go
@@ -29,7 +29,7 @@
 	defer b.cleanup(t)
 	sh := modules.NewShell()
 	defer sh.Cleanup(os.Stderr, os.Stderr)
-	server, err := sh.Start("runServer", "127.0.0.1:0")
+	server, err := sh.Start("runServer", nil, "127.0.0.1:0")
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
@@ -64,7 +64,7 @@
 
 	// Resurrect the server with the same address, verify client
 	// re-establishes the connection.
-	server, err = sh.Start("runServer", addr)
+	server, err = sh.Start("runServer", nil, addr)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
@@ -85,7 +85,7 @@
 
 func (h *proxyHandle) Start(t *testing.T) error {
 	sh := modules.NewShell()
-	server, err := sh.Start("runProxy")
+	server, err := sh.Start("runProxy", nil)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
diff --git a/runtimes/google/ipc/stream/manager/manager_test.go b/runtimes/google/ipc/stream/manager/manager_test.go
index cd66579..873d882 100644
--- a/runtimes/google/ipc/stream/manager/manager_test.go
+++ b/runtimes/google/ipc/stream/manager/manager_test.go
@@ -438,7 +438,7 @@
 	client := InternalNew(naming.FixedRoutingID(0xcccccccc))
 	sh := modules.NewShell(".*")
 	defer sh.Cleanup(nil, nil)
-	h, err := sh.Start("runServer", "127.0.0.1:0")
+	h, err := sh.Start("runServer", nil, "127.0.0.1:0")
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
@@ -459,7 +459,7 @@
 		t.Fatal("Expected client.Dial to fail since server is dead")
 	}
 
-	h, err = sh.Start("runServer", addr)
+	h, err = sh.Start("runServer", nil, addr)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
diff --git a/runtimes/google/rt/mgmt_test.go b/runtimes/google/rt/mgmt_test.go
index 4b3b757..0737a1e 100644
--- a/runtimes/google/rt/mgmt_test.go
+++ b/runtimes/google/rt/mgmt_test.go
@@ -113,7 +113,7 @@
 func TestNoWaiters(t *testing.T) {
 	sh := modules.NewShell(noWaitersCmd)
 	defer sh.Cleanup(os.Stderr, os.Stderr)
-	h, err := sh.Start(noWaitersCmd)
+	h, err := sh.Start(noWaitersCmd, nil)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
@@ -139,7 +139,7 @@
 func TestForceStop(t *testing.T) {
 	sh := modules.NewShell(forceStopCmd)
 	defer sh.Cleanup(os.Stderr, os.Stderr)
-	h, err := sh.Start(forceStopCmd)
+	h, err := sh.Start(forceStopCmd, nil)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
@@ -291,7 +291,7 @@
 	sh := modules.NewShell(appCmd)
 	sh.SetVar("VEYRON_CREDENTIALS", childcreds)
 	sh.SetVar(mgmt.ParentNodeManagerConfigKey, configServiceName)
-	h, err := sh.Start("app")
+	h, err := sh.Start("app", nil)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
diff --git a/runtimes/google/rt/rt.go b/runtimes/google/rt/rt.go
index d106b7f..6de8860 100644
--- a/runtimes/google/rt/rt.go
+++ b/runtimes/google/rt/rt.go
@@ -5,7 +5,6 @@
 	"fmt"
 	"os"
 	"path/filepath"
-	"strings"
 	"sync"
 
 	"veyron.io/veyron/veyron2"
@@ -17,6 +16,7 @@
 	"veyron.io/veyron/veyron2/rt"
 
 	"veyron.io/veyron/veyron/lib/exec"
+	"veyron.io/veyron/veyron/lib/flags"
 	_ "veyron.io/veyron/veyron/lib/stats/sysstats"
 	"veyron.io/veyron/veyron/runtimes/google/naming/namespace"
 	"veyron.io/veyron/veyron2/options"
@@ -40,6 +40,7 @@
 	store      security.PublicIDStore
 	client     ipc.Client
 	mgmt       *mgmtImpl
+	flags      flags.RuntimeFlags
 	nServers   int  // GUARDED_BY(mu)
 	cleaningUp bool // GUARDED_BY(mu)
 
@@ -49,14 +50,21 @@
 
 var _ veyron2.Runtime = (*vrt)(nil)
 
+var flagsOnce sync.Once
+var runtimeFlags *flags.Flags
+
 func init() {
 	rt.RegisterRuntime(veyron2.GoogleRuntimeName, New)
+	runtimeFlags = flags.CreateAndRegister(flag.CommandLine, flags.Runtime)
 }
 
 // Implements veyron2/rt.New
 func New(opts ...veyron2.ROpt) (veyron2.Runtime, error) {
 	rt := &vrt{mgmt: new(mgmtImpl), lang: i18n.LangIDFromEnv(), program: filepath.Base(os.Args[0])}
-	flag.Parse()
+	flagsOnce.Do(func() {
+		runtimeFlags.Parse(os.Args[1:])
+	})
+	rt.flags = runtimeFlags.RuntimeFlags()
 	nsRoots := []string{}
 	for _, o := range opts {
 		switch v := o.(type) {
@@ -66,8 +74,6 @@
 			rt.id = v.PrivateID
 		case options.Profile:
 			rt.profile = v.Profile
-		case options.NamespaceRoots:
-			nsRoots = v
 		case options.RuntimeName:
 			if v != "google" && v != "" {
 				return nil, fmt.Errorf("%q is the wrong name for this runtime", v)
@@ -88,20 +94,7 @@
 		vlog.VI(1).Infof("Using profile %q", rt.profile.Name())
 	}
 
-	if len(nsRoots) == 0 {
-		for _, ev := range os.Environ() {
-			p := strings.SplitN(ev, "=", 2)
-			if len(p) != 2 {
-				continue
-			}
-			k, v := p[0], p[1]
-			if strings.HasPrefix(k, "NAMESPACE_ROOT") {
-				nsRoots = append(nsRoots, v)
-			}
-		}
-	}
-
-	if ns, err := namespace.New(rt, nsRoots...); err != nil {
+	if ns, err := namespace.New(rt, rt.flags.NamespaceRoots...); err != nil {
 		return nil, fmt.Errorf("Couldn't create mount table: %v", err)
 	} else {
 		rt.ns = ns
@@ -113,7 +106,7 @@
 		return nil, fmt.Errorf("failed to create stream manager: %s", err)
 	}
 
-	if err := rt.initSecurity(); err != nil {
+	if err := rt.initSecurity(rt.flags.Credentials); err != nil {
 		return nil, fmt.Errorf("failed to init sercurity: %s", err)
 	}
 
diff --git a/runtimes/google/rt/rt_test.go b/runtimes/google/rt/rt_test.go
index 8b23035..44b28fe 100644
--- a/runtimes/google/rt/rt_test.go
+++ b/runtimes/google/rt/rt_test.go
@@ -10,7 +10,6 @@
 	"testing"
 	"time"
 
-	"veyron.io/veyron/veyron2"
 	"veyron.io/veyron/veyron2/naming"
 	"veyron.io/veyron/veyron2/options"
 	"veyron.io/veyron/veyron2/rt"
@@ -20,7 +19,6 @@
 	"veyron.io/veyron/veyron/lib/expect"
 	"veyron.io/veyron/veyron/lib/modules"
 	"veyron.io/veyron/veyron/lib/testutil"
-	irt "veyron.io/veyron/veyron/runtimes/google/rt"
 	vsecurity "veyron.io/veyron/veyron/security"
 )
 
@@ -28,6 +26,10 @@
 	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 "" }
@@ -44,6 +46,9 @@
 func init() {
 	testutil.Init()
 	modules.RegisterChild("child", "", child)
+	modules.RegisterChild("principal", "", principal)
+	modules.RegisterChild("mutate", "", mutatePrincipal)
+	modules.RegisterChild("runner", "", runner)
 }
 
 func TestHelperProcess(t *testing.T) {
@@ -71,14 +76,14 @@
 	vlog.Infof("%s\n", r.Logger())
 	fmt.Fprintf(stdout, "%s\n", r.Logger())
 	modules.WaitForEOF(stdin)
-	fmt.Printf("done\n")
+	fmt.Fprintf(stdout, "done\n")
 	return nil
 }
 
 func TestInitArgs(t *testing.T) {
 	sh := modules.NewShell("child")
 	defer sh.Cleanup(os.Stderr, os.Stderr)
-	h, err := sh.Start("child", "--logtostderr=true", "--vv=3", "--", "foobar")
+	h, err := sh.Start("child", nil, "--logtostderr=true", "--vv=3", "--", "foobar")
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
@@ -99,67 +104,221 @@
 	h.Shutdown(os.Stderr, os.Stderr)
 }
 
-func TestInitPrincipal(t *testing.T) {
-	newRT := func() veyron2.Runtime {
-		r, err := rt.New(profileOpt)
-		if err != nil {
-			t.Fatalf("rt.New failed: %v", err)
-		}
-		return r
+func validatePrincipal(p security.Principal) error {
+	if p == nil {
+		return fmt.Errorf("nil principal")
 	}
-	testPrincipal := func(r veyron2.Runtime) security.Principal {
-		p := r.Principal()
-		if p == nil {
-			t.Fatalf("rt.Principal() returned nil")
-		}
-		blessings := p.BlessingStore().Default()
-		if blessings == nil {
-			t.Fatalf("rt.Principal().BlessingStore().Default() returned nil")
+	blessings := p.BlessingStore().Default()
+	if blessings == nil {
+		return fmt.Errorf("rt.Principal().BlessingStore().Default() returned nil")
 
-		}
-		if n := len(blessings.ForContext(&context{local: p})); n != 1 {
-			t.Fatalf("rt.Principal().BlessingStore().Default() returned Blessing %v with %d recognized blessings, want exactly one recognized blessing", blessings, n)
-		}
-		return p
 	}
-	origCredentialsDir := os.Getenv(irt.VeyronCredentialsEnvVar)
-	defer os.Setenv(irt.VeyronCredentialsEnvVar, origCredentialsDir)
-
-	// Test that even with VEYRON_CREDENTIALS unset the runtime's Principal
-	// is correctly initialized.
-	if err := os.Setenv(irt.VeyronCredentialsEnvVar, ""); err != nil {
-		t.Fatal(err)
+	if n := len(blessings.ForContext(&context{local: p})); n != 1 {
+		fmt.Errorf("rt.Principal().BlessingStore().Default() returned Blessing %v with %d recognized blessings, want exactly one recognized blessing", blessings, n)
 	}
-	testPrincipal(newRT())
+	return nil
+}
 
-	// Test that with VEYRON_CREDENTIALS set the runtime's Principal is correctly
-	// initialized.
-	credentials, err := ioutil.TempDir("", "credentials")
+func tmpDir(t *testing.T) string {
+	dir, err := ioutil.TempDir("", "rt_test_dir")
 	if err != nil {
-		t.Fatal(err)
+		t.Fatalf("unexpected error: %s", err)
 	}
-	defer os.RemoveAll(credentials)
-	if err := os.Setenv(irt.VeyronCredentialsEnvVar, credentials); err != nil {
-		t.Fatal(err)
+	return dir
+}
+
+func principal(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
+	r := rt.Init()
+	err := validatePrincipal(r.Principal())
+	fmt.Fprintf(stdout, "ERROR=%v\n", err)
+	fmt.Fprintf(stdout, "PUBKEY=%s\n", r.Principal().PublicKey())
+	modules.WaitForEOF(stdin)
+	return nil
+}
+
+// Runner runs a principal as a subprocess and reports back with its
+// own security info and it's childs.
+func runner(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
+	r := rt.Init()
+	err := validatePrincipal(r.Principal())
+	fmt.Fprintf(stdout, "RUNNER_ERROR=%v\n", err)
+	fmt.Fprintf(stdout, "RUNNER_PUBKEY=%s\n", r.Principal().PublicKey())
+	if err != nil {
+		return err
 	}
-	p := testPrincipal(newRT())
+	sh := modules.NewShell("principal")
+	defer sh.Cleanup(os.Stderr, os.Stderr)
+	h, err := sh.Start("principal", nil, args[1:]...)
+	if err != nil {
+		return err
+	}
+	s := expect.NewSession(nil, h.Stdout(), 1*time.Second) // time.Minute)
+	fmt.Fprintf(stdout, s.ReadLine()+"\n")
+	fmt.Fprintf(stdout, s.ReadLine()+"\n")
+	modules.WaitForEOF(stdin)
+	return nil
+}
+
+func mutatePrincipal(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
+	r := rt.Init()
+
+	rtPrincipal := r.Principal()
+	err := validatePrincipal(rtPrincipal)
+	fmt.Fprintf(stdout, "ERROR=%v\n", err)
 
 	// Mutate the roots and store of this principal.
-	blessing, err := p.BlessSelf("irrelevant")
+	blessing, err := rtPrincipal.BlessSelf("irrelevant")
 	if err != nil {
-		t.Fatal(err)
+		return err
 	}
-	if _, err := p.BlessingStore().Set(blessing, security.AllPrincipals); err != nil {
-		t.Fatal(err)
+	if _, err := rtPrincipal.BlessingStore().Set(blessing, security.AllPrincipals); err != nil {
+		return err
 	}
-	if err := p.AddToRoots(blessing); err != nil {
+	if err := rtPrincipal.AddToRoots(blessing); err != nil {
+		return err
+	}
+	newRT, err := rt.New(profileOpt)
+	if err != nil {
+		return fmt.Errorf("rt.New failed: %v", err)
+	}
+	// Test that the same principal gets initialized on creating a new runtime
+	// from the same credentials directory.
+	if got := newRT.Principal(); !reflect.DeepEqual(got, rtPrincipal) {
+		return fmt.Errorf("Initialized Principal: %v, expected: %v", got.PublicKey(), rtPrincipal.PublicKey())
+	}
+	fmt.Fprintf(stdout, "PUBKEY=%s\n", newRT.Principal().PublicKey())
+	modules.WaitForEOF(stdin)
+	return nil
+}
+
+func createCredentialsInDir(t *testing.T, dir string) security.Principal {
+	principal, err := vsecurity.CreatePersistentPrincipal(dir, nil)
+	if err != nil {
+		t.Fatalf("unexpected error: %s", err)
+	}
+	vsecurity.InitDefaultBlessings(principal, "test")
+	return principal
+}
+
+func TestPrincipalInheritance(t *testing.T) {
+	sh := modules.NewShell("principal", "runner")
+	defer func() {
+		sh.Cleanup(os.Stdout, os.Stderr)
+	}()
+
+	// Test that the child inherits the parent's credentials correctly.
+	// The running test process may or may not have a credentials directory set
+	// up so we have to use a 'runner' process to ensure the correct setup.
+	cdir := tmpDir(t)
+	defer os.RemoveAll(cdir)
+
+	principal := createCredentialsInDir(t, cdir)
+
+	// directory supplied by the environment.
+	credEnv := []string{veyronCredentialsEnvVar + "=" + cdir}
+
+	h, err := sh.Start("runner", credEnv)
+	if err != nil {
+		t.Fatalf("unexpected error: %s", err)
+	}
+	s := expect.NewSession(t, h.Stdout(), 2*time.Second) //time.Minute)
+	runnerErr := s.ExpectVar("RUNNER_ERROR")
+	runnerPubKey := s.ExpectVar("RUNNER_PUBKEY")
+	principalErr := s.ExpectVar("ERROR")
+	principalPubKey := s.ExpectVar("PUBKEY")
+	if err := s.Error(); err != nil {
+		t.Fatalf("failed to read input from children: %s", err)
+	}
+	h.Shutdown(os.Stdout, os.Stderr)
+	if runnerErr != "<nil>" || principalErr != "<nil>" {
+		t.Fatalf("unexpected error: runner %q, principal %q", runnerErr, principalErr)
+	}
+	pubKey := principal.PublicKey().String()
+	if runnerPubKey != pubKey || principalPubKey != pubKey {
+		t.Fatalf("unexpected pubkeys: expected %s: runner %s, principal %s",
+			pubKey, runnerPubKey, principalPubKey)
+	}
+
+}
+
+func TestPrincipalInit(t *testing.T) {
+	// Collet the process' public key and error status
+	collect := func(sh *modules.Shell, cmd string, env []string, args ...string) (string, error) {
+		h, err := sh.Start(cmd, env, args...)
+		if err != nil {
+			t.Fatalf("unexpected error: %s", err)
+		}
+		s := expect.NewSession(t, h.Stdout(), time.Minute)
+		s.SetVerbosity(testing.Verbose())
+		errstr := s.ExpectVar("ERROR")
+		pubkey := s.ExpectVar("PUBKEY")
+		if errstr != "<nil>" {
+			return pubkey, fmt.Errorf("%s", errstr)
+		}
+		return pubkey, nil
+	}
+
+	// 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)
+
+	// Test that with VEYRON_CREDENTIALS unset the runtime's Principal
+	// is correctly initialized.
+	if err := os.Setenv(veyronCredentialsEnvVar, ""); err != nil {
 		t.Fatal(err)
 	}
 
-	// Test that the same principal gets initialized on creating a new runtime
-	// from the same credentials directory.
-	if got := newRT().Principal(); !reflect.DeepEqual(got, p) {
-		t.Fatalf("Initialized Principal: %v, expected: %v", got.PublicKey(), p.PublicKey())
+	sh := modules.NewShell("principal")
+	defer sh.Cleanup(os.Stderr, os.Stderr)
+
+	pubkey, err := collect(sh, "principal", nil)
+	if err != nil {
+		t.Fatalf("child failed to create+validate principal: %v", err)
+	}
+	if len(pubkey) == 0 {
+		t.Fatalf("child failed to return a public key")
+	}
+
+	// Test specifying credentials via VEYRON_CREDENTIALS
+	cdir1 := tmpDir(t)
+	defer os.RemoveAll(cdir1)
+	principal := createCredentialsInDir(t, cdir1)
+	// directory supplied by the environment.
+	credEnv := []string{veyronCredentialsEnvVar + "=" + cdir1}
+
+	pubkey, err = collect(sh, "principal", credEnv)
+	if err != nil {
+		t.Errorf("unexpected error: %s", err)
+	}
+
+	if got, want := pubkey, principal.PublicKey().String(); got != want {
+		t.Errorf("got %q, want %q", got, want)
+	}
+
+	// Test specifying credentials via the command line and that the
+	// comand line overrides the environment
+	cdir2 := tmpDir(t)
+	defer os.RemoveAll(cdir2)
+	clPrincipal := createCredentialsInDir(t, cdir2)
+
+	pubkey, err = collect(sh, "principal", credEnv, "--veyron.credentials="+cdir2)
+	if err != nil {
+		t.Errorf("unexpected error: %s", err)
+	}
+
+	if got, want := pubkey, clPrincipal.PublicKey().String(); got != want {
+		t.Errorf("got %q, want %q", got, want)
+	}
+
+	// Mutate the roots and store of the principal in the child process.
+	pubkey, err = collect(sh, "mutate", credEnv, "--veyron.credentials="+cdir2)
+	if err != nil {
+		t.Errorf("unexpected error: %s", err)
+	}
+
+	if got, want := pubkey, clPrincipal.PublicKey().String(); got != want {
+		t.Errorf("got %q, want %q", got, want)
 	}
 }
 
diff --git a/runtimes/google/rt/security.go b/runtimes/google/rt/security.go
index 0863c04a..aa673d4 100644
--- a/runtimes/google/rt/security.go
+++ b/runtimes/google/rt/security.go
@@ -15,10 +15,6 @@
 	"veyron.io/veyron/veyron2/vlog"
 )
 
-// Environment variable pointing to a directory where information about a principal
-// (private key, blessing store, blessing roots etc.) is stored.
-const VeyronCredentialsEnvVar = "VEYRON_CREDENTIALS"
-
 func (rt *vrt) Principal() security.Principal {
 	return rt.principal
 }
@@ -35,31 +31,33 @@
 	return rt.store
 }
 
-func (rt *vrt) initSecurity() error {
+func (rt *vrt) initSecurity(credentials string) error {
 	if err := rt.initOldSecurity(); err != nil {
 		return err
 	}
-	if err := rt.initPrincipal(); err != nil {
+	if err := rt.initPrincipal(credentials); err != nil {
 		return fmt.Errorf("principal initialization failed: %v", err)
 	}
 	return nil
 }
 
-func (rt *vrt) initPrincipal() error {
+func (rt *vrt) initPrincipal(credentials string) error {
 	if rt.principal != nil {
 		return nil
 	}
 	var err error
+	// TODO(cnicolaou,ashankar,ribrdb): this should be supplied via
+	// the exec.GetChildHandle call.
 	if len(os.Getenv(agent.FdVarName)) > 0 {
 		rt.principal, err = rt.connectToAgent()
 		return err
-	} else if dir := os.Getenv(VeyronCredentialsEnvVar); len(dir) > 0 {
+	} else if len(credentials) > 0 {
 		// TODO(ataly, ashankar): If multiple runtimes are getting
 		// initialized at the same time from the same VEYRON_CREDENTIALS
 		// we will need some kind of locking for the credential files.
-		if rt.principal, err = vsecurity.LoadPersistentPrincipal(dir, nil); err != nil {
+		if rt.principal, err = vsecurity.LoadPersistentPrincipal(credentials, nil); err != nil {
 			if os.IsNotExist(err) {
-				if rt.principal, err = vsecurity.CreatePersistentPrincipal(dir, nil); err != nil {
+				if rt.principal, err = vsecurity.CreatePersistentPrincipal(credentials, nil); err != nil {
 					return err
 				}
 				return vsecurity.InitDefaultBlessings(rt.principal, defaultBlessingName())
diff --git a/runtimes/google/rt/signal_test.go b/runtimes/google/rt/signal_test.go
index 5aa1b3d..e37f883 100644
--- a/runtimes/google/rt/signal_test.go
+++ b/runtimes/google/rt/signal_test.go
@@ -47,7 +47,7 @@
 func TestWithRuntime(t *testing.T) {
 	sh := modules.NewShell("withRuntime")
 	defer sh.Cleanup(os.Stderr, os.Stderr)
-	h, err := sh.Start("withRuntime")
+	h, err := sh.Start("withRuntime", nil)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
@@ -64,7 +64,7 @@
 func TestWithoutRuntime(t *testing.T) {
 	sh := modules.NewShell("withoutRuntime")
 	defer sh.Cleanup(os.Stderr, os.Stderr)
-	h, err := sh.Start("withoutRuntime")
+	h, err := sh.Start("withoutRuntime", nil)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
diff --git a/runtimes/google/security/identity_test.go b/runtimes/google/security/identity_test.go
index 315e9cd..1dae49c 100644
--- a/runtimes/google/security/identity_test.go
+++ b/runtimes/google/security/identity_test.go
@@ -352,7 +352,7 @@
 	// registers all values encoded within the same process.
 	sh := modules.NewShell(".*")
 	defer sh.Cleanup(nil, nil)
-	h, err := sh.Start("encodeUnregisteredCaveat")
+	h, err := sh.Start("encodeUnregisteredCaveat", nil)
 	if err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
diff --git a/security/agent/agentd/main.go b/security/agent/agentd/main.go
index b3341cb..423e146 100644
--- a/security/agent/agentd/main.go
+++ b/security/agent/agentd/main.go
@@ -1,11 +1,12 @@
 package main
 
 import (
-	"code.google.com/p/gopass"
+	"code.google.com/p/go.crypto/ssh/terminal"
 	"flag"
 	"fmt"
 	"os"
 	"os/exec"
+	"os/signal"
 	"syscall"
 	_ "veyron.io/veyron/veyron/profiles"
 	vsecurity "veyron.io/veyron/veyron/security"
@@ -89,11 +90,11 @@
 
 func handleDoesNotExist(dir string) (security.Principal, error) {
 	fmt.Println("Private key file does not exist. Creating new private key...")
-	pass, err := gopass.GetPass("Enter passphrase (entering nothing will store unecrypted): ")
+	pass, err := getPassword("Enter passphrase (entering nothing will store unecrypted): ")
 	if err != nil {
 		return nil, fmt.Errorf("failed to read passphrase: %v", err)
 	}
-	p, err := vsecurity.CreatePersistentPrincipal(dir, []byte(pass))
+	p, err := vsecurity.CreatePersistentPrincipal(dir, pass)
 	if err != nil {
 		return nil, err
 	}
@@ -103,9 +104,40 @@
 
 func handlePassphrase(dir string) (security.Principal, error) {
 	fmt.Println("Private key file is encrypted. Please enter passphrase.")
-	pass, err := gopass.GetPass("Enter passphrase: ")
+	pass, err := getPassword("Enter passphrase: ")
 	if err != nil {
 		return nil, fmt.Errorf("failed to read passphrase: %v", err)
 	}
-	return vsecurity.LoadPersistentPrincipal(dir, []byte(pass))
+	return vsecurity.LoadPersistentPrincipal(dir, pass)
+}
+
+func getPassword(prompt string) ([]byte, error) {
+	fmt.Printf(prompt)
+	stop := make(chan bool)
+	defer close(stop)
+	state, err := terminal.GetState(int(os.Stdin.Fd()))
+	if err != nil {
+		return nil, err
+	}
+	go catchTerminationSignals(stop, state)
+	return terminal.ReadPassword(int(os.Stdin.Fd()))
+}
+
+// catchTerminationSignals catches signals to allow us to turn terminal echo back on.
+func catchTerminationSignals(stop <-chan bool, state *terminal.State) {
+	var successErrno syscall.Errno
+	sig := make(chan os.Signal, 4)
+	// Catch the blockable termination signals.
+	signal.Notify(sig, syscall.SIGTERM, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGHUP)
+	select {
+	case <-sig:
+		// Start on new line in terminal.
+		fmt.Printf("\n")
+		if err := terminal.Restore(int(os.Stdin.Fd()), state); err != successErrno {
+			vlog.Errorf("Failed to restore terminal state (%v), you words may not show up when you type, enter 'stty echo' to fix this.", err)
+		}
+		os.Exit(-1)
+	case <-stop:
+		signal.Stop(sig)
+	}
 }
diff --git a/security/agent/pingpong/wire.vdl.go b/security/agent/pingpong/wire.vdl.go
index 5a22289..9bf1574 100644
--- a/security/agent/pingpong/wire.vdl.go
+++ b/security/agent/pingpong/wire.vdl.go
@@ -13,8 +13,9 @@
 	_gen_wiretype "veyron.io/veyron/veyron2/wiretype"
 )
 
-// TODO(bprosnitz) Remove this line once signatures are updated to use typevals.
-// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only bootstrap types are used on interfaces.
+// TODO(toddw): Remove this line once the new signature support is done.
+// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only
+// bootstrap types are used on interfaces.
 const _ = _gen_wiretype.TypeIDInvalid
 
 // Simple service used in the agent tests.
diff --git a/security/agent/server/wire.vdl.go b/security/agent/server/wire.vdl.go
index 445984a..d9fcc39 100644
--- a/security/agent/server/wire.vdl.go
+++ b/security/agent/server/wire.vdl.go
@@ -15,8 +15,9 @@
 	_gen_wiretype "veyron.io/veyron/veyron2/wiretype"
 )
 
-// TODO(bprosnitz) Remove this line once signatures are updated to use typevals.
-// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only bootstrap types are used on interfaces.
+// TODO(toddw): Remove this line once the new signature support is done.
+// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only
+// bootstrap types are used on interfaces.
 const _ = _gen_wiretype.TypeIDInvalid
 
 // Agent is the interface the client binds and uses.
diff --git a/services/identity/identity.vdl.go b/services/identity/identity.vdl.go
index 068b53a..85027dc 100644
--- a/services/identity/identity.vdl.go
+++ b/services/identity/identity.vdl.go
@@ -16,8 +16,9 @@
 	_gen_wiretype "veyron.io/veyron/veyron2/wiretype"
 )
 
-// TODO(bprosnitz) Remove this line once signatures are updated to use typevals.
-// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only bootstrap types are used on interfaces.
+// TODO(toddw): Remove this line once the new signature support is done.
+// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only
+// bootstrap types are used on interfaces.
 const _ = _gen_wiretype.TypeIDInvalid
 
 // OAuthBlesser exchanges OAuth access tokens for
diff --git a/services/mgmt/debug/debug.vdl.go b/services/mgmt/debug/debug.vdl.go
index 9a98789..96e09d0 100644
--- a/services/mgmt/debug/debug.vdl.go
+++ b/services/mgmt/debug/debug.vdl.go
@@ -19,8 +19,9 @@
 	_gen_wiretype "veyron.io/veyron/veyron2/wiretype"
 )
 
-// TODO(bprosnitz) Remove this line once signatures are updated to use typevals.
-// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only bootstrap types are used on interfaces.
+// TODO(toddw): Remove this line once the new signature support is done.
+// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only
+// bootstrap types are used on interfaces.
 const _ = _gen_wiretype.TypeIDInvalid
 
 // This interface exists only for the purpose of generating a valid Signature
diff --git a/services/mgmt/node/config.vdl.go b/services/mgmt/node/config.vdl.go
index 32965b5..5ef274f 100644
--- a/services/mgmt/node/config.vdl.go
+++ b/services/mgmt/node/config.vdl.go
@@ -13,8 +13,9 @@
 	_gen_wiretype "veyron.io/veyron/veyron2/wiretype"
 )
 
-// TODO(bprosnitz) Remove this line once signatures are updated to use typevals.
-// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only bootstrap types are used on interfaces.
+// TODO(toddw): Remove this line once the new signature support is done.
+// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only
+// bootstrap types are used on interfaces.
 const _ = _gen_wiretype.TypeIDInvalid
 
 // Config is an RPC API to the config service.
diff --git a/services/mgmt/node/impl/impl_test.go b/services/mgmt/node/impl/impl_test.go
index 8794636..69b1f2c 100644
--- a/services/mgmt/node/impl/impl_test.go
+++ b/services/mgmt/node/impl/impl_test.go
@@ -1081,6 +1081,8 @@
 			name = logFileTrimInfoRE.ReplaceAllString(name, "bin.<*>.INFO.<timestamp>")
 			filteredResults = append(filteredResults, name)
 		}
+		sort.Strings(filteredResults)
+		sort.Strings(tc.expected)
 		if !reflect.DeepEqual(filteredResults, tc.expected) {
 			t.Errorf("unexpected result for (%q, %q). Got %q, want %q", tc.name, tc.pattern, filteredResults, tc.expected)
 		}
@@ -1088,6 +1090,9 @@
 
 	// Call Size() on the log file objects.
 	files := doGlob(t, "nm", "apps/google naps/"+installID+"/"+instance1ID+"/logs/*")
+	if want, got := 4, len(files); got < want {
+		t.Errorf("Unexpected number of matches. Got %d, want at least %d", got, want)
+	}
 	for _, file := range files {
 		name := naming.Join("nm", file)
 		c, err := logreader.BindLogFile(name)
@@ -1155,7 +1160,6 @@
 	if err := stream.Finish(); err != nil {
 		t.Errorf("Finish failed: %v", err)
 	}
-	sort.Strings(results)
 	return results
 }
 
diff --git a/services/mgmt/node/impl/util_test.go b/services/mgmt/node/impl/util_test.go
index 8c098dc..c039bbd 100644
--- a/services/mgmt/node/impl/util_test.go
+++ b/services/mgmt/node/impl/util_test.go
@@ -39,7 +39,7 @@
 }
 
 func startRootMT(t *testing.T, sh *modules.Shell) (string, modules.Handle, *expect.Session) {
-	h, err := sh.Start(core.RootMTCommand, "--", "--veyron.tcp.address=127.0.0.1:0")
+	h, err := sh.Start(core.RootMTCommand, nil, "--", "--veyron.tcp.address=127.0.0.1:0")
 	if err != nil {
 		t.Fatalf("failed to start root mount table: %s", err)
 	}
@@ -72,10 +72,10 @@
 		vlog.VI(1).Info("---------------------------------")
 		sh.Cleanup(nil, os.Stderr)
 		mtHandle.Shutdown(nil, os.Stderr)
-		sh.Start(core.SetNamespaceRootsCommand, "")
+		sh.Start(core.SetNamespaceRootsCommand, nil, "")
 	}
 
-	if _, err := sh.Start(core.SetNamespaceRootsCommand, mtName); err != nil {
+	if _, err := sh.Start(core.SetNamespaceRootsCommand, nil, mtName); err != nil {
 		t.Fatalf("%s: unexpected error: %s", loc(1), err)
 	}
 	sh.SetVar("NAMESPACE_ROOT", mtName)
@@ -83,7 +83,7 @@
 }
 
 func runShellCommand(t *testing.T, sh *modules.Shell, env []string, cmd string, args ...string) (modules.Handle, *expect.Session) {
-	h, err := sh.StartWithEnv(cmd, env, args...)
+	h, err := sh.Start(cmd, env, args...)
 	if err != nil {
 		t.Fatalf("%s: failed to start %q: %s", loc(1), cmd, err)
 		return nil, nil
diff --git a/services/mgmt/repository/repository.vdl.go b/services/mgmt/repository/repository.vdl.go
index 2ec59c2..57ac530 100644
--- a/services/mgmt/repository/repository.vdl.go
+++ b/services/mgmt/repository/repository.vdl.go
@@ -23,8 +23,9 @@
 	_gen_wiretype "veyron.io/veyron/veyron2/wiretype"
 )
 
-// TODO(bprosnitz) Remove this line once signatures are updated to use typevals.
-// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only bootstrap types are used on interfaces.
+// TODO(toddw): Remove this line once the new signature support is done.
+// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only
+// bootstrap types are used on interfaces.
 const _ = _gen_wiretype.TypeIDInvalid
 
 // Application describes an application repository internally. Besides
diff --git a/services/mgmt/root/root.vdl.go b/services/mgmt/root/root.vdl.go
index 09c1f3a..273f77b 100644
--- a/services/mgmt/root/root.vdl.go
+++ b/services/mgmt/root/root.vdl.go
@@ -15,8 +15,9 @@
 	_gen_wiretype "veyron.io/veyron/veyron2/wiretype"
 )
 
-// TODO(bprosnitz) Remove this line once signatures are updated to use typevals.
-// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only bootstrap types are used on interfaces.
+// TODO(toddw): Remove this line once the new signature support is done.
+// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only
+// bootstrap types are used on interfaces.
 const _ = _gen_wiretype.TypeIDInvalid
 
 // Root is an interface to be implemented by a process with root level
diff --git a/services/mounttable/lib/collection_test.vdl.go b/services/mounttable/lib/collection_test.vdl.go
index 77b9710..e31a27d 100644
--- a/services/mounttable/lib/collection_test.vdl.go
+++ b/services/mounttable/lib/collection_test.vdl.go
@@ -13,8 +13,9 @@
 	_gen_wiretype "veyron.io/veyron/veyron2/wiretype"
 )
 
-// TODO(bprosnitz) Remove this line once signatures are updated to use typevals.
-// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only bootstrap types are used on interfaces.
+// TODO(toddw): Remove this line once the new signature support is done.
+// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only
+// bootstrap types are used on interfaces.
 const _ = _gen_wiretype.TypeIDInvalid
 
 // Collection is the interface the client binds and uses.
diff --git a/services/security/discharger.vdl.go b/services/security/discharger.vdl.go
index 67dddaf..6793150 100644
--- a/services/security/discharger.vdl.go
+++ b/services/security/discharger.vdl.go
@@ -15,8 +15,9 @@
 	_gen_wiretype "veyron.io/veyron/veyron2/wiretype"
 )
 
-// TODO(bprosnitz) Remove this line once signatures are updated to use typevals.
-// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only bootstrap types are used on interfaces.
+// TODO(toddw): Remove this line once the new signature support is done.
+// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only
+// bootstrap types are used on interfaces.
 const _ = _gen_wiretype.TypeIDInvalid
 
 // Discharger is the interface for obtaining discharges for ThirdPartyCaveats.
diff --git a/tools/mgmt/nminstall b/tools/mgmt/nminstall
new file mode 100755
index 0000000..c6358d2
--- /dev/null
+++ b/tools/mgmt/nminstall
@@ -0,0 +1,124 @@
+#!/bin/bash
+#
+# Installs node manager on the local machine.
+#
+# Specifically:
+#
+# 1. Fetches the binaries required for a node manager installation from a few
+# possible sources.
+#
+# 2. Sets up the helper with setuid.  The helper binary needs to be owned by
+# root and have the suid bit set, to enable the node manager to run binaries
+# under different system accounts than itself.
+#
+# 3. Runs the self-install command on the node manager.
+#
+# Usage:
+#
+# # Gets binaries from local repository (TODO(caprita): implement)
+# ./nminstall <install parent dir>
+#
+# # Gets binaries from local filesystem
+# ./nminstall <install parent dir> /path/to/binaries
+#
+# # Gets binaries from HTTP server (TODO(caprita): implement)
+# ./nminstall <install parent dir> http://host/path
+
+set -e
+
+usage() {
+  echo "usage:"
+  echo "./nminstall <install parent dir> [<binary source>]"
+}
+
+# TODO(caprita): Also agent.
+readonly BIN_NAMES=(noded suidhelper)
+
+#######################################################
+# Fetches binaries needed by node manager installation.
+# Globals:
+#   BIN_NAMES
+#   VEYRON_ROOT
+# Arguments:
+#   destination for binaries
+#   source of binaries
+# Returns:
+#   None
+#######################################
+get_binaries() {
+  local -r BIN_INSTALL="$1"
+  local -r BIN_SOURCE="$2"
+
+  local bin_names_str=""
+  for bin_name in ${BIN_NAMES[@]}; do
+    bin_names_str+=" ${bin_name}"
+  done
+  # If source is not specified, try to look for it in the repository.
+  if [[ -z "${BIN_SOURCE}" ]]; then
+    if [[ -z "${VEYRON_ROOT}" ]]; then
+      echo 'ERROR: binary source not specified and no local repository available'
+      exit 1
+    fi
+    local -r REPO_BIN_DIR="${VEYRON_ROOT}/veyron/go/bin"
+    echo "Fetching binaries:${bin_names_str} from: ${REPO_BIN_DIR} ..."
+    for bin_name in ${BIN_NAMES[@]}; do
+      local repo_source="${REPO_BIN_DIR}/${bin_name}"
+      if [[ -x "${repo_source}" ]]; then
+        local file_destination="${BIN_INSTALL}/${bin_name}"
+	cp "${repo_source}" "${file_destination}"
+        chmod 700 "${file_destination}"
+      else
+	echo "couldn't find ${repo_source}"
+	exit 1
+      fi
+    done
+    echo "Binaries are in ${BIN_INSTALL}."
+    return
+  fi
+
+  echo 'ERROR: couldn'"'"'t fetch binaries.'
+  exit 1
+}
+
+main() {
+  local -r INSTALL_PARENT_DIR="$1"
+  if [[ -z "${INSTALL_PARENT_DIR}" ]]; then
+    echo 'No local install destination specified!'
+    usage
+    exit 1
+  fi
+
+  if [[ ! -d "${INSTALL_PARENT_DIR}" ]]; then
+    echo "${INSTALL_PARENT_DIR} is not a directory!"
+    exit 1
+  fi
+
+  local -r INSTALL_DIR="${INSTALL_PARENT_DIR}/node_manager"
+
+  # TODO(caprita): Check that the node manager is not already installed before
+  # proceeding.  We should require an explicit uninstall to avoid wiping away
+  # the node manager accidentally.
+  sudo rm -rf "${INSTALL_DIR}"
+  mkdir -m 700 "${INSTALL_DIR}"
+
+  local -r BIN_INSTALL="${INSTALL_DIR}/bin"
+  mkdir -m 700 "${BIN_INSTALL}"
+
+  # Fetch the binaries.
+  local -r BIN_SOURCE="$2"
+  get_binaries "${BIN_INSTALL}" "${BIN_SOURCE}"
+
+  # Set up the suidhelper.
+  echo "Configuring suidhelper ..."
+  local -r SETUID_SCRIPT="${BIN_INSTALL}/suidhelper"
+  sudo bash -c "chown root:root \"${SETUID_SCRIPT}\"; chmod 4551 \"${SETUID_SCRIPT}\""
+  echo "Suidhelper configured."
+
+  # Tell the node manager to install itself.
+  local -r NM_ROOT="${INSTALL_DIR}/nmroot"
+  echo "Installing node manager under ${NM_ROOT} ..."
+  VEYRON_NM_CURRENT="${INSTALL_DIR}/curr" VEYRON_NM_ROOT="${NM_ROOT}" VEYRON_NM_HELPER="${SETUID_SCRIPT}" "${BIN_INSTALL}/noded" --install_self
+  echo "Node manager installed."
+}
+
+main "$@"
diff --git a/tools/naming/simulator/driver.go b/tools/naming/simulator/driver.go
index c6abba2..4f944ca 100644
--- a/tools/naming/simulator/driver.go
+++ b/tools/naming/simulator/driver.go
@@ -189,7 +189,7 @@
 		}
 		output(lineno, l)
 	} else {
-		handle, err := sh.Start(name, sub...)
+		handle, err := sh.Start(name, nil, sub...)
 		if err != nil {
 			return err
 		}
diff --git a/tools/servicerunner/main.go b/tools/servicerunner/main.go
index 366e8f4..6b3f501 100644
--- a/tools/servicerunner/main.go
+++ b/tools/servicerunner/main.go
@@ -76,7 +76,7 @@
 
 	vars := map[string]string{}
 
-	h, err := sh.Start("root", "--", "--veyron.tcp.address=127.0.0.1:0")
+	h, err := sh.Start("root", nil, "--", "--veyron.tcp.address=127.0.0.1:0")
 	panicOnError(err)
 	updateVars(h, vars, "MT_NAME")
 
@@ -87,12 +87,12 @@
 
 	// NOTE(sadovsky): The proxyd binary requires --protocol and --address flags
 	// while the proxyd command instead uses ListenSpec flags.
-	h, err = sh.Start("proxyd", "--", "--veyron.tcp.address=127.0.0.1:0", "p")
+	h, err = sh.Start("proxyd", nil, "--", "--veyron.tcp.address=127.0.0.1:0", "p")
 	panicOnError(err)
 	updateVars(h, vars, "PROXY_ADDR")
 
 	// TODO(sadovsky): Which identd should we be using?
-	h, err = sh.Start("wsprd", "--", "--veyron.proxy="+vars["PROXY_ADDR"], "--identd=/proxy.envyor.com:8101/identity/veyron-test/google")
+	h, err = sh.Start("wsprd", nil, "--", "--veyron.proxy="+vars["PROXY_ADDR"], "--identd=/proxy.envyor.com:8101/identity/veyron-test/google")
 	panicOnError(err)
 	updateVars(h, vars, "WSPR_ADDR")
 
diff --git a/tools/vrpc/test_base/test_base.vdl.go b/tools/vrpc/test_base/test_base.vdl.go
index bac146f..92bf836 100644
--- a/tools/vrpc/test_base/test_base.vdl.go
+++ b/tools/vrpc/test_base/test_base.vdl.go
@@ -19,8 +19,9 @@
 	Y int32
 }
 
-// TODO(bprosnitz) Remove this line once signatures are updated to use typevals.
-// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only bootstrap types are used on interfaces.
+// TODO(toddw): Remove this line once the new signature support is done.
+// It corrects a bug where _gen_wiretype is unused in VDL pacakges where only
+// bootstrap types are used on interfaces.
 const _ = _gen_wiretype.TypeIDInvalid
 
 // TypeTester is the interface the client binds and uses.