Merge "veyron/lib/modules: allow Shutdown to return an error status and avoid races."
diff --git a/lib/unixfd/unixfd.go b/lib/unixfd/unixfd.go
new file mode 100644
index 0000000..2fa870f
--- /dev/null
+++ b/lib/unixfd/unixfd.go
@@ -0,0 +1,133 @@
+// Package unixfd provides provides support for Dialing and Listening
+// on already connected file descriptors (like those returned by socketpair).
+package unixfd
+
+import (
+	"errors"
+	"fmt"
+	"io"
+	"net"
+	"os"
+	"strconv"
+	"sync"
+	"syscall"
+	"veyron2/ipc/stream"
+)
+
+const Network string = "unixfd"
+
+// singleConnListener implements net.Listener for an already-connected socket.
+// This is different from net.FileListener, which calls syscall.Listen
+// on an unconnected socket.
+type singleConnListener struct {
+	c    chan net.Conn
+	addr net.Addr
+	sync.Mutex
+}
+
+func (l *singleConnListener) getChan() chan net.Conn {
+	l.Lock()
+	defer l.Unlock()
+	return l.c
+}
+
+func (l *singleConnListener) Accept() (net.Conn, error) {
+	c := l.getChan()
+	if c == nil {
+		return nil, errors.New("listener closed")
+	}
+	if conn, ok := <-c; ok {
+		return conn, nil
+	}
+	return nil, io.EOF
+}
+
+func (l *singleConnListener) Close() error {
+	l.Lock()
+	defer l.Unlock()
+	lc := l.c
+	if lc == nil {
+		return errors.New("listener already closed")
+	}
+	close(l.c)
+	l.c = nil
+	// If the socket was never Accept'ed we need to close it.
+	if c, ok := <-lc; ok {
+		return c.Close()
+	}
+	return nil
+}
+
+func (l *singleConnListener) Addr() net.Addr {
+	return l.addr
+}
+
+func unixFDConn(address string) (net.Conn, error) {
+	fd, err := strconv.ParseInt(address, 10, 32)
+	if err != nil {
+		return nil, err
+	}
+	file := os.NewFile(uintptr(fd), "tmp")
+	conn, err := net.FileConn(file)
+	// 'file' is not used after this point, but we keep it open
+	// so that 'address' remains valid.
+	if err != nil {
+		file.Close()
+		return nil, err
+	}
+	// We wrap 'conn' so we can customize the address, and also
+	// to close 'file'.
+	return &fdConn{addr(address), file, conn}, nil
+}
+
+type fdConn struct {
+	addr net.Addr
+	sock *os.File
+	net.Conn
+}
+
+func (c *fdConn) Close() (err error) {
+	defer c.sock.Close()
+	return c.Conn.Close()
+}
+
+func (c *fdConn) LocalAddr() net.Addr {
+	return c.addr
+}
+
+func (c *fdConn) RemoteAddr() net.Addr {
+	return c.addr
+}
+
+func unixFDListen(address string) (net.Listener, error) {
+	conn, err := unixFDConn(address)
+	if err != nil {
+		return nil, err
+	}
+	c := make(chan net.Conn, 1)
+	c <- conn
+	return &singleConnListener{c, conn.LocalAddr(), sync.Mutex{}}, nil
+}
+
+type addr string
+
+func (a addr) Network() string { return Network }
+func (a addr) String() string  { return string(a) }
+
+// Addr returns a net.Addr for the unixfd network for the given file descriptor.
+func Addr(fd uintptr) net.Addr {
+	return addr(fmt.Sprintf("%d", fd))
+}
+
+// Socketpair returns two connected unix domain sockets, or an error.
+func Socketpair() ([]*os.File, error) {
+	fds, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_STREAM, 0)
+	if err != nil {
+		return nil, err
+	}
+	return []*os.File{os.NewFile(uintptr(fds[0]), "local"), os.NewFile(uintptr(fds[1]), "remote")}, nil
+}
+
+func init() {
+	stream.RegisterProtocol(Network, unixFDConn, unixFDListen)
+}
diff --git a/lib/unixfd/unixfd_test.go b/lib/unixfd/unixfd_test.go
new file mode 100644
index 0000000..dd46ce9
--- /dev/null
+++ b/lib/unixfd/unixfd_test.go
@@ -0,0 +1,127 @@
+package unixfd
+
+import (
+	"bytes"
+	"io"
+	"net"
+	"os"
+	"reflect"
+	"testing"
+)
+
+type nothing struct{}
+
+func dial(fd *os.File) (net.Conn, error) {
+	addr := Addr(fd.Fd())
+	return unixFDConn(addr.String())
+}
+
+func listen(fd *os.File) (net.Listener, error) {
+	addr := Addr(fd.Fd())
+	return unixFDListen(addr.String())
+}
+
+func testWrite(t *testing.T, c net.Conn, data string) {
+	n, err := c.Write([]byte(data))
+	if err != nil {
+		t.Errorf("Write: %v", err)
+		return
+	}
+	if n != len(data) {
+		t.Errorf("Wrote %d bytes, expected %d", n, len(data))
+	}
+}
+
+func testRead(t *testing.T, c net.Conn, expected string) {
+	buf := make([]byte, len(expected)+2)
+	n, err := c.Read(buf)
+	if err != nil {
+		t.Errorf("Read: %v", err)
+		return
+	}
+	if n != len(expected) || !bytes.Equal(buf[0:n], []byte(expected)) {
+		t.Errorf("got %q, expected %q", buf[0:n], expected)
+	}
+}
+
+func TestDial(t *testing.T) {
+	fds, err := Socketpair()
+	if err != nil {
+		t.Fatalf("socketpair: %v", err)
+	}
+	a, err := dial(fds[0])
+	if err != nil {
+		t.Fatalf("dial: %v", err)
+	}
+	b, err := dial(fds[1])
+	if err != nil {
+		t.Fatalf("dial: %v", err)
+	}
+
+	testWrite(t, a, "TEST1")
+	testRead(t, b, "TEST1")
+	testWrite(t, b, "TEST2")
+	testRead(t, a, "TEST2")
+
+	if !reflect.DeepEqual(a.LocalAddr(), Addr(fds[0].Fd())) {
+		t.Errorf("Invalid address %v, expected %d", a.LocalAddr(), fds[0].Fd())
+	}
+	if !reflect.DeepEqual(a.RemoteAddr(), Addr(fds[0].Fd())) {
+		t.Errorf("Invalid address %v, expected %d", a.RemoteAddr(), fds[0].Fd())
+	}
+	if !reflect.DeepEqual(b.LocalAddr(), Addr(fds[1].Fd())) {
+		t.Errorf("Invalid address %v, expected %d", a.LocalAddr(), fds[1].Fd())
+	}
+	if !reflect.DeepEqual(b.RemoteAddr(), Addr(fds[1].Fd())) {
+		t.Errorf("Invalid address %v, expected %d", a.RemoteAddr(), fds[1].Fd())
+	}
+}
+
+func TestListen(t *testing.T) {
+	fds, err := Socketpair()
+	if err != nil {
+		t.Fatalf("socketpair: %v", err)
+	}
+	a, err := dial(fds[0])
+	if err != nil {
+		t.Fatalf("dial: %v", err)
+	}
+	l, err := listen(fds[1])
+	if err != nil {
+		t.Fatalf("listen: %v", err)
+	}
+	b, err := l.Accept()
+	if err != nil {
+		t.Fatalf("accept: %v", err)
+	}
+	start := make(chan nothing, 0)
+	done := make(chan nothing)
+	go func() {
+		defer close(done)
+		<-start
+		if _, err := l.Accept(); err != io.EOF {
+			t.Fatalf("accept: expected EOF, got %v", err)
+		}
+	}()
+
+	// block until the goroutine starts running
+	start <- nothing{}
+	testWrite(t, a, "LISTEN")
+	testRead(t, b, "LISTEN")
+
+	err = l.Close()
+	if err != nil {
+		t.Fatalf("close: %v", err)
+	}
+	<-done
+
+	// After closed, accept should fail immediately
+	_, err = l.Accept()
+	if err == nil {
+		t.Fatalf("Accept succeeded after close")
+	}
+	err = l.Close()
+	if err == nil {
+		t.Fatalf("Close succeeded twice")
+	}
+}
diff --git a/runtimes/google/ipc/stream/crypto/tls_generate_old.sh b/runtimes/google/ipc/stream/crypto/tls_generate_old.sh
index 0560c33..c66c2e8 100755
--- a/runtimes/google/ipc/stream/crypto/tls_generate_old.sh
+++ b/runtimes/google/ipc/stream/crypto/tls_generate_old.sh
@@ -25,8 +25,7 @@
     sed -e 's|// +build go1.4|// +build !go1.4|' |
     sed -e 's|"crypto/tls"|tls "veyron/runtimes/google/ipc/stream/crypto/tlsfork"|' >>$OUTFILE
 
-  local -r REPO_ROOT="$(git rev-parse --show-toplevel)"
-  "${REPO_ROOT}/scripts/build/go" fmt "${OUTFILE}"
+  "${VEYRON_ROOT}/veyron/scripts/build/go" fmt "${OUTFILE}"
 }
 
 main "$@"
diff --git a/runtimes/google/rt/security.go b/runtimes/google/rt/security.go
index a69b33c..8325c02 100644
--- a/runtimes/google/rt/security.go
+++ b/runtimes/google/rt/security.go
@@ -5,10 +5,14 @@
 	"os"
 	"os/user"
 
+	"veyron/lib/unixfd"
 	isecurity "veyron/runtimes/google/security"
 	vsecurity "veyron/security"
+	"veyron/security/agent"
 
+	"veyron2"
 	"veyron2/security"
+	"veyron2/verror"
 	"veyron2/vlog"
 )
 
@@ -50,7 +54,10 @@
 		return nil
 	}
 	var err error
-	if file := os.Getenv("VEYRON_IDENTITY"); len(file) > 0 {
+	if len(os.Getenv(agent.EndpointVarName)) > 0 {
+		rt.id, err = rt.connectToAgent()
+		return err
+	} else if file := os.Getenv("VEYRON_IDENTITY"); len(file) > 0 {
 		if rt.id, err = loadIdentityFromFile(file); err != nil || rt.id == nil {
 			return fmt.Errorf("Could not load identity from the VEYRON_IDENTITY environment variable (%q): %v", file, err)
 		}
@@ -105,3 +112,25 @@
 	defer f.Close()
 	return vsecurity.LoadIdentity(f)
 }
+
+func (rt *vrt) connectToAgent() (security.PrivateID, error) {
+	// Verify we're communicating over unix domain sockets so
+	// we know it's safe to use VCSecurityNone.
+	endpoint, err := rt.NewEndpoint(os.Getenv(agent.EndpointVarName))
+	if err != nil {
+		return nil, err
+	}
+	if endpoint.Addr().Network() != unixfd.Network {
+		return nil, verror.BadArgf("invalid agent address %v", endpoint.Addr())
+	}
+
+	client, err := rt.NewClient(veyron2.VCSecurityNone)
+	if err != nil {
+		return nil, err
+	}
+	signer, err := agent.NewAgentSigner(client, endpoint.String(), rt.NewContext())
+	if err != nil {
+		return nil, err
+	}
+	return isecurity.NewPrivateID("selfSigned", signer)
+}
diff --git a/security/agent/agent_test.go b/security/agent/agent_test.go
new file mode 100644
index 0000000..f2e46b2
--- /dev/null
+++ b/security/agent/agent_test.go
@@ -0,0 +1,85 @@
+package agent_test
+
+import (
+	"crypto/ecdsa"
+	"crypto/elliptic"
+	"crypto/rand"
+	"os"
+	"reflect"
+	"testing"
+	"veyron/security/agent"
+	"veyron/security/agent/server"
+	"veyron2"
+	"veyron2/rt"
+	"veyron2/security"
+)
+
+type fakesigner struct {
+	key security.PublicKey
+}
+
+type testdata struct {
+	server_conn os.File
+	agent       security.Signer
+	signer      fakesigner
+}
+
+func setup() *testdata {
+	runtime := rt.Init()
+	result := &testdata{signer: newFakeSigner()}
+	sock, err := server.RunAnonymousAgent(runtime, result.signer)
+	if err != nil {
+		panic(err)
+	}
+	defer sock.Close()
+	client, err := runtime.NewClient(veyron2.VCSecurityNone)
+	if err != nil {
+		panic(err)
+	}
+	if agent, err := agent.NewAgentSigner(client, agent.CreateAgentEndpoint(int(sock.Fd())), runtime.NewContext()); err == nil {
+		result.agent = agent
+		return result
+	} else {
+		panic(err)
+	}
+}
+
+func TestSignature(t *testing.T) {
+	td := setup()
+	sig, err := td.agent.Sign(nil, []byte("abc"))
+
+	if err != nil {
+		t.Error(err)
+	}
+	expected := security.Signature{R: []byte{6}, S: []byte{7}}
+	if !reflect.DeepEqual(sig, expected) {
+		t.Errorf("Bad signature. Got\n%#v\nExpected:\n%#v", sig, expected)
+	}
+}
+
+func TestPublicKey(t *testing.T) {
+	td := setup()
+	expected_key := td.signer.PublicKey()
+	agent_key := td.agent.PublicKey()
+	if !reflect.DeepEqual(expected_key, agent_key) {
+		t.Errorf("Different keys: %v, %v", expected_key, agent_key)
+	}
+}
+
+func newFakeSigner() fakesigner {
+	key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+	if err != nil {
+		panic(err)
+	}
+	return fakesigner{security.NewECDSAPublicKey(&key.PublicKey)}
+}
+
+func (fakesigner) Sign(message []byte) (security.Signature, error) {
+	var sig security.Signature
+	sig.R, sig.S = []byte{6}, []byte{7}
+	return sig, nil
+}
+
+func (s fakesigner) PublicKey() security.PublicKey {
+	return s.key
+}
diff --git a/security/agent/agentd/main.go b/security/agent/agentd/main.go
new file mode 100644
index 0000000..9538b1e
--- /dev/null
+++ b/security/agent/agentd/main.go
@@ -0,0 +1,63 @@
+package main
+
+import (
+	"flag"
+	"fmt"
+	"os"
+	"os/exec"
+	"syscall"
+	"veyron/security/agent"
+	"veyron/security/agent/server"
+	"veyron2/rt"
+)
+
+func main() {
+	flag.Usage = func() {
+		fmt.Fprintf(os.Stderr, `Usage: %s [agent options] command command_args...
+
+Loads the identity specified in VEYRON_IDENTITY into memory, then
+starts the specified command with access to the identity via the
+agent protocol instead of directly reading from disk.
+
+`, os.Args[0])
+		flag.PrintDefaults()
+	}
+	// Load the identity specified in the environment
+	runtime := rt.Init()
+	log := runtime.Logger()
+
+	if len(flag.Args()) < 1 {
+		flag.Usage()
+		os.Exit(1)
+	}
+
+	var err error
+	if err = os.Setenv(agent.EndpointVarName, agent.CreateAgentEndpoint(3)); err != nil {
+		log.Fatalf("setenv: %v", err)
+	}
+	if err = os.Setenv("VEYRON_IDENTITY", ""); err != nil {
+		log.Fatalf("setenv: %v", err)
+	}
+
+	// Start running our server.
+	var sock *os.File
+	if sock, err = server.RunAnonymousAgent(runtime, runtime.Identity()); err != nil {
+		log.Fatalf("RunAgent: %v", err)
+	}
+
+	// Now run the client and wait for it to finish.
+	cmd := exec.Command(flag.Args()[0], flag.Args()[1:]...)
+	cmd.Stdin = os.Stdin
+	cmd.Stdout = os.Stdout
+	cmd.Stderr = os.Stderr
+	cmd.ExtraFiles = []*os.File{sock}
+
+	err = cmd.Start()
+	if err != nil {
+		log.Fatalf("Error starting child: %v", err)
+	}
+	sock.Close()
+	cmd.Wait()
+	status := cmd.ProcessState.Sys().(syscall.WaitStatus)
+	os.Exit(status.ExitStatus())
+}
diff --git a/security/agent/client.go b/security/agent/client.go
new file mode 100644
index 0000000..cb32acc
--- /dev/null
+++ b/security/agent/client.go
@@ -0,0 +1,72 @@
+// Package agent provides a client for communicating with an "Agent"
+// process holding the private key for an identity.
+package agent
+
+import (
+	"fmt"
+	"strconv"
+
+	"veyron/lib/unixfd"
+	"veyron2/context"
+	"veyron2/ipc"
+	"veyron2/naming"
+	"veyron2/security"
+	"veyron2/security/wire"
+)
+
+// EndpointVarName is the name of the environment variable containing
+// the endpoint for talking to the agent.
+const EndpointVarName = "VEYRON_AGENT_ENDPOINT"
+
+type client struct {
+	client ipc.Client
+	name   string
+	ctx    context.T
+	key    security.PublicKey
+}
+
+func (c *client) call(name string, result interface{}, args ...interface{}) (err error) {
+	var call ipc.Call
+	if call, err = c.client.StartCall(c.ctx, c.name, name, args); err == nil {
+		if ierr := call.Finish(result, &err); ierr != nil {
+			err = ierr
+		}
+	}
+	return
+}
+
+// NewAgentSigner returns a Signer using the PrivateKey held in a remote agent process.
+// 'ctx' should not have a deadline, and should never be cancelled.
+func NewAgentSigner(c ipc.Client, endpoint string, ctx context.T) (security.Signer, error) {
+	agent := &client{c, naming.JoinAddressName(endpoint, ""), ctx, nil}
+	if err := agent.fetchPublicKey(); err != nil {
+		return nil, err
+	}
+	return agent, nil
+}
+
+func (c *client) fetchPublicKey() (err error) {
+	var key wire.PublicKey
+	if err = c.call("PublicKey", &key); err != nil {
+		return
+	}
+	c.key, err = key.Decode()
+	return
+}
+
+func (c *client) PublicKey() security.PublicKey {
+	return c.key
+}
+
+func (c *client) Sign(purpose, message []byte) (sig security.Signature, err error) {
+	if purpose != nil {
+		err = fmt.Errorf("purpose not supported")
+		return
+	}
+	err = c.call("Sign", &sig, message)
+	return
+}
+
+func CreateAgentEndpoint(fd int) string {
+	return naming.FormatEndpoint(unixfd.Network, strconv.Itoa(fd))
+}
diff --git a/security/agent/server/server.go b/security/agent/server/server.go
new file mode 100644
index 0000000..71578d7
--- /dev/null
+++ b/security/agent/server/server.go
@@ -0,0 +1,65 @@
+// Package server provides a server which keeps a private key in memory
+// and allows clients to use the key for signing.
+package server
+
+import (
+	"os"
+	"veyron/lib/unixfd"
+	"veyron2"
+	"veyron2/ipc"
+	"veyron2/security"
+	"veyron2/security/wire"
+)
+
+type Signer interface {
+	Sign(message []byte) (security.Signature, error)
+	PublicKey() security.PublicKey
+}
+
+type agentd struct {
+	signer Signer
+}
+
+// RunAnonymousAgent starts the agent server listening on an
+// anonymous unix domain socket. It will respond to SignatureRequests
+// using 'signer'.
+// The returned 'client' is typically passed via cmd.ExtraFiles to a child process.
+func RunAnonymousAgent(runtime veyron2.Runtime, signer Signer) (client *os.File, err error) {
+	// VCSecurityNone is safe since we're using anonymous unix sockets.
+	// Only our child process can possibly communicate on the socket.
+	s, err := runtime.NewServer(veyron2.VCSecurityNone)
+	if err != nil {
+		return nil, err
+	}
+
+	socks, err := unixfd.Socketpair()
+	server_sock := socks[0]
+	client_sock := make(chan *os.File, 1)
+	client_sock <- socks[1]
+	close(client_sock)
+	defer server_sock.Close()
+	defer func() {
+		if sock, ok := <-client_sock; ok {
+			sock.Close()
+		}
+	}()
+
+	serverAgent := NewServerAgent(agentd{signer})
+	addr := unixfd.Addr(server_sock.Fd())
+	if _, err = s.Listen(addr.Network(), addr.String()); err != nil {
+		return
+	}
+	if err = s.Serve("", ipc.LeafDispatcher(serverAgent, nil)); err != nil {
+		return
+	}
+	return <-client_sock, nil
+}
+
+func (a agentd) Sign(_ ipc.ServerContext, message []byte) (security.Signature, error) {
+	return a.signer.Sign(message)
+}
+
+func (a agentd) PublicKey(ipc.ServerContext) (key wire.PublicKey, err error) {
+	err = key.Encode(a.signer.PublicKey())
+	return
+}
diff --git a/security/agent/server/wire.vdl b/security/agent/server/wire.vdl
new file mode 100644
index 0000000..695aad0
--- /dev/null
+++ b/security/agent/server/wire.vdl
@@ -0,0 +1,11 @@
+package server
+
+import (
+	"veyron2/security"
+	"veyron2/security/wire"
+)
+
+type Agent interface {
+	Sign(message []byte) (security.Signature, error)
+	PublicKey() (wire.PublicKey, error)
+}
diff --git a/security/agent/server/wire.vdl.go b/security/agent/server/wire.vdl.go
new file mode 100644
index 0000000..ff7e386
--- /dev/null
+++ b/security/agent/server/wire.vdl.go
@@ -0,0 +1,230 @@
+// This file was auto-generated by the veyron vdl tool.
+// Source: wire.vdl
+
+package server
+
+import (
+	"veyron2/security"
+
+	"veyron2/security/wire"
+
+	// The non-user imports are prefixed with "_gen_" to prevent collisions.
+	_gen_veyron2 "veyron2"
+	_gen_context "veyron2/context"
+	_gen_ipc "veyron2/ipc"
+	_gen_naming "veyron2/naming"
+	_gen_vdlutil "veyron2/vdl/vdlutil"
+	_gen_wiretype "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.
+const _ = _gen_wiretype.TypeIDInvalid
+
+// Agent is the interface the client binds and uses.
+// Agent_ExcludingUniversal is the interface without internal framework-added methods
+// to enable embedding without method collisions.  Not to be used directly by clients.
+type Agent_ExcludingUniversal interface {
+	Sign(ctx _gen_context.T, message []byte, opts ..._gen_ipc.CallOpt) (reply security.Signature, err error)
+	PublicKey(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply wire.PublicKey, err error)
+}
+type Agent interface {
+	_gen_ipc.UniversalServiceMethods
+	Agent_ExcludingUniversal
+}
+
+// AgentService is the interface the server implements.
+type AgentService interface {
+	Sign(context _gen_ipc.ServerContext, message []byte) (reply security.Signature, err error)
+	PublicKey(context _gen_ipc.ServerContext) (reply wire.PublicKey, err error)
+}
+
+// BindAgent returns the client stub implementing the Agent
+// interface.
+//
+// If no _gen_ipc.Client is specified, the default _gen_ipc.Client in the
+// global Runtime is used.
+func BindAgent(name string, opts ..._gen_ipc.BindOpt) (Agent, error) {
+	var client _gen_ipc.Client
+	switch len(opts) {
+	case 0:
+		// Do nothing.
+	case 1:
+		if clientOpt, ok := opts[0].(_gen_ipc.Client); opts[0] == nil || ok {
+			client = clientOpt
+		} else {
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
+		}
+	default:
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
+	}
+	stub := &clientStubAgent{defaultClient: client, name: name}
+
+	return stub, nil
+}
+
+// NewServerAgent creates a new server stub.
+//
+// It takes a regular server implementing the AgentService
+// interface, and returns a new server stub.
+func NewServerAgent(server AgentService) interface{} {
+	return &ServerStubAgent{
+		service: server,
+	}
+}
+
+// clientStubAgent implements Agent.
+type clientStubAgent struct {
+	defaultClient _gen_ipc.Client
+	name          string
+}
+
+func (__gen_c *clientStubAgent) client(ctx _gen_context.T) _gen_ipc.Client {
+	if __gen_c.defaultClient != nil {
+		return __gen_c.defaultClient
+	}
+	return _gen_veyron2.RuntimeFromContext(ctx).Client()
+}
+
+func (__gen_c *clientStubAgent) Sign(ctx _gen_context.T, message []byte, opts ..._gen_ipc.CallOpt) (reply security.Signature, err error) {
+	var call _gen_ipc.Call
+	if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Sign", []interface{}{message}, opts...); err != nil {
+		return
+	}
+	if ierr := call.Finish(&reply, &err); ierr != nil {
+		err = ierr
+	}
+	return
+}
+
+func (__gen_c *clientStubAgent) PublicKey(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply wire.PublicKey, err error) {
+	var call _gen_ipc.Call
+	if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "PublicKey", nil, opts...); err != nil {
+		return
+	}
+	if ierr := call.Finish(&reply, &err); ierr != nil {
+		err = ierr
+	}
+	return
+}
+
+func (__gen_c *clientStubAgent) UnresolveStep(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply []string, err error) {
+	var call _gen_ipc.Call
+	if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "UnresolveStep", nil, opts...); err != nil {
+		return
+	}
+	if ierr := call.Finish(&reply, &err); ierr != nil {
+		err = ierr
+	}
+	return
+}
+
+func (__gen_c *clientStubAgent) Signature(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply _gen_ipc.ServiceSignature, err error) {
+	var call _gen_ipc.Call
+	if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Signature", nil, opts...); err != nil {
+		return
+	}
+	if ierr := call.Finish(&reply, &err); ierr != nil {
+		err = ierr
+	}
+	return
+}
+
+func (__gen_c *clientStubAgent) GetMethodTags(ctx _gen_context.T, method string, opts ..._gen_ipc.CallOpt) (reply []interface{}, err error) {
+	var call _gen_ipc.Call
+	if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "GetMethodTags", []interface{}{method}, opts...); err != nil {
+		return
+	}
+	if ierr := call.Finish(&reply, &err); ierr != nil {
+		err = ierr
+	}
+	return
+}
+
+// ServerStubAgent wraps a server that implements
+// AgentService and provides an object that satisfies
+// the requirements of veyron2/ipc.ReflectInvoker.
+type ServerStubAgent struct {
+	service AgentService
+}
+
+func (__gen_s *ServerStubAgent) GetMethodTags(call _gen_ipc.ServerCall, method string) ([]interface{}, error) {
+	// TODO(bprosnitz) GetMethodTags() will be replaces with Signature().
+	// Note: This exhibits some weird behavior like returning a nil error if the method isn't found.
+	// This will change when it is replaced with Signature().
+	switch method {
+	case "Sign":
+		return []interface{}{}, nil
+	case "PublicKey":
+		return []interface{}{}, nil
+	default:
+		return nil, nil
+	}
+}
+
+func (__gen_s *ServerStubAgent) Signature(call _gen_ipc.ServerCall) (_gen_ipc.ServiceSignature, error) {
+	result := _gen_ipc.ServiceSignature{Methods: make(map[string]_gen_ipc.MethodSignature)}
+	result.Methods["PublicKey"] = _gen_ipc.MethodSignature{
+		InArgs: []_gen_ipc.MethodArgument{},
+		OutArgs: []_gen_ipc.MethodArgument{
+			{Name: "", Type: 71},
+			{Name: "", Type: 69},
+		},
+	}
+	result.Methods["Sign"] = _gen_ipc.MethodSignature{
+		InArgs: []_gen_ipc.MethodArgument{
+			{Name: "message", Type: 66},
+		},
+		OutArgs: []_gen_ipc.MethodArgument{
+			{Name: "", Type: 68},
+			{Name: "", Type: 69},
+		},
+	}
+
+	result.TypeDefs = []_gen_vdlutil.Any{
+		_gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "byte", Tags: []string(nil)}, _gen_wiretype.SliceType{Elem: 0x41, Name: "", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x3, Name: "veyron2/security.Hash", Tags: []string(nil)}, _gen_wiretype.StructType{
+			[]_gen_wiretype.FieldType{
+				_gen_wiretype.FieldType{Type: 0x42, Name: "Purpose"},
+				_gen_wiretype.FieldType{Type: 0x43, Name: "Hash"},
+				_gen_wiretype.FieldType{Type: 0x42, Name: "R"},
+				_gen_wiretype.FieldType{Type: 0x42, Name: "S"},
+			},
+			"veyron2/security.Signature", []string(nil)},
+		_gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "veyron2/security/wire.KeyCurve", Tags: []string(nil)}, _gen_wiretype.StructType{
+			[]_gen_wiretype.FieldType{
+				_gen_wiretype.FieldType{Type: 0x46, Name: "Curve"},
+				_gen_wiretype.FieldType{Type: 0x42, Name: "XY"},
+			},
+			"veyron2/security/wire.PublicKey", []string(nil)},
+	}
+
+	return result, nil
+}
+
+func (__gen_s *ServerStubAgent) UnresolveStep(call _gen_ipc.ServerCall) (reply []string, err error) {
+	if unresolver, ok := __gen_s.service.(_gen_ipc.Unresolver); ok {
+		return unresolver.UnresolveStep(call)
+	}
+	if call.Server() == nil {
+		return
+	}
+	var published []string
+	if published, err = call.Server().Published(); err != nil || published == nil {
+		return
+	}
+	reply = make([]string, len(published))
+	for i, p := range published {
+		reply[i] = _gen_naming.Join(p, call.Name())
+	}
+	return
+}
+
+func (__gen_s *ServerStubAgent) Sign(call _gen_ipc.ServerCall, message []byte) (reply security.Signature, err error) {
+	reply, err = __gen_s.service.Sign(call, message)
+	return
+}
+
+func (__gen_s *ServerStubAgent) PublicKey(call _gen_ipc.ServerCall) (reply wire.PublicKey, err error) {
+	reply, err = __gen_s.service.PublicKey(call)
+	return
+}
diff --git a/security/agent/test.sh b/security/agent/test.sh
new file mode 100755
index 0000000..c932314
--- /dev/null
+++ b/security/agent/test.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+# Test running an application using the agent.
+
+source "${VEYRON_ROOT}/environment/scripts/lib/shell_test.sh"
+
+build() {
+  local GO="${REPO_ROOT}/scripts/build/go"
+  "${GO}" build veyron/security/agent/agentd || shell_test::fail "line ${LINENO}: failed to build agentd"
+  "${GO}" build -o pingpong veyron/security/agent/test || shell_test::fail "line ${LINENO}: failed to build pingpong"
+}
+
+main() {
+  local workdir="$(shell::tmp_dir)"
+  cd "${workdir}"
+  build
+
+  shell_test::setup_server_test
+  shell_test::start_server ./pingpong --server
+  export VEYRON_PUBLICID_STORE="$(shell::tmp_dir)"
+  echo VEYRON_PUBLICID_STORE=$VEYRON_PUBLICID_STORE
+  ls $VEYRON_PUBLICID_STORE
+  ./agentd --v=4 ./pingpong || shell_test::fail "line ${LINENO}: ping"
+  local identity=$(./agentd bash -c 'echo $VEYRON_IDENTITY')
+  if [[ -n "${identity}" ]]; then
+      shel_test::fail "line ${LINENO}: identity preserved"
+  fi
+
+  shell_test::pass
+}
+
+main "$@"
diff --git a/security/agent/test/main.go b/security/agent/test/main.go
new file mode 100644
index 0000000..0d554fe
--- /dev/null
+++ b/security/agent/test/main.go
@@ -0,0 +1,70 @@
+package main
+
+import (
+	"flag"
+	"fmt"
+
+	"veyron/lib/signals"
+	sflag "veyron/security/flag"
+	"veyron2/ipc"
+	"veyron2/rt"
+)
+
+var runServer = flag.Bool("server", false, "Whether to run in server mode")
+
+type pongd struct{}
+
+func (f *pongd) Ping(_ ipc.ServerContext, message string) (result string, err error) {
+	return "pong", nil
+}
+
+func clientMain() {
+	runtime := rt.Init()
+	log := runtime.Logger()
+	log.Info("Pinging...")
+
+	s, err := BindPingPong("pingpong")
+	if err != nil {
+		log.Fatal("error binding to server: ", err)
+	}
+
+	pong, err := s.Ping(runtime.NewContext(), "ping")
+	if err != nil {
+		log.Fatal("error pinging: ", err)
+	}
+	fmt.Println(pong)
+}
+
+func serverMain() {
+	r := rt.Init()
+	log := r.Logger()
+	s, err := r.NewServer()
+	if err != nil {
+		log.Fatal("failure creating server: ", err)
+	}
+	log.Info("Waiting for ping")
+
+	serverPong := NewServerPingPong(&pongd{})
+
+	if endpoint, err := s.Listen("tcp", "127.0.0.1:0"); err == nil {
+		fmt.Printf("Listening at: %v\n", endpoint)
+	} else {
+		log.Fatal("error listening to service: ", err)
+	}
+
+	if err := s.Serve("pingpong", ipc.LeafDispatcher(serverPong, sflag.NewAuthorizerOrDie())); err != nil {
+		log.Fatal("error serving service: ", err)
+	}
+
+	// Wait forever.
+	<-signals.ShutdownOnSignals()
+}
+
+func main() {
+	flag.Parse()
+	if *runServer {
+		serverMain()
+	} else {
+		clientMain()
+	}
+}
diff --git a/security/agent/test/wire.vdl b/security/agent/test/wire.vdl
new file mode 100644
index 0000000..0fc2ed4
--- /dev/null
+++ b/security/agent/test/wire.vdl
@@ -0,0 +1,6 @@
+package main
+
+// Simple service used in the agent tests.
+type PingPong interface {
+	Ping(message string) (string, error)
+}
diff --git a/security/agent/test/wire.vdl.go b/security/agent/test/wire.vdl.go
new file mode 100644
index 0000000..87378b1
--- /dev/null
+++ b/security/agent/test/wire.vdl.go
@@ -0,0 +1,186 @@
+// This file was auto-generated by the veyron vdl tool.
+// Source: wire.vdl
+
+package main
+
+import (
+	// The non-user imports are prefixed with "_gen_" to prevent collisions.
+	_gen_veyron2 "veyron2"
+	_gen_context "veyron2/context"
+	_gen_ipc "veyron2/ipc"
+	_gen_naming "veyron2/naming"
+	_gen_vdlutil "veyron2/vdl/vdlutil"
+	_gen_wiretype "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.
+const _ = _gen_wiretype.TypeIDInvalid
+
+// Simple service used in the agent tests.
+// PingPong is the interface the client binds and uses.
+// PingPong_ExcludingUniversal is the interface without internal framework-added methods
+// to enable embedding without method collisions.  Not to be used directly by clients.
+type PingPong_ExcludingUniversal interface {
+	Ping(ctx _gen_context.T, message string, opts ..._gen_ipc.CallOpt) (reply string, err error)
+}
+type PingPong interface {
+	_gen_ipc.UniversalServiceMethods
+	PingPong_ExcludingUniversal
+}
+
+// PingPongService is the interface the server implements.
+type PingPongService interface {
+	Ping(context _gen_ipc.ServerContext, message string) (reply string, err error)
+}
+
+// BindPingPong returns the client stub implementing the PingPong
+// interface.
+//
+// If no _gen_ipc.Client is specified, the default _gen_ipc.Client in the
+// global Runtime is used.
+func BindPingPong(name string, opts ..._gen_ipc.BindOpt) (PingPong, error) {
+	var client _gen_ipc.Client
+	switch len(opts) {
+	case 0:
+		// Do nothing.
+	case 1:
+		if clientOpt, ok := opts[0].(_gen_ipc.Client); opts[0] == nil || ok {
+			client = clientOpt
+		} else {
+			return nil, _gen_vdlutil.ErrUnrecognizedOption
+		}
+	default:
+		return nil, _gen_vdlutil.ErrTooManyOptionsToBind
+	}
+	stub := &clientStubPingPong{defaultClient: client, name: name}
+
+	return stub, nil
+}
+
+// NewServerPingPong creates a new server stub.
+//
+// It takes a regular server implementing the PingPongService
+// interface, and returns a new server stub.
+func NewServerPingPong(server PingPongService) interface{} {
+	return &ServerStubPingPong{
+		service: server,
+	}
+}
+
+// clientStubPingPong implements PingPong.
+type clientStubPingPong struct {
+	defaultClient _gen_ipc.Client
+	name          string
+}
+
+func (__gen_c *clientStubPingPong) client(ctx _gen_context.T) _gen_ipc.Client {
+	if __gen_c.defaultClient != nil {
+		return __gen_c.defaultClient
+	}
+	return _gen_veyron2.RuntimeFromContext(ctx).Client()
+}
+
+func (__gen_c *clientStubPingPong) Ping(ctx _gen_context.T, message string, opts ..._gen_ipc.CallOpt) (reply string, err error) {
+	var call _gen_ipc.Call
+	if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Ping", []interface{}{message}, opts...); err != nil {
+		return
+	}
+	if ierr := call.Finish(&reply, &err); ierr != nil {
+		err = ierr
+	}
+	return
+}
+
+func (__gen_c *clientStubPingPong) UnresolveStep(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply []string, err error) {
+	var call _gen_ipc.Call
+	if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "UnresolveStep", nil, opts...); err != nil {
+		return
+	}
+	if ierr := call.Finish(&reply, &err); ierr != nil {
+		err = ierr
+	}
+	return
+}
+
+func (__gen_c *clientStubPingPong) Signature(ctx _gen_context.T, opts ..._gen_ipc.CallOpt) (reply _gen_ipc.ServiceSignature, err error) {
+	var call _gen_ipc.Call
+	if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "Signature", nil, opts...); err != nil {
+		return
+	}
+	if ierr := call.Finish(&reply, &err); ierr != nil {
+		err = ierr
+	}
+	return
+}
+
+func (__gen_c *clientStubPingPong) GetMethodTags(ctx _gen_context.T, method string, opts ..._gen_ipc.CallOpt) (reply []interface{}, err error) {
+	var call _gen_ipc.Call
+	if call, err = __gen_c.client(ctx).StartCall(ctx, __gen_c.name, "GetMethodTags", []interface{}{method}, opts...); err != nil {
+		return
+	}
+	if ierr := call.Finish(&reply, &err); ierr != nil {
+		err = ierr
+	}
+	return
+}
+
+// ServerStubPingPong wraps a server that implements
+// PingPongService and provides an object that satisfies
+// the requirements of veyron2/ipc.ReflectInvoker.
+type ServerStubPingPong struct {
+	service PingPongService
+}
+
+func (__gen_s *ServerStubPingPong) GetMethodTags(call _gen_ipc.ServerCall, method string) ([]interface{}, error) {
+	// TODO(bprosnitz) GetMethodTags() will be replaces with Signature().
+	// Note: This exhibits some weird behavior like returning a nil error if the method isn't found.
+	// This will change when it is replaced with Signature().
+	switch method {
+	case "Ping":
+		return []interface{}{}, nil
+	default:
+		return nil, nil
+	}
+}
+
+func (__gen_s *ServerStubPingPong) Signature(call _gen_ipc.ServerCall) (_gen_ipc.ServiceSignature, error) {
+	result := _gen_ipc.ServiceSignature{Methods: make(map[string]_gen_ipc.MethodSignature)}
+	result.Methods["Ping"] = _gen_ipc.MethodSignature{
+		InArgs: []_gen_ipc.MethodArgument{
+			{Name: "message", Type: 3},
+		},
+		OutArgs: []_gen_ipc.MethodArgument{
+			{Name: "", Type: 3},
+			{Name: "", Type: 65},
+		},
+	}
+
+	result.TypeDefs = []_gen_vdlutil.Any{
+		_gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
+
+	return result, nil
+}
+
+func (__gen_s *ServerStubPingPong) UnresolveStep(call _gen_ipc.ServerCall) (reply []string, err error) {
+	if unresolver, ok := __gen_s.service.(_gen_ipc.Unresolver); ok {
+		return unresolver.UnresolveStep(call)
+	}
+	if call.Server() == nil {
+		return
+	}
+	var published []string
+	if published, err = call.Server().Published(); err != nil || published == nil {
+		return
+	}
+	reply = make([]string, len(published))
+	for i, p := range published {
+		reply[i] = _gen_naming.Join(p, call.Name())
+	}
+	return
+}
+
+func (__gen_s *ServerStubPingPong) Ping(call _gen_ipc.ServerCall, message string) (reply string, err error) {
+	reply, err = __gen_s.service.Ping(call, message)
+	return
+}
diff --git a/services/mgmt/application/applicationd/test.sh b/services/mgmt/application/applicationd/test.sh
index 3f7206a..3b1a56f 100755
--- a/services/mgmt/application/applicationd/test.sh
+++ b/services/mgmt/application/applicationd/test.sh
@@ -9,7 +9,7 @@
 source "${VEYRON_ROOT}/environment/scripts/lib/shell_test.sh"
 
 build() {
-  local -r GO="${REPO_ROOT}/scripts/build/go"
+  local -r GO="${VEYRON_ROOT}/veyron/scripts/build/go"
   "${GO}" build veyron/services/mgmt/application/applicationd || shell_test::fail "line ${LINENO}: failed to build 'applicationd'"
   "${GO}" build veyron/tools/application || shell_test::fail "line ${LINENO}: failed to build 'application'"
 }
diff --git a/services/mgmt/binary/binaryd/test.sh b/services/mgmt/binary/binaryd/test.sh
index 3763245..8252e36 100755
--- a/services/mgmt/binary/binaryd/test.sh
+++ b/services/mgmt/binary/binaryd/test.sh
@@ -9,7 +9,7 @@
 source "${VEYRON_ROOT}/environment/scripts/lib/shell_test.sh"
 
 build() {
-  local -r GO="${REPO_ROOT}/scripts/build/go"
+  local -r GO="${VEYRON_ROOT}/veyron/scripts/build/go"
   "${GO}" build veyron/services/mgmt/binary/binaryd || shell_test::fail "line ${LINENO}: failed to build 'binaryd'"
   "${GO}" build veyron/tools/binary || shell_test::fail "line ${LINENO}: failed to build 'binary'"
 }
diff --git a/services/mgmt/build/buildd/test.sh b/services/mgmt/build/buildd/test.sh
index 0cfce9b..68906d5 100755
--- a/services/mgmt/build/buildd/test.sh
+++ b/services/mgmt/build/buildd/test.sh
@@ -17,7 +17,7 @@
 source "${VEYRON_ROOT}/environment/scripts/lib/shell_test.sh"
 
 build() {
-  local -r GO="${REPO_ROOT}/scripts/build/go"
+  local -r GO="${VEYRON_ROOT}/veyron/scripts/build/go"
   "${GO}" build veyron/services/mgmt/build/buildd || shell_test::fail "line ${LINENO}: failed to build 'buildd'"
   "${GO}" build veyron/tools/build || shell_test::fail "line ${LINENO}: failed to build 'build'"
 }
diff --git a/services/mgmt/profile/profiled/test.sh b/services/mgmt/profile/profiled/test.sh
index 48c87fe..eccf535 100755
--- a/services/mgmt/profile/profiled/test.sh
+++ b/services/mgmt/profile/profiled/test.sh
@@ -10,7 +10,7 @@
 source "${VEYRON_ROOT}/environment/scripts/lib/shell_test.sh"
 
 build() {
-  local -r GO="${REPO_ROOT}/scripts/build/go"
+  local -r GO="${VEYRON_ROOT}/veyron/scripts/build/go"
   "${GO}" build veyron/services/mgmt/profile/profiled || shell_test::fail "line ${LINENO}: failed to build 'profiled'"
   "${GO}" build veyron/tools/profile || shell_test::fail "line ${LINENO}: failed to build 'profile'"
 }
diff --git a/services/mounttable/mounttabled/test.sh b/services/mounttable/mounttabled/test.sh
index 0f447e4..c0c60d1 100755
--- a/services/mounttable/mounttabled/test.sh
+++ b/services/mounttable/mounttabled/test.sh
@@ -12,7 +12,7 @@
 source "${VEYRON_ROOT}/environment/scripts/lib/shell_test.sh"
 
 build() {
-  local -r GO="${REPO_ROOT}/scripts/build/go"
+  local -r GO="${VEYRON_ROOT}/veyron/scripts/build/go"
   "${GO}" build veyron/services/mounttable/mounttabled || shell_test::fail "line ${LINENO}: failed to build mounttabled"
   "${GO}" build veyron/tools/mounttable || shell_test::fail "line ${LINENO}: failed to build mounttable"
 }
diff --git a/services/wsprd/app/app.go b/services/wsprd/app/app.go
index 7c970d3..1323ec8 100644
--- a/services/wsprd/app/app.go
+++ b/services/wsprd/app/app.go
@@ -5,6 +5,7 @@
 import (
 	"bytes"
 	"encoding/json"
+	"flag"
 	"fmt"
 	"io"
 	"sync"
@@ -28,6 +29,19 @@
 	wiretype_build "veyron2/wiretype/build"
 )
 
+// TODO(bjornick,nlacasse): Remove the retryTimeout flag once we able
+// to pass it in from javascript. For now all RPCs have the same
+// retryTimeout, set by command line flag.
+var retryTimeoutOpt ipc.CallOpt
+
+func init() {
+	// TODO(bjornick,nlacasse): Remove the retryTimeout flag once we able
+	// to pass it in from javascript. For now all RPCs have the same
+	// retryTimeout, set by command line flag.
+	retryTimeout := flag.Int("retry-timeout", 0, "Duration in seconds to retry starting an RPC call. 0 means never retry.")
+	retryTimeoutOpt = veyron2.RetryTimeoutOpt(time.Duration(*retryTimeout) * time.Second)
+}
+
 // Temporary holder of RPC so that we can store the unprocessed args.
 type veyronTempRPC struct {
 	Name        string
@@ -201,10 +215,7 @@
 		return nil, verror.BadArgf("no client created")
 	}
 	methodName := lib.UppercaseFirstCharacter(msg.Method)
-	// TODO(bjornick): Remove the retry option once we able to pass it in
-	// from javascript.  If we don't have this, then trying to make an
-	// rpc to unknown name will hang.
-	clientCall, err := c.client.StartCall(ctx, msg.Name, methodName, msg.InArgs, veyron2.RetryTimeoutOpt(0))
+	clientCall, err := c.client.StartCall(ctx, msg.Name, methodName, msg.InArgs, retryTimeoutOpt)
 	if err != nil {
 		return nil, fmt.Errorf("error starting call (name: %v, method: %v, args: %v): %v", msg.Name, methodName, msg.InArgs, err)
 	}
@@ -482,7 +493,7 @@
 	}
 
 	// Fetch and adapt signature from the SignatureManager
-	sig, err := c.signatureManager.Signature(ctx, tempMsg.Name, c.client)
+	sig, err := c.signatureManager.Signature(ctx, tempMsg.Name, c.client, retryTimeoutOpt)
 	if err != nil {
 		return nil, nil, verror.Internalf("error getting service signature for %s: %v", tempMsg.Name, err)
 	}
diff --git a/services/wsprd/lib/signature_manager.go b/services/wsprd/lib/signature_manager.go
index 23d5e87..b31d4df 100644
--- a/services/wsprd/lib/signature_manager.go
+++ b/services/wsprd/lib/signature_manager.go
@@ -4,13 +4,12 @@
 	"sync"
 	"time"
 
-	"veyron2"
 	"veyron2/context"
 	"veyron2/ipc"
 )
 
 type SignatureManager interface {
-	Signature(ctx context.T, name string, client ipc.Client) (*ipc.ServiceSignature, error)
+	Signature(ctx context.T, name string, client ipc.Client, opts ...ipc.CallOpt) (*ipc.ServiceSignature, error)
 }
 
 // signatureManager can be used to discover the signature of a remote service
@@ -46,7 +45,7 @@
 
 // signature uses the given client to fetch the signature for the given service name.
 // It locks until it fetches the service signature from the remote server, if not a cache hit.
-func (sm *signatureManager) Signature(ctx context.T, name string, client ipc.Client) (*ipc.ServiceSignature, error) {
+func (sm *signatureManager) Signature(ctx context.T, name string, client ipc.Client, opts ...ipc.CallOpt) (*ipc.ServiceSignature, error) {
 	sm.Lock()
 	defer sm.Unlock()
 
@@ -56,10 +55,7 @@
 	}
 
 	// cache expired or not found, fetch it from the remote server
-	// TODO(bjornick): Remove the retry option once we able to pass it in
-	// from javascript.  If we don't have this, then trying to make an
-	// rpc to unknown name will hang.
-	signatureCall, err := client.StartCall(ctx, name, "Signature", []interface{}{}, veyron2.RetryTimeoutOpt(0))
+	signatureCall, err := client.StartCall(ctx, name, "Signature", []interface{}{}, opts...)
 	if err != nil {
 		return nil, err
 	}
diff --git a/tools/identity/test.sh b/tools/identity/test.sh
index e5b4277..30e6ecc 100755
--- a/tools/identity/test.sh
+++ b/tools/identity/test.sh
@@ -11,7 +11,7 @@
 main() {
   # Build binaries.
   cd "${TMPDIR}"
-  local -r GO="${REPO_ROOT}/scripts/build/go"
+  local -r GO="${VEYRON_ROOT}/veyron/scripts/build/go"
   "${GO}" build veyron/tools/identity || shell_test::fail "line ${LINENO}: failed to build identity"
 
   ./identity print >/dev/null || shell_test::fail "line ${LINENO}: print failed"
diff --git a/tools/playground/.gitignore b/tools/playground/.gitignore
new file mode 100644
index 0000000..a25285a
--- /dev/null
+++ b/tools/playground/.gitignore
@@ -0,0 +1 @@
+builder/netrc
diff --git a/tools/playground/builder/netrc b/tools/playground/builder/netrc
deleted file mode 100644
index 2cb442c..0000000
--- a/tools/playground/builder/netrc
+++ /dev/null
@@ -1,2 +0,0 @@
-machine veyron.googlesource.com login git-nlacasse.google.com password 1/jK0LNfz-nCtEoI2zixqeuGJww3CIlfN_vY31eVDRMck
-machine veyron-review.googlesource.com login git-nlacasse.google.com password 1/jK0LNfz-nCtEoI2zixqeuGJww3CIlfN_vY31eVDRMck
diff --git a/tools/playground/builder/services.go b/tools/playground/builder/services.go
index ded83f9..2ad1b3a 100644
--- a/tools/playground/builder/services.go
+++ b/tools/playground/builder/services.go
@@ -6,19 +6,42 @@
 	"fmt"
 	"io"
 	"log"
+	"math/rand"
 	"os"
 	"path"
 	"regexp"
 	"strconv"
+	"syscall"
 	"time"
 )
 
 var (
-	proxyPort    = 1234
-	proxyName    = "proxy"
-	wsprBasePort = 1235
+	proxyName = "proxy"
 )
 
+// Note: This was copied from veyron/go/src/veyron/tools/findunusedport.
+// I would like to be able to import that package directly, but it defines a
+// main(), so can't be imported.  An alternative solution would be to call the
+// 'findunusedport' binary, but that would require starting another process and
+// parsing the output.  It seemed simpler to just copy the function here.
+func findUnusedPort() (int, error) {
+	rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
+	for i := 0; i < 1000; i++ {
+		port := 1024 + rnd.Int31n(64512)
+		fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
+		if err != nil {
+			continue
+		}
+		sa := &syscall.SockaddrInet4{Port: int(port)}
+		if err := syscall.Bind(fd, sa); err != nil {
+			continue
+		}
+		syscall.Close(fd)
+		return int(port), nil
+	}
+	return 0, fmt.Errorf("Can't find unused port.")
+}
+
 // startMount starts a mounttabled process, and sets the NAMESPACE_ROOT env
 // variable to the mounttable's location.  We run one mounttabled process for
 // the entire environment.
@@ -60,7 +83,11 @@
 // startProxy starts a proxyd process.  We run one proxyd process for the
 // entire environment.
 func startProxy() (proc *os.Process, err error) {
-	cmd := makeCmdJsonEvent("", "proxyd", "-name="+proxyName, "-address=:"+strconv.Itoa(proxyPort))
+	port, err := findUnusedPort()
+	if err != nil {
+		return nil, err
+	}
+	cmd := makeCmdJsonEvent("", "proxyd", "-name="+proxyName, "-address=localhost:"+strconv.Itoa(port))
 	err = cmd.Start()
 	if err != nil {
 		return nil, err
@@ -69,15 +96,22 @@
 }
 
 // startWspr starts a wsprd process. We run one wsprd process for each
-// javascript file being run. The 'index' argument is used to pick a distinct
-// port for each wsprd process.
+// javascript file being run.
 func startWspr(f *codeFile) (proc *os.Process, port int, err error) {
-	port = wsprBasePort + f.index
+	port, err = findUnusedPort()
+	if err != nil {
+		return nil, port, err
+	}
 	cmd := makeCmdJsonEvent(f.Name,
 		"wsprd",
 		"-v=-1",
 		"-vproxy="+proxyName,
 		"-port="+strconv.Itoa(port),
+		// Retry starting RPC calls for 3 seconds.
+		// TODO(nlacasse): Remove this when javascript can tell wspr
+		// how long to retry for.  Right now its a global setting in
+		// wspr.
+		"-retry-timeout=3",
 		// The identd server won't be used, so pass a fake name.
 		"-identd=/unused")
 
diff --git a/tools/playground/builder/vbuild.go b/tools/playground/builder/vbuild.go
index cc9188e..df63c38 100644
--- a/tools/playground/builder/vbuild.go
+++ b/tools/playground/builder/vbuild.go
@@ -25,7 +25,7 @@
 	"veyron/tools/playground/event"
 )
 
-const RUN_TIMEOUT = time.Second
+const runTimeout = 3 * time.Second
 
 var (
 	verbose = flag.Bool("v", false, "Verbose mode")
@@ -153,7 +153,7 @@
 		log.Fatal(err)
 	}
 
-	mt, err := startMount(RUN_TIMEOUT)
+	mt, err := startMount(runTimeout)
 	if err != nil {
 		log.Fatal(err)
 	}
@@ -222,12 +222,13 @@
 		}
 	}
 
-	timeout := time.After(RUN_TIMEOUT)
+	timeout := time.After(runTimeout)
 
 	for running > 0 {
 		select {
 		case <-timeout:
 			writeEvent("", "Playground exceeded deadline.", "stderr")
+			stopAll(files)
 		case status := <-exit:
 			if status.err == nil {
 				writeEvent(status.name, "Exited.", "stdout")
@@ -376,6 +377,17 @@
 	cmd := exec.Command(prog, args...)
 	cmd.Env = os.Environ()
 
+	// TODO(nlacasse): There is a bug in this code which results in
+	//   "read |0: bad file descriptor".
+	// The error seems to be caused by our use of cmd.StdoutPipe/StderrPipe
+	// and cmd.Wait.  In particular, we seem to be calling Wait after the
+	// pipes have been closed.
+	// See: http://stackoverflow.com/questions/20134095/why-do-i-get-bad-file-descriptor-in-this-go-program-using-stderr-and-ioutil-re
+	// and https://code.google.com/p/go/issues/detail?id=2266
+	//
+	// One solution is to wrap cmd.Start/Run, so that wait is never called
+	// before the pipes are closed.
+
 	stdout, err := cmd.StdoutPipe()
 	if err != nil {
 		log.Fatal(err)
diff --git a/tools/playground/test.sh b/tools/playground/test.sh
index ccf8d3c..90d4e8f 100755
--- a/tools/playground/test.sh
+++ b/tools/playground/test.sh
@@ -4,8 +4,20 @@
 
 source "${VEYRON_ROOT}/environment/scripts/lib/shell_test.sh"
 
+install_veyron_js() {
+  # This installs the veyron.js library, and makes it accessable to javascript
+  # files in the veyron playground test folder under the module name 'veyron'.
+  #
+  # TODO(nlacasse): Once veyron.js is installed in a public npm registry, this
+  # should be replaced with just "npm install veyron".
+  pushd "${VEYRON_ROOT}/veyron.js"
+  "${VEYRON_ROOT}/environment/cout/node/bin/npm" link
+  popd
+  "${VEYRON_ROOT}/environment/cout/node/bin/npm" link veyron
+}
+
 build() {
-  local -r GO="${REPO_ROOT}/scripts/build/go"
+  local -r GO="${VEYRON_ROOT}/veyron/scripts/build/go"
   "${GO}" build veyron/tools/identity || shell_test::fail "line ${LINENO}: failed to build 'identity'"
   "${GO}" build veyron/services/proxy/proxyd || shell_test::fail "line ${LINENO}: failed to build 'proxyd'"
   "${GO}" build veyron/services/mounttable/mounttabled || shell_test::fail "line ${LINENO}: failed to build 'mounttabled'"
@@ -35,10 +47,11 @@
 main() {
   cd $(shell::tmp_dir)
   build
+  install_veyron_js
 
-  local -r DIR="${REPO_ROOT}/go/src/veyron/tools/playground/testdata"
+  local -r DIR="${VEYRON_ROOT}/veyron/go/src/veyron/tools/playground/testdata"
 
-  export GOPATH="$(pwd)":$VEYRON_ROOT/veyron/go
+  export GOPATH="$(pwd)":"${VEYRON_ROOT}/veyron/go"
   export PATH="$(pwd):$PATH"
 
   # Test without identities