Merge "ref: Make principal tool print "EXPIRED" in dumpblessings."
diff --git a/cmd/servicerunner/main.go b/cmd/servicerunner/main.go
index 728caa7..d08ae2b 100644
--- a/cmd/servicerunner/main.go
+++ b/cmd/servicerunner/main.go
@@ -128,7 +128,7 @@
 
 	lspec := v23.GetListenSpec(ctx)
 	lspec.Addrs = rpc.ListenAddrs{{"ws", "127.0.0.1:0"}}
-	proxyShutdown, proxyEndpoint, err := profiles.NewProxy(ctx, lspec, security.AllowEveryone(), "test/proxy")
+	proxyShutdown, proxyEndpoint, err := generic.NewProxy(ctx, lspec, security.AllowEveryone(), "test/proxy")
 	defer proxyShutdown()
 	vars["PROXY_NAME"] = proxyEndpoint.Name()
 
diff --git a/runtime/doc.go b/runtime/doc.go
index 327c5b9..c296404 100644
--- a/runtime/doc.go
+++ b/runtime/doc.go
@@ -2,23 +2,24 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Package profiles and its subdirectories provide implementations of the
-// Vanadium runtime for different runtime environments.  Each subdirectory is a
-// package that implements the v23.Profile function.
+// Package runtime and its subdirectories provide implementations of the
+// Vanadium runtime for different runtime environments.
 //
-// Profiles register themselves by calling v.io/v23/rt.RegisterProfile in an
-// init function.  Users choose a particular profile implementation by importing
-// the appropriate package in their main package.  It is an error to import more
-// than one profile, and the registration mechanism will panic if this is
-// attempted.  Commonly used functionality and pre-canned profiles are in
-// profiles/internal.
+// Each subdirectory of the runtime/factories package is a package that
+// implements the v23.RuntimeFactory function.
 //
-// This top level directory contains a 'generic' Profile and utility routines
-// used by other Profiles. It should be imported whenever possible and
-// particularly by tests.
+// runtime/internal has common functionality use in runtime/factories.
 //
-// The 'roaming' Profile adds operating system support for varied network
+// RuntimeFactories register themselves by calling v.io/v23/rt.RegisterRuntimeFactory
+// in an init function.  Users choose a particular RuntimeFactory implementation
+// by importing the appropriate package in their main package.  It is an error
+// to import more than one RuntimeFactory, and the registration mechanism will
+// panic if this is attempted.
+//
+// The 'roaming' RuntimeFactory adds operating system support for varied network
 // configurations and in particular dhcp. It should be used by any application
-// that may 'roam' or any may be behind a 1-1 NAT. The 'static' profile
-// does not provide dhcp support, but is otherwise like the roaming profile.
-package profiles
+// that may 'roam' or be behind a 1-1 NAT.
+//
+// The 'static' RuntimeFactory does not provide dhcp support, but is otherwise
+// like the 'roaming' RuntimeFactory.
+package runtime
diff --git a/runtime/factories/chrome/chromeinit.go b/runtime/factories/chrome/chrome.go
similarity index 84%
rename from runtime/factories/chrome/chromeinit.go
rename to runtime/factories/chrome/chrome.go
index 45032c9..5108bbe 100644
--- a/runtime/factories/chrome/chromeinit.go
+++ b/runtime/factories/chrome/chrome.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Package chrome implements a profile for use within Chrome, in particular for
-// use by Chrome extensions.
+// Package chrome implements a RuntimeFactory for use within Chrome, in
+// particular for use by Chrome extensions.
 package chrome
 
 import (
@@ -25,7 +25,7 @@
 var commonFlags *flags.Flags
 
 func init() {
-	v23.RegisterProfile(Init)
+	v23.RegisterRuntimeFactory(Init)
 	rpc.RegisterUnknownProtocol("wsh", websocket.Dial, websocket.Resolve, websocket.Listener)
 	commonFlags = flags.CreateAndRegister(flag.CommandLine, flags.Runtime)
 }
@@ -41,6 +41,6 @@
 	if err != nil {
 		return nil, nil, shutdown, err
 	}
-	vlog.Log.VI(1).Infof("Initializing chrome profile.")
+	vlog.Log.VI(1).Infof("Initializing chrome RuntimeFactory.")
 	return runtime, ctx, shutdown, nil
 }
diff --git a/runtime/factories/fake/fake.go b/runtime/factories/fake/fake.go
index 943cb11..35b055a 100644
--- a/runtime/factories/fake/fake.go
+++ b/runtime/factories/fake/fake.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Package fake implements a fake profile, useful in tests for mocking out
-// certain components.
+// Package fake implements a fake RuntimeFactory, useful in tests for mocking
+// out certain components.
 package fake
 
 // TODO(mattr): Make a more complete, but still fake, implementation.
@@ -31,7 +31,7 @@
 )
 
 func init() {
-	v23.RegisterProfile(Init)
+	v23.RegisterRuntimeFactory(Init)
 	rpc.RegisterUnknownProtocol("wsh", websocket.HybridDial, websocket.HybridResolve, websocket.HybridListener)
 }
 
diff --git a/runtime/factories/fake/fake_test.go b/runtime/factories/fake/fake_test.go
index 07f1732..7aef3a8 100644
--- a/runtime/factories/fake/fake_test.go
+++ b/runtime/factories/fake/fake_test.go
@@ -12,7 +12,7 @@
 	_ "v.io/x/ref/runtime/factories/fake"
 )
 
-// Ensure that the fake profile can be used to initialize a fake runtime.
+// Ensure that the fake RuntimeFactory can be used to initialize a fake runtime.
 func TestInit(t *testing.T) {
 	ctx, shutdown := v23.Init()
 	defer shutdown()
diff --git a/runtime/factories/gce/init.go b/runtime/factories/gce/gce.go
similarity index 86%
rename from runtime/factories/gce/init.go
rename to runtime/factories/gce/gce.go
index cd39339..9fe80da 100644
--- a/runtime/factories/gce/init.go
+++ b/runtime/factories/gce/gce.go
@@ -4,8 +4,8 @@
 
 // +build linux
 
-// Package gce implements a profile for binaries that only run on Google Compute
-// Engine.
+// Package gce implements a RuntimeFactory for binaries that only run on Google
+// Compute Engine (GCE).
 package gce
 
 import (
@@ -33,7 +33,7 @@
 var commonFlags *flags.Flags
 
 func init() {
-	v23.RegisterProfile(Init)
+	v23.RegisterRuntimeFactory(Init)
 	rpc.RegisterUnknownProtocol("wsh", websocket.HybridDial, websocket.HybridResolve, websocket.HybridListener)
 	commonFlags = flags.CreateAndRegister(flag.CommandLine, flags.Runtime, flags.Listen)
 }
@@ -68,12 +68,12 @@
 		return nil, nil, shutdown, err
 	}
 
-	vlog.Log.VI(1).Infof("Initializing GCE profile.")
+	vlog.Log.VI(1).Infof("Initializing GCE RuntimeFactory.")
 
-	profileShutdown := func() {
+	runtimeFactoryShutdown := func() {
 		ac.Shutdown()
 		shutdown()
 	}
 
-	return runtime, ctx, profileShutdown, nil
+	return runtime, ctx, runtimeFactoryShutdown, nil
 }
diff --git a/runtime/factories/generic/genericinit.go b/runtime/factories/generic/generic.go
similarity index 81%
rename from runtime/factories/generic/genericinit.go
rename to runtime/factories/generic/generic.go
index 0b40d36..9de2b92 100644
--- a/runtime/factories/generic/genericinit.go
+++ b/runtime/factories/generic/generic.go
@@ -2,7 +2,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package profiles
+// Package generic implements a RuntimeFactory that is useful in tests. It
+// prefers listening on localhost addresses.
+package generic
 
 import (
 	"flag"
@@ -25,7 +27,7 @@
 var commonFlags *flags.Flags
 
 func init() {
-	v23.RegisterProfile(Init)
+	v23.RegisterRuntimeFactory(Init)
 	rpc.RegisterUnknownProtocol("wsh", websocket.HybridDial, websocket.HybridResolve, websocket.HybridListener)
 	flags.SetDefaultHostPort(":0")
 	commonFlags = flags.CreateAndRegister(flag.CommandLine, flags.Runtime, flags.Listen)
@@ -56,11 +58,11 @@
 	if err != nil {
 		return nil, nil, nil, err
 	}
-	vlog.Log.VI(1).Infof("Initializing generic profile.")
+	vlog.Log.VI(1).Infof("Initializing generic RuntimeFactory.")
 
-	profileShutdown := func() {
+	runtimeFactoryShutdown := func() {
 		ac.Shutdown()
 		shutdown()
 	}
-	return runtime, ctx, profileShutdown, nil
+	return runtime, ctx, runtimeFactoryShutdown, nil
 }
diff --git a/runtime/factories/generic/proxy.go b/runtime/factories/generic/proxy.go
index 4e3d500..862c1de 100644
--- a/runtime/factories/generic/proxy.go
+++ b/runtime/factories/generic/proxy.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package profiles
+package generic
 
 import (
 	"v.io/v23/context"
diff --git a/runtime/factories/roaming/roaminginit.go b/runtime/factories/roaming/roaming.go
similarity index 90%
rename from runtime/factories/roaming/roaminginit.go
rename to runtime/factories/roaming/roaming.go
index 00ae923..9f6c8ef 100644
--- a/runtime/factories/roaming/roaminginit.go
+++ b/runtime/factories/roaming/roaming.go
@@ -4,7 +4,7 @@
 
 // +build linux darwin
 
-// Package roaming implements a profile suitable for a variety of network
+// Package roaming implements a RuntimeFactory suitable for a variety of network
 // configurations, including 1-1 NATs, dhcp auto-configuration, and Google
 // Compute Engine.
 //
@@ -41,13 +41,13 @@
 
 const (
 	SettingsStreamName = "roaming"
-	SettingsStreamDesc = "pubsub stream used by the roaming profile"
+	SettingsStreamDesc = "pubsub stream used by the roaming RuntimeFactory"
 )
 
 var commonFlags *flags.Flags
 
 func init() {
-	v23.RegisterProfile(Init)
+	v23.RegisterRuntimeFactory(Init)
 	rpc.RegisterUnknownProtocol("wsh", websocket.HybridDial, websocket.HybridResolve, websocket.HybridListener)
 	commonFlags = flags.CreateAndRegister(flag.CommandLine, flags.Runtime, flags.Listen)
 }
@@ -72,7 +72,7 @@
 		if addr := internal.GCEPublicAddress(vlog.Log); addr != nil {
 			listenSpec.AddressChooser = func(string, []net.Addr) ([]net.Addr, error) {
 				// TODO(cnicolaou): the protocol at least should
-				// be configurable, or maybe there's a profile specific
+				// be configurable, or maybe there's a RuntimeFactory specific
 				// flag to configure both the protocol and address.
 				return []net.Addr{netstate.NewNetAddr("wsh", addr.String())}, nil
 			}
@@ -80,11 +80,11 @@
 			if err != nil {
 				return nil, nil, shutdown, err
 			}
-			profileShutdown := func() {
+			runtimeFactoryShutdown := func() {
 				ac.Shutdown()
 				shutdown()
 			}
-			return runtime, ctx, profileShutdown, nil
+			return runtime, ctx, runtimeFactoryShutdown, nil
 		}
 	}
 
@@ -93,7 +93,7 @@
 	// Create stream in Init function to avoid a race between any
 	// goroutines started here and consumers started after Init returns.
 	ch := make(chan pubsub.Setting)
-	// TODO(cnicolaou): use stop to shutdown this stream when the profile shutdowns.
+	// TODO(cnicolaou): use stop to shutdown this stream when the RuntimeFactory shutdowns.
 	stop, err := publisher.CreateStream(SettingsStreamName, SettingsStreamDesc, ch)
 	if err != nil {
 		ac.Shutdown()
@@ -124,13 +124,13 @@
 	}
 
 	go monitorNetworkSettingsX(runtime, ctx, watcher, prev, stop, cleanupCh, watcherCh, ch)
-	profileShutdown := func() {
+	runtimeFactoryShutdown := func() {
 		close(cleanupCh)
 		ac.Shutdown()
 		shutdown()
 		<-watcherCh
 	}
-	return runtime, ctx, profileShutdown, nil
+	return runtime, ctx, runtimeFactoryShutdown, nil
 }
 
 // monitorNetworkSettings will monitor network configuration changes and
diff --git a/runtime/factories/static/staticinit.go b/runtime/factories/static/static.go
similarity index 88%
rename from runtime/factories/static/staticinit.go
rename to runtime/factories/static/static.go
index de8fc33..c49bd32 100644
--- a/runtime/factories/static/staticinit.go
+++ b/runtime/factories/static/static.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Package static implements a profile for static network configurations.
+// Package static implements a RuntimeFactory for static network configurations.
 package static
 
 import (
@@ -30,7 +30,7 @@
 var commonFlags *flags.Flags
 
 func init() {
-	v23.RegisterProfile(Init)
+	v23.RegisterRuntimeFactory(Init)
 	rpc.RegisterUnknownProtocol("wsh", websocket.HybridDial, websocket.HybridResolve, websocket.HybridListener)
 	commonFlags = flags.CreateAndRegister(flag.CommandLine, flags.Runtime, flags.Listen)
 }
@@ -61,11 +61,11 @@
 			if err != nil {
 				return nil, nil, nil, err
 			}
-			profileShutdown := func() {
+			runtimeFactoryShutdown := func() {
 				ac.Shutdown()
 				shutdown()
 			}
-			return runtime, ctx, profileShutdown, nil
+			return runtime, ctx, runtimeFactoryShutdown, nil
 		}
 	}
 	listenSpec.AddressChooser = internal.IPAddressChooser
@@ -75,9 +75,9 @@
 		return nil, nil, shutdown, err
 	}
 
-	profileShutdown := func() {
+	runtimeFactoryShutdown := func() {
 		ac.Shutdown()
 		shutdown()
 	}
-	return runtime, ctx, profileShutdown, nil
+	return runtime, ctx, runtimeFactoryShutdown, nil
 }
diff --git a/services/agent/internal/server/server.go b/services/agent/internal/server/server.go
index 55e239f..893d4e7 100644
--- a/services/agent/internal/server/server.go
+++ b/services/agent/internal/server/server.go
@@ -11,12 +11,12 @@
 	"crypto/sha512"
 	"crypto/x509"
 	"encoding/base64"
+	"fmt"
 	"io"
 	"net"
 	"os"
 	"path/filepath"
 	"strconv"
-	"sync"
 
 	"v.io/v23"
 	"v.io/v23/context"
@@ -59,10 +59,8 @@
 
 type keymgr struct {
 	path       string
-	principals map[keyHandle]keyData // GUARDED_BY(Mutex)
 	passphrase []byte
 	ctx        *context.T
-	mu         sync.Mutex
 }
 
 // RunAnonymousAgent starts the agent server listening on an
@@ -90,16 +88,16 @@
 	return remote, agentlib.AgentEndpoint(remoteFd), nil
 }
 
-// RunKeyManager starts the key manager server listening on an
-// anonymous unix domain socket. It will persist principals in 'path' using 'passphrase'.
-// Typically only used by the device manager.
-// The returned 'client' is typically passed via cmd.ExtraFiles to a child process.
+// RunKeyManager starts the key manager server listening on an anonymous unix
+// domain socket. It will persist principals in 'path' using 'passphrase'.
+// The returned 'client' is typically passed via cmd.ExtraFiles to a child
+// process.
 func RunKeyManager(ctx *context.T, path string, passphrase []byte) (client *os.File, err error) {
 	if path == "" {
 		return nil, verror.New(errStoragePathRequired, nil)
 	}
 
-	mgr := &keymgr{path: path, passphrase: passphrase, principals: make(map[keyHandle]keyData), ctx: ctx}
+	mgr := &keymgr{path: path, passphrase: passphrase, ctx: ctx}
 
 	if err := os.MkdirAll(filepath.Join(mgr.path, "keys"), 0700); err != nil {
 		return nil, err
@@ -113,12 +111,13 @@
 		return nil, err
 	}
 
-	go mgr.readDMConns(local)
+	go mgr.readConns(local)
 
 	return client, nil
 }
 
-func (a keymgr) readDMConns(conn *net.UnixConn) {
+func (a *keymgr) readConns(conn *net.UnixConn) {
+	cache := make(map[keyHandle]keyData)
 	donech := a.ctx.Done()
 	if donech != nil {
 		go func() {
@@ -144,17 +143,24 @@
 			}
 		}
 		ack()
-		var data *keyData
+		var data keyData
 		if n == len(buf) {
-			data = a.readKey(buf)
+			if cached, ok := cache[buf]; ok {
+				data = cached
+			} else if data, err = a.readKey(buf); err != nil {
+				vlog.Error(err)
+				continue
+			} else {
+				cache[buf] = data
+			}
 		} else if n == 1 {
-			var handle []byte
-			if handle, data, err = a.newKey(buf[0] == 1); err != nil {
+			if buf, data, err = a.newKey(buf[0] == 1); err != nil {
 				vlog.Infof("Error creating key: %v", err)
 				unixfd.CloseUnixAddr(addr)
 				continue
 			}
-			if _, err = conn.Write(handle); err != nil {
+			cache[buf] = data
+			if _, err = conn.Write(buf[:]); err != nil {
 				vlog.Infof("Error sending key handle: %v", err)
 				unixfd.CloseUnixAddr(addr)
 				continue
@@ -164,69 +170,52 @@
 			unixfd.CloseUnixAddr(addr)
 			continue
 		}
-		conn := dial(addr)
-		if data != nil && conn != nil {
-			if err := startAgent(a.ctx, conn, data.w, data.p); err != nil {
-				vlog.Infof("error starting agent: %v", err)
-			}
+		conn, err := dial(addr)
+		if err != nil {
+			vlog.Info(err)
+			continue
+		}
+		if err := startAgent(a.ctx, conn, data.w, data.p); err != nil {
+			vlog.Infof("error starting agent: %v", err)
 		}
 	}
 }
 
-func (a *keymgr) readKey(handle keyHandle) *keyData {
-	a.mu.Lock()
-	cachedData, ok := a.principals[handle]
-	a.mu.Unlock()
-	if ok {
-		return &cachedData
-	}
+func (a *keymgr) readKey(handle keyHandle) (keyData, error) {
+	var nodata keyData
 	filename := base64.URLEncoding.EncodeToString(handle[:])
 	in, err := os.Open(filepath.Join(a.path, "keys", filename))
 	if err != nil {
-		vlog.Errorf("unable to open key file: %v", err)
-		return nil
+		return nodata, fmt.Errorf("unable to open key file: %v", err)
 	}
 	defer in.Close()
 	key, err := vsecurity.LoadPEMKey(in, a.passphrase)
 	if err != nil {
-		vlog.Errorf("unable to load key: %v", err)
-		return nil
+		return nodata, fmt.Errorf("unable to load key in %q: %v", in.Name(), err)
 	}
 	state, err := vsecurity.NewPrincipalStateSerializer(filepath.Join(a.path, "creds", filename))
 	if err != nil {
-		vlog.Errorf("unable to create persisted state serializer: %v", err)
-		return nil
+		return nodata, fmt.Errorf("unable to create persisted state serializer: %v", err)
 	}
 	principal, err := vsecurity.NewPrincipalFromSigner(security.NewInMemoryECDSASigner(key.(*ecdsa.PrivateKey)), state)
 	if err != nil {
-		vlog.Errorf("unable to load principal: %v", err)
-		return nil
+		return nodata, fmt.Errorf("unable to load principal: %v", err)
 	}
-	data := keyData{newWatchers(), principal}
-	a.mu.Lock()
-	cachedData, ok = a.principals[handle]
-	if !ok {
-		a.principals[handle] = data
-		cachedData = data
-	}
-	a.mu.Unlock()
-
-	return &cachedData
+	return keyData{newWatchers(), principal}, nil
 }
 
-func dial(addr net.Addr) *net.UnixConn {
+func dial(addr net.Addr) (*net.UnixConn, error) {
 	fd, err := strconv.ParseInt(addr.String(), 10, 32)
 	if err != nil {
-		vlog.Errorf("Invalid address %v", addr)
-		return nil
+		return nil, fmt.Errorf("invalid address: %v", addr)
 	}
 	file := os.NewFile(uintptr(fd), "client")
 	defer file.Close()
 	conn, err := net.FileConn(file)
 	if err != nil {
-		vlog.Infof("unable to create conn: %v", err)
+		return nil, fmt.Errorf("unable to create conn: %v", err)
 	}
-	return conn.(*net.UnixConn)
+	return conn.(*net.UnixConn), nil
 }
 
 func startAgent(ctx *context.T, conn *net.UnixConn, w *watchers, principal security.Principal) error {
@@ -306,47 +295,46 @@
 	return a.principal.MintDischarge(forCaveat, caveatOnDischarge, additionalCaveatsOnDischarge...)
 }
 
-func (a keymgr) newKey(in_memory bool) (id []byte, data *keyData, err error) {
+func (a *keymgr) newKey(in_memory bool) (keyHandle, keyData, error) {
+	var handle keyHandle
+	var nodata keyData
 	if a.path == "" {
-		return nil, nil, verror.New(errNotMultiKeyMode, nil)
+		return handle, nodata, verror.New(errNotMultiKeyMode, nil)
 	}
 	key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
-	keyHandle, err := keyid(key)
 	if err != nil {
-		return nil, nil, err
+		return handle, nodata, err
+	}
+	if handle, err = keyid(key); err != nil {
+		return handle, nodata, err
 	}
 	signer := security.NewInMemoryECDSASigner(key)
 	var p security.Principal
 	if in_memory {
-		p, err = vsecurity.NewPrincipalFromSigner(signer, nil)
-		if err != nil {
-			return nil, nil, err
+		if p, err = vsecurity.NewPrincipalFromSigner(signer, nil); err != nil {
+			return handle, nodata, err
 		}
 	} else {
-		filename := base64.URLEncoding.EncodeToString(keyHandle[:])
+		filename := base64.URLEncoding.EncodeToString(handle[:])
 		out, err := os.OpenFile(filepath.Join(a.path, "keys", filename), os.O_WRONLY|os.O_CREATE, 0600)
 		if err != nil {
-			return nil, nil, err
+			return handle, nodata, err
 		}
 		defer out.Close()
 		err = vsecurity.SavePEMKey(out, key, a.passphrase)
 		if err != nil {
-			return nil, nil, err
+			return handle, nodata, err
 		}
 		state, err := vsecurity.NewPrincipalStateSerializer(filepath.Join(a.path, "creds", filename))
 		if err != nil {
-			return nil, nil, err
+			return handle, nodata, err
 		}
 		p, err = vsecurity.NewPrincipalFromSigner(signer, state)
 		if err != nil {
-			return nil, nil, err
+			return handle, nodata, err
 		}
 	}
-	data = &keyData{newWatchers(), p}
-	a.mu.Lock()
-	a.principals[keyHandle] = *data
-	a.mu.Unlock()
-	return keyHandle[:], data, nil
+	return handle, keyData{newWatchers(), p}, nil
 }
 
 func keyid(key *ecdsa.PrivateKey) (handle keyHandle, err error) {
diff --git a/services/identity/internal/templates/partials.go b/services/identity/internal/templates/partials.go
index 729f15b..d2a8d11 100644
--- a/services/identity/internal/templates/partials.go
+++ b/services/identity/internal/templates/partials.go
@@ -64,7 +64,7 @@
   <div class="provider-info-section">
     <h5>Root name</h5>
     <span class="provider-address">
-      dev.v.io/root
+      {{.Self}}
     </span>
 
     <h5>Public key</h5>
diff --git a/services/wspr/internal/app/app_test.go b/services/wspr/internal/app/app_test.go
index 06fec30..991f2dc 100644
--- a/services/wspr/internal/app/app_test.go
+++ b/services/wspr/internal/app/app_test.go
@@ -313,7 +313,7 @@
 		return nil, fmt.Errorf("unable to start mounttable: %v", err)
 	}
 	proxySpec := rpc.ListenSpec{Addrs: rpc.ListenAddrs{{"tcp", "127.0.0.1:0"}}}
-	proxyShutdown, proxyEndpoint, err := profiles.NewProxy(ctx, proxySpec, security.AllowEveryone())
+	proxyShutdown, proxyEndpoint, err := generic.NewProxy(ctx, proxySpec, security.AllowEveryone())
 	if err != nil {
 		return nil, fmt.Errorf("unable to start proxy: %v", err)
 	}
diff --git a/services/wspr/internal/browspr/browspr_test.go b/services/wspr/internal/browspr/browspr_test.go
index 329e385..7f54006 100644
--- a/services/wspr/internal/browspr/browspr_test.go
+++ b/services/wspr/internal/browspr/browspr_test.go
@@ -84,7 +84,7 @@
 	defer shutdown()
 
 	proxySpec := rpc.ListenSpec{Addrs: rpc.ListenAddrs{{"tcp", "127.0.0.1:0"}}}
-	proxyShutdown, proxyEndpoint, err := profiles.NewProxy(ctx, proxySpec, security.AllowEveryone())
+	proxyShutdown, proxyEndpoint, err := generic.NewProxy(ctx, proxySpec, security.AllowEveryone())
 	if err != nil {
 		t.Fatalf("Failed to start proxy: %v", err)
 	}