Merge "Counterpart of https://vanadium-review.googlesource.com/16644"
diff --git a/cmd/principal/main.go b/cmd/principal/main.go
index 86f9293..7184c88 100644
--- a/cmd/principal/main.go
+++ b/cmd/principal/main.go
@@ -477,7 +477,7 @@
 				return fmt.Errorf("failed to set blessings %v for peers %v: %v", blessings, pattern, err)
 			}
 			if flagAddToRoots {
-				if err := p.AddToRoots(blessings); err != nil {
+				if err := security.AddToRoots(p, blessings); err != nil {
 					return fmt.Errorf("AddToRoots failed: %v", err)
 				}
 			}
@@ -523,7 +523,7 @@
 				if err != nil {
 					return fmt.Errorf("failed to decode provided blessings: %v", err)
 				}
-				if err := p.AddToRoots(blessings); err != nil {
+				if err := security.AddToRoots(p, blessings); err != nil {
 					return fmt.Errorf("AddToRoots failed: %v", err)
 				}
 				return nil
@@ -566,7 +566,7 @@
 				return fmt.Errorf("failed to set blessings %v as default: %v", blessings, err)
 			}
 			if flagAddToRoots {
-				if err := p.AddToRoots(blessings); err != nil {
+				if err := security.AddToRoots(p, blessings); err != nil {
 					return fmt.Errorf("AddToRoots failed: %v", err)
 				}
 			}
@@ -730,7 +730,7 @@
 				}
 			}
 			if flagAddToRoots {
-				if err := p.AddToRoots(blessings); err != nil {
+				if err := security.AddToRoots(p, blessings); err != nil {
 					return fmt.Errorf("AddToRoots failed: %v", err)
 				}
 			}
@@ -1239,7 +1239,7 @@
 		}
 	}
 	if flagAddToRoots {
-		if err := r.principal.AddToRoots(b); err != nil {
+		if err := security.AddToRoots(r.principal, b); err != nil {
 			return fmt.Errorf("failed to add blessings to recognized roots: %v", err)
 		}
 	}
diff --git a/cmd/vrun/vrun.go b/cmd/vrun/vrun.go
index 9c706ab..f90f385 100644
--- a/cmd/vrun/vrun.go
+++ b/cmd/vrun/vrun.go
@@ -125,7 +125,7 @@
 		vlog.Errorf("Couldn't set default client blessing")
 		return err
 	}
-	if err = p.AddToRoots(blessing); err != nil {
+	if err = security.AddToRoots(p, blessing); err != nil {
 		vlog.Errorf("Couldn't set trusted roots")
 		return err
 	}
diff --git a/cmd/vrun/vrun_v23_test.go b/cmd/vrun/vrun_v23_test.go
index bd43692..00f57d1 100644
--- a/cmd/vrun/vrun_v23_test.go
+++ b/cmd/vrun/vrun_v23_test.go
@@ -90,10 +90,10 @@
 		i.Fatal(err)
 	}
 	// The client and server must both recognize bserver and its delegates.
-	if err := pserver.AddToRoots(bserver); err != nil {
+	if err := security.AddToRoots(pserver, bserver); err != nil {
 		i.Fatal(err)
 	}
-	if err := pclient.AddToRoots(bserver); err != nil {
+	if err := security.AddToRoots(pclient, bserver); err != nil {
 		i.Fatal(err)
 	}
 	// We need to add set a default blessings to this pclient for this principal to
diff --git a/lib/security/audit/principal.go b/lib/security/audit/principal.go
index c558398..75df141 100644
--- a/lib/security/audit/principal.go
+++ b/lib/security/audit/principal.go
@@ -78,7 +78,6 @@
 func (p *auditingPrincipal) PublicKey() security.PublicKey         { return p.principal.PublicKey() }
 func (p *auditingPrincipal) Roots() security.BlessingRoots         { return p.principal.Roots() }
 func (p *auditingPrincipal) BlessingStore() security.BlessingStore { return p.principal.BlessingStore() }
-func (p *auditingPrincipal) AddToRoots(b security.Blessings) error { return p.principal.AddToRoots(b) }
 
 func (p *auditingPrincipal) Encrypter() security.BlessingsBasedEncrypter {
 	return p.principal.Encrypter()
diff --git a/lib/security/audit/principal_test.go b/lib/security/audit/principal_test.go
index 404918c..faad182 100644
--- a/lib/security/audit/principal_test.go
+++ b/lib/security/audit/principal_test.go
@@ -137,17 +137,12 @@
 	)
 	ctx, _ = v23.WithPrincipal(ctx, p)
 	auditedP := audit.NewPrincipal(ctx, auditor)
-	blessing, err := p.BlessSelf("self")
-	if err != nil {
-		t.Fatal(err)
-	}
 	tests := []struct {
 		Method string
 		Args   V
 	}{
 		{"PublicKey", V{}},
 		{"Roots", V{}},
-		{"AddToRoots", V{blessing}},
 		{"BlessingStore", V{}},
 	}
 
@@ -211,7 +206,6 @@
 func (p *mockPrincipal) PublicKey() security.PublicKey               { return p.NextResult.(security.PublicKey) }
 func (p *mockPrincipal) Roots() security.BlessingRoots               { return nil }
 func (p *mockPrincipal) BlessingStore() security.BlessingStore       { return nil }
-func (p *mockPrincipal) AddToRoots(b security.Blessings) error       { return nil }
 func (p *mockPrincipal) Encrypter() security.BlessingsBasedEncrypter { return nil }
 func (p *mockPrincipal) Decrypter() security.BlessingsBasedDecrypter { return nil }
 
diff --git a/lib/security/prepare_discharges_test.go b/lib/security/prepare_discharges_test.go
index b7059e2..5aee79f 100644
--- a/lib/security/prepare_discharges_test.go
+++ b/lib/security/prepare_discharges_test.go
@@ -66,10 +66,10 @@
 	if err != nil {
 		t.Fatal(err)
 	}
-	pclient.AddToRoots(pdischarger.BlessingStore().Default())
-	pclient.AddToRoots(v23.GetPrincipal(ctx).BlessingStore().Default())
-	pdischarger.AddToRoots(pclient.BlessingStore().Default())
-	pdischarger.AddToRoots(v23.GetPrincipal(ctx).BlessingStore().Default())
+	security.AddToRoots(pclient, pdischarger.BlessingStore().Default())
+	security.AddToRoots(pclient, v23.GetPrincipal(ctx).BlessingStore().Default())
+	security.AddToRoots(pdischarger, pclient.BlessingStore().Default())
+	security.AddToRoots(pdischarger, v23.GetPrincipal(ctx).BlessingStore().Default())
 
 	expcav, err := security.NewExpiryCaveat(time.Now().Add(time.Hour))
 	if err != nil {
diff --git a/lib/security/principal.go b/lib/security/principal.go
index 742d511..39d3dfb 100644
--- a/lib/security/principal.go
+++ b/lib/security/principal.go
@@ -142,7 +142,7 @@
 	if _, err := p.BlessingStore().Set(blessings, security.AllPrincipals); err != nil {
 		return err
 	}
-	if err := p.AddToRoots(blessings); err != nil {
+	if err := security.AddToRoots(p, blessings); err != nil {
 		return err
 	}
 	return nil
diff --git a/lib/security/testutil_test.go b/lib/security/testutil_test.go
index fb7fee0..4118e85 100644
--- a/lib/security/testutil_test.go
+++ b/lib/security/testutil_test.go
@@ -42,7 +42,7 @@
 			panic(err)
 		}
 	}
-	if err := p.AddToRoots(def); err != nil {
+	if err := security.AddToRoots(p, def); err != nil {
 		panic(err)
 	}
 	if err := p.BlessingStore().SetDefault(def); err != nil {
diff --git a/runtime/internal/naming/namespace/all_test.go b/runtime/internal/naming/namespace/all_test.go
index 4cd19d8..843e2fe 100644
--- a/runtime/internal/naming/namespace/all_test.go
+++ b/runtime/internal/naming/namespace/all_test.go
@@ -49,10 +49,10 @@
 		pc  = testutil.NewPrincipal("c")
 	)
 	// Setup the principals so that they recognize each other.
-	if err := psc.AddToRoots(pc.BlessingStore().Default()); err != nil {
+	if err := security.AddToRoots(psc, pc.BlessingStore().Default()); err != nil {
 		t.Fatal(err)
 	}
-	if err := pc.AddToRoots(psc.BlessingStore().Default()); err != nil {
+	if err := security.AddToRoots(pc, psc.BlessingStore().Default()); err != nil {
 		t.Fatal(err)
 	}
 	if sc, err = v23.WithPrincipal(ctx, psc); err != nil {
diff --git a/runtime/internal/naming/namespace/perms_test.go b/runtime/internal/naming/namespace/perms_test.go
index b66d0ef..5e169d6 100644
--- a/runtime/internal/naming/namespace/perms_test.go
+++ b/runtime/internal/naming/namespace/perms_test.go
@@ -46,7 +46,7 @@
 			// testutil.NewPrincipal has already setup each
 			// principal to use the same blessing for both server
 			// and client activities.
-			if err := p1.AddToRoots(v23.GetPrincipal(other).BlessingStore().Default()); err != nil {
+			if err := security.AddToRoots(p1, v23.GetPrincipal(other).BlessingStore().Default()); err != nil {
 				panic(err)
 			}
 		}
diff --git a/runtime/internal/rpc/full_test.go b/runtime/internal/rpc/full_test.go
index cc71ade..bd1c492 100644
--- a/runtime/internal/rpc/full_test.go
+++ b/runtime/internal/rpc/full_test.go
@@ -555,10 +555,10 @@
 
 	// Client and server recognize the servers blessings
 	for _, p := range []security.Principal{pserver, pclient} {
-		if err := p.AddToRoots(pserver.BlessingStore().Default()); err != nil {
+		if err := security.AddToRoots(p, pserver.BlessingStore().Default()); err != nil {
 			t.Fatal(err)
 		}
-		if err := p.AddToRoots(batman); err != nil {
+		if err := security.AddToRoots(p, batman); err != nil {
 			t.Fatal(err)
 		}
 	}
@@ -607,10 +607,10 @@
 	)
 
 	// Make the client recognize all server blessings
-	if err := pclient.AddToRoots(pserver.BlessingStore().Default()); err != nil {
+	if err := security.AddToRoots(pclient, pserver.BlessingStore().Default()); err != nil {
 		t.Fatal(err)
 	}
-	if err := pclient.AddToRoots(pdischarger.BlessingStore().Default()); err != nil {
+	if err := security.AddToRoots(pclient, pdischarger.BlessingStore().Default()); err != nil {
 		t.Fatal(err)
 	}
 
@@ -683,8 +683,8 @@
 		t.Fatalf("failed to set blessings: %v", err)
 	}
 	// The client will only talk to the discharge services if it recognizes them.
-	pdischargeClient.AddToRoots(pdischarger1.BlessingStore().Default())
-	pdischargeClient.AddToRoots(pdischarger2.BlessingStore().Default())
+	security.AddToRoots(pdischargeClient, pdischarger1.BlessingStore().Default())
+	security.AddToRoots(pdischargeClient, pdischarger2.BlessingStore().Default())
 
 	ns := tnaming.NewSimpleNamespace()
 
@@ -730,7 +730,7 @@
 	)
 
 	// Make the client recognize all server blessings
-	if err := pclient.AddToRoots(pserver.BlessingStore().Default()); err != nil {
+	if err := security.AddToRoots(pclient, pserver.BlessingStore().Default()); err != nil {
 		t.Fatal(err)
 	}
 
@@ -925,8 +925,8 @@
 func newClientServerPrincipals() (client, server security.Principal) {
 	client = testutil.NewPrincipal("client")
 	server = testutil.NewPrincipal("server")
-	client.AddToRoots(server.BlessingStore().Default())
-	server.AddToRoots(client.BlessingStore().Default())
+	security.AddToRoots(client, server.BlessingStore().Default())
+	security.AddToRoots(server, client.BlessingStore().Default())
 	return
 }
 
diff --git a/runtime/internal/rpc/server_authorizer_test.go b/runtime/internal/rpc/server_authorizer_test.go
index 07c07e6..dc3ba7e 100644
--- a/runtime/internal/rpc/server_authorizer_test.go
+++ b/runtime/internal/rpc/server_authorizer_test.go
@@ -49,7 +49,7 @@
 	ctx, _ = v23.WithPrincipal(ctx, pclient)
 	// Make client recognize ali, bob and otherAli blessings
 	for _, b := range []security.Blessings{ali, bob, otherAli} {
-		if err := pclient.AddToRoots(b); err != nil {
+		if err := security.AddToRoots(pclient, b); err != nil {
 			t.Fatal(err)
 		}
 	}
diff --git a/runtime/internal/rpc/stream/manager/manager_test.go b/runtime/internal/rpc/stream/manager/manager_test.go
index b6ea905..e495136 100644
--- a/runtime/internal/rpc/stream/manager/manager_test.go
+++ b/runtime/internal/rpc/stream/manager/manager_test.go
@@ -929,7 +929,7 @@
 	)
 
 	// p must recognize its own blessings!
-	p.AddToRoots(b)
+	security.AddToRoots(p, b)
 	for idx, test := range tests {
 		sctx, _ := v23.WithPrincipal(ctx, test.principal)
 		ln, ep, err := server.Listen(sctx, "tcp", "127.0.0.1:0", test.blessings)
diff --git a/runtime/internal/rpc/stream/proxy/proxy_test.go b/runtime/internal/rpc/stream/proxy/proxy_test.go
index 1e92bb4..274c234 100644
--- a/runtime/internal/rpc/stream/proxy/proxy_test.go
+++ b/runtime/internal/rpc/stream/proxy/proxy_test.go
@@ -114,9 +114,9 @@
 		dave  = testutil.NewPrincipal("dave")
 	)
 	// Make the proxy recognize "alice", "bob" and "carol", but not "dave"
-	v23.GetPrincipal(ctx).AddToRoots(alice.BlessingStore().Default())
-	v23.GetPrincipal(ctx).AddToRoots(bob.BlessingStore().Default())
-	v23.GetPrincipal(ctx).AddToRoots(carol.BlessingStore().Default())
+	security.AddToRoots(v23.GetPrincipal(ctx), alice.BlessingStore().Default())
+	security.AddToRoots(v23.GetPrincipal(ctx), bob.BlessingStore().Default())
+	security.AddToRoots(v23.GetPrincipal(ctx), carol.BlessingStore().Default())
 
 	testcases := []struct {
 		p  security.Principal
diff --git a/runtime/internal/rpc/test/client_test.go b/runtime/internal/rpc/test/client_test.go
index a2b7d4c..efec8ac 100644
--- a/runtime/internal/rpc/test/client_test.go
+++ b/runtime/internal/rpc/test/client_test.go
@@ -572,7 +572,7 @@
 
 	ctx1, err := v23.WithPrincipal(ctx, testutil.NewPrincipal("test-blessing"))
 	// Client must recognize the server, otherwise it won't even send the request.
-	v23.GetPrincipal(ctx1).AddToRoots(v23.GetPrincipal(ctx).BlessingStore().Default())
+	security.AddToRoots(v23.GetPrincipal(ctx1), v23.GetPrincipal(ctx).BlessingStore().Default())
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/runtime/internal/rpc/test/full_test.go b/runtime/internal/rpc/test/full_test.go
index f28eaae..ad8bfdb 100644
--- a/runtime/internal/rpc/test/full_test.go
+++ b/runtime/internal/rpc/test/full_test.go
@@ -478,7 +478,7 @@
 
 	// The server should recognize the client principal as an authority
 	// on "random" blessings.
-	v23.GetPrincipal(sctx).AddToRoots(bRandom)
+	security.AddToRoots(v23.GetPrincipal(sctx), bRandom)
 
 	// Set a blessing on the client's blessing store to be presented to
 	// the discharge server.
diff --git a/runtime/internal/rpc/test/proxy_test.go b/runtime/internal/rpc/test/proxy_test.go
index 854f338..89c9dfd 100644
--- a/runtime/internal/rpc/test/proxy_test.go
+++ b/runtime/internal/rpc/test/proxy_test.go
@@ -171,7 +171,7 @@
 
 	// The client must recognize the server's blessings, otherwise it won't
 	// communicate with it.
-	pclient.AddToRoots(pserver.BlessingStore().Default())
+	security.AddToRoots(pclient, pserver.BlessingStore().Default())
 
 	// If no address is specified then we'll only 'listen' via
 	// the proxy.
diff --git a/runtime/internal/rt/rpc_test.go b/runtime/internal/rt/rpc_test.go
index c1099a8..c32a840 100644
--- a/runtime/internal/rt/rpc_test.go
+++ b/runtime/internal/rt/rpc_test.go
@@ -127,7 +127,7 @@
 	for _, ctx := range []*context.T{clientCtx, serverCtx} {
 		for _, b := range []security.Blessings{alphaClient, betaClient} {
 			p := v23.GetPrincipal(ctx)
-			if err := p.AddToRoots(b); err != nil {
+			if err := security.AddToRoots(p, b); err != nil {
 				t.Fatal(err)
 			}
 		}
@@ -186,7 +186,7 @@
 			{[]rpc.ServerOpt{bopt}, []string{"dev.v.io/users/foo@bar.com/devices/phone/applications/app", "otherblessing"}},
 		}
 	)
-	if err := p.AddToRoots(bopt.Blessings); err != nil {
+	if err := security.AddToRoots(p, bopt.Blessings); err != nil {
 		t.Fatal(err)
 	}
 	for idx, test := range tests {
@@ -285,7 +285,7 @@
 	if _, err := pclient.BlessingStore().Set(rootClient, "root/server"); err != nil {
 		t.Fatal(err)
 	}
-	if err := pclient.AddToRoots(rootClient); err != nil {
+	if err := security.AddToRoots(pclient, rootClient); err != nil {
 		t.Fatal(err)
 	}
 
diff --git a/services/agent/agentlib/agent_test.go b/services/agent/agentlib/agent_test.go
index bd20ae8..9a9aaba 100644
--- a/services/agent/agentlib/agent_test.go
+++ b/services/agent/agentlib/agent_test.go
@@ -240,8 +240,7 @@
 	if err != nil {
 		b.Fatal(err)
 	}
-	err = p.AddToRoots(blessing)
-	if err != nil {
+	if err = security.AddToRoots(p, blessing); err != nil {
 		b.Fatal(err)
 	}
 	b.ResetTimer()
diff --git a/services/agent/agentlib/agent_v23_test.go b/services/agent/agentlib/agent_v23_test.go
index 9f89231..d366cbd 100644
--- a/services/agent/agentlib/agent_v23_test.go
+++ b/services/agent/agentlib/agent_v23_test.go
@@ -255,10 +255,10 @@
 		i.Fatal(err)
 	}
 	// The client and server must both recognize bserver and its delegates.
-	if err := pserver.AddToRoots(bserver); err != nil {
+	if err := security.AddToRoots(pserver, bserver); err != nil {
 		i.Fatal(err)
 	}
-	if err := pclient.AddToRoots(bserver); err != nil {
+	if err := security.AddToRoots(pclient, bserver); err != nil {
 		i.Fatal(err)
 	}
 	return agentd.WithEnv(ref.EnvCredentials + "=" + clientDir), agentd.WithEnv(ref.EnvCredentials + "=" + serverDir)
diff --git a/services/agent/agentlib/client.go b/services/agent/agentlib/client.go
index 4d38021..6312028 100644
--- a/services/agent/agentlib/client.go
+++ b/services/agent/agentlib/client.go
@@ -267,10 +267,6 @@
 	return &blessingRoots{c.caller}
 }
 
-func (c *client) AddToRoots(blessings security.Blessings) error {
-	return c.caller.call("AddToRoots", results(), blessings)
-}
-
 // TODO(ataly): Implement this method.
 func (c *client) Encrypter() security.BlessingsBasedEncrypter {
 	return nil
diff --git a/services/agent/internal/cache/cache.go b/services/agent/internal/cache/cache.go
index d572b65..307019f 100644
--- a/services/agent/internal/cache/cache.go
+++ b/services/agent/internal/cache/cache.go
@@ -357,10 +357,6 @@
 	return p.cache.Roots()
 }
 
-func (p *cachedPrincipal) AddToRoots(blessings security.Blessings) error {
-	return p.cache.AddToRoots(blessings)
-}
-
 func (p *cachedPrincipal) Close() error {
 	return p.Principal.Close()
 }
diff --git a/services/agent/internal/server/server.go b/services/agent/internal/server/server.go
index c2e9bf5..20e7669 100644
--- a/services/agent/internal/server/server.go
+++ b/services/agent/internal/server/server.go
@@ -236,12 +236,6 @@
 	return a.principal.BlessingsInfo(blessings), nil
 }
 
-func (a *agentd) AddToRoots(blessings security.Blessings) error {
-	defer a.unlock()
-	a.mu.Lock()
-	return a.principal.AddToRoots(blessings)
-}
-
 func (a *agentd) BlessingStoreSet(blessings security.Blessings, forPeers security.BlessingPattern) (security.Blessings, error) {
 	defer a.unlock()
 	a.mu.Lock()
diff --git a/services/agent/internal/test_principal/main.go b/services/agent/internal/test_principal/main.go
index b4a35f7..7fc129e 100644
--- a/services/agent/internal/test_principal/main.go
+++ b/services/agent/internal/test_principal/main.go
@@ -106,7 +106,7 @@
 	if err := p.Roots().Recognized(keybytes, "batman"); err == nil {
 		errorf("Roots().Recognized returned nil")
 	}
-	if err := p.AddToRoots(b); err != nil {
+	if err := security.AddToRoots(p, b); err != nil {
 		errorf("AddToRoots: %v", err)
 	}
 	if err := p.Roots().Recognized(keybytes, "batman"); err != nil {
diff --git a/services/agent/pod_agentd/main.go b/services/agent/pod_agentd/main.go
index bf14dae..a83d872 100644
--- a/services/agent/pod_agentd/main.go
+++ b/services/agent/pod_agentd/main.go
@@ -83,7 +83,7 @@
 	if _, err = p.BlessingStore().Set(blessings, security.AllPrincipals); err != nil {
 		return err
 	}
-	if err = p.AddToRoots(blessings); err != nil {
+	if err = security.AddToRoots(p, blessings); err != nil {
 		return err
 	}
 
@@ -113,7 +113,7 @@
 		if err := vom.Decode(vomBlessings, &blessings); err != nil {
 			ctx.Fatalf("unable to decode the vom blessing roots: %v", err)
 		}
-		if err := p.AddToRoots(blessings); err != nil {
+		if err := security.AddToRoots(p, blessings); err != nil {
 			ctx.Fatalf("unable to add blessing roots: %v", err)
 		}
 	}
diff --git a/services/agent/vbecome/vbecome.go b/services/agent/vbecome/vbecome.go
index 479a1a1..2030c5b 100644
--- a/services/agent/vbecome/vbecome.go
+++ b/services/agent/vbecome/vbecome.go
@@ -158,7 +158,7 @@
 		ctx.Errorf("Couldn't set default client blessing")
 		return err
 	}
-	if err = p.AddToRoots(blessing); err != nil {
+	if err = security.AddToRoots(p, blessing); err != nil {
 		ctx.Errorf("Couldn't set trusted roots")
 		return err
 	}
diff --git a/services/agent/wire.vdl b/services/agent/wire.vdl
index 8b959e8..59b1fdc 100644
--- a/services/agent/wire.vdl
+++ b/services/agent/wire.vdl
@@ -43,7 +43,6 @@
 	MintDischarge(forCaveat, caveatOnDischarge security.Caveat, additionalCaveatsOnDischarge []security.Caveat) (security.WireDischarge | error)
 	PublicKey() ([]byte | error)
 	BlessingsInfo(blessings security.WireBlessings) (map[string][]security.Caveat | error)
-	AddToRoots(blessing security.WireBlessings) error
 
 	BlessingStoreSet(blessings security.WireBlessings, forPeers security.BlessingPattern) (security.WireBlessings | error)
 	BlessingStoreForPeer(peerBlessings []string) (security.WireBlessings | error)
diff --git a/services/agent/wire.vdl.go b/services/agent/wire.vdl.go
index c41b9ea..77b790c 100644
--- a/services/agent/wire.vdl.go
+++ b/services/agent/wire.vdl.go
@@ -132,7 +132,6 @@
 	MintDischarge(ctx *context.T, forCaveat security.Caveat, caveatOnDischarge security.Caveat, additionalCaveatsOnDischarge []security.Caveat, opts ...rpc.CallOpt) (security.Discharge, error)
 	PublicKey(*context.T, ...rpc.CallOpt) ([]byte, error)
 	BlessingsInfo(ctx *context.T, blessings security.Blessings, opts ...rpc.CallOpt) (map[string][]security.Caveat, error)
-	AddToRoots(ctx *context.T, blessing security.Blessings, opts ...rpc.CallOpt) error
 	BlessingStoreSet(ctx *context.T, blessings security.Blessings, forPeers security.BlessingPattern, opts ...rpc.CallOpt) (security.Blessings, error)
 	BlessingStoreForPeer(ctx *context.T, peerBlessings []string, opts ...rpc.CallOpt) (security.Blessings, error)
 	BlessingStoreSetDefault(ctx *context.T, blessings security.Blessings, opts ...rpc.CallOpt) error
@@ -198,11 +197,6 @@
 	return
 }
 
-func (c implAgentClientStub) AddToRoots(ctx *context.T, i0 security.Blessings, opts ...rpc.CallOpt) (err error) {
-	err = v23.GetClient(ctx).Call(ctx, c.name, "AddToRoots", []interface{}{i0}, nil, opts...)
-	return
-}
-
 func (c implAgentClientStub) BlessingStoreSet(ctx *context.T, i0 security.Blessings, i1 security.BlessingPattern, opts ...rpc.CallOpt) (o0 security.Blessings, err error) {
 	err = v23.GetClient(ctx).Call(ctx, c.name, "BlessingStoreSet", []interface{}{i0, i1}, []interface{}{&o0}, opts...)
 	return
@@ -354,7 +348,6 @@
 	MintDischarge(ctx *context.T, call rpc.ServerCall, forCaveat security.Caveat, caveatOnDischarge security.Caveat, additionalCaveatsOnDischarge []security.Caveat) (security.Discharge, error)
 	PublicKey(*context.T, rpc.ServerCall) ([]byte, error)
 	BlessingsInfo(ctx *context.T, call rpc.ServerCall, blessings security.Blessings) (map[string][]security.Caveat, error)
-	AddToRoots(ctx *context.T, call rpc.ServerCall, blessing security.Blessings) error
 	BlessingStoreSet(ctx *context.T, call rpc.ServerCall, blessings security.Blessings, forPeers security.BlessingPattern) (security.Blessings, error)
 	BlessingStoreForPeer(ctx *context.T, call rpc.ServerCall, peerBlessings []string) (security.Blessings, error)
 	BlessingStoreSetDefault(ctx *context.T, call rpc.ServerCall, blessings security.Blessings) error
@@ -386,7 +379,6 @@
 	MintDischarge(ctx *context.T, call rpc.ServerCall, forCaveat security.Caveat, caveatOnDischarge security.Caveat, additionalCaveatsOnDischarge []security.Caveat) (security.Discharge, error)
 	PublicKey(*context.T, rpc.ServerCall) ([]byte, error)
 	BlessingsInfo(ctx *context.T, call rpc.ServerCall, blessings security.Blessings) (map[string][]security.Caveat, error)
-	AddToRoots(ctx *context.T, call rpc.ServerCall, blessing security.Blessings) error
 	BlessingStoreSet(ctx *context.T, call rpc.ServerCall, blessings security.Blessings, forPeers security.BlessingPattern) (security.Blessings, error)
 	BlessingStoreForPeer(ctx *context.T, call rpc.ServerCall, peerBlessings []string) (security.Blessings, error)
 	BlessingStoreSetDefault(ctx *context.T, call rpc.ServerCall, blessings security.Blessings) error
@@ -460,10 +452,6 @@
 	return s.impl.BlessingsInfo(ctx, call, i0)
 }
 
-func (s implAgentServerStub) AddToRoots(ctx *context.T, call rpc.ServerCall, i0 security.Blessings) error {
-	return s.impl.AddToRoots(ctx, call, i0)
-}
-
 func (s implAgentServerStub) BlessingStoreSet(ctx *context.T, call rpc.ServerCall, i0 security.Blessings, i1 security.BlessingPattern) (security.Blessings, error) {
 	return s.impl.BlessingStoreSet(ctx, call, i0, i1)
 }
@@ -595,12 +583,6 @@
 			},
 		},
 		{
-			Name: "AddToRoots",
-			InArgs: []rpc.ArgDesc{
-				{"blessing", ``}, // security.Blessings
-			},
-		},
-		{
 			Name: "BlessingStoreSet",
 			InArgs: []rpc.ArgDesc{
 				{"blessings", ``}, // security.Blessings
diff --git a/services/device/claimable/main.go b/services/device/claimable/main.go
index 2120cec..e7a52ab 100644
--- a/services/device/claimable/main.go
+++ b/services/device/claimable/main.go
@@ -72,7 +72,7 @@
 		if err := vom.Decode(vomBlessings, &blessings); err != nil {
 			ctx.Fatalf("unable to decode the vom blessing roots: %v", err)
 		}
-		if err := p.AddToRoots(blessings); err != nil {
+		if err := security.AddToRoots(p, blessings); err != nil {
 			ctx.Fatalf("unable to add blessing roots: %v", err)
 		}
 	}
diff --git a/services/device/deviced/internal/impl/app_service.go b/services/device/deviced/internal/impl/app_service.go
index 56dd7bc..e3ee797 100644
--- a/services/device/deviced/internal/impl/app_service.go
+++ b/services/device/deviced/internal/impl/app_service.go
@@ -659,7 +659,7 @@
 	if _, err := p.BlessingStore().Set(appBlessings, security.AllPrincipals); err != nil {
 		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("BlessingStore.Set() failed: %v", err))
 	}
-	if err := p.AddToRoots(appBlessings); err != nil {
+	if err := security.AddToRoots(p, appBlessings); err != nil {
 		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("AddToRoots() failed: %v", err))
 	}
 	// In addition, we give the app separate blessings for the purpose of
@@ -693,7 +693,7 @@
 		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("BlessingStore.Set() failed: %v", err))
 	}
 	info.DeviceManagerPeerPattern = randomPattern
-	if err := p.AddToRoots(dmBlessings); err != nil {
+	if err := security.AddToRoots(p, dmBlessings); err != nil {
 		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("AddToRoots() failed: %v", err))
 	}
 	return nil
diff --git a/services/device/deviced/internal/impl/device_service.go b/services/device/deviced/internal/impl/device_service.go
index 6ee780b..be3db00 100644
--- a/services/device/deviced/internal/impl/device_service.go
+++ b/services/device/deviced/internal/impl/device_service.go
@@ -335,7 +335,7 @@
 	if _, err := p.BlessingStore().Set(dmBlessings, security.AllPrincipals); err != nil {
 		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("BlessingStore.Set() failed: %v", err))
 	}
-	if err := p.AddToRoots(dmBlessings); err != nil {
+	if err := security.AddToRoots(p, dmBlessings); err != nil {
 		return verror.New(errors.ErrOperationFailed, ctx, fmt.Sprintf("AddToRoots() failed: %v", err))
 	}
 
diff --git a/services/device/deviced/internal/impl/impl_test.go b/services/device/deviced/internal/impl/impl_test.go
index b210344..c99f31c 100644
--- a/services/device/deviced/internal/impl/impl_test.go
+++ b/services/device/deviced/internal/impl/impl_test.go
@@ -18,6 +18,7 @@
 	"v.io/v23"
 	"v.io/v23/context"
 	"v.io/v23/naming"
+	"v.io/v23/security"
 	"v.io/v23/services/application"
 	"v.io/v23/services/device"
 	"v.io/x/ref"
@@ -518,7 +519,7 @@
 	// Both the "external" processes must recognize the root mounttable's
 	// blessings, otherwise they will not talk to it.
 	for _, c := range []*context.T{selfCtx, otherCtx} {
-		v23.GetPrincipal(c).AddToRoots(v23.GetPrincipal(ctx).BlessingStore().Default())
+		security.AddToRoots(v23.GetPrincipal(c), v23.GetPrincipal(ctx).BlessingStore().Default())
 	}
 
 	dmh := servicetest.RunCommand(t, sh, nil, utiltest.DeviceManager, "dm", root, "unused_helper", "unused_app_repo_name", "unused_curr_link")
diff --git a/services/device/deviced/internal/impl/perms/perms_test.go b/services/device/deviced/internal/impl/perms/perms_test.go
index 838e7c8..975648d 100644
--- a/services/device/deviced/internal/impl/perms/perms_test.go
+++ b/services/device/deviced/internal/impl/perms/perms_test.go
@@ -90,7 +90,7 @@
 	utiltest.InstallAppExpectError(t, octx, verror.ErrNoServers.ID)
 	// Even if it does recognize the device (by virtue of recognizing the
 	// claimant), the device will not allow it to install.
-	if err := v23.GetPrincipal(octx).AddToRoots(v23.GetPrincipal(claimantCtx).BlessingStore().Default()); err != nil {
+	if err := security.AddToRoots(v23.GetPrincipal(octx), v23.GetPrincipal(claimantCtx).BlessingStore().Default()); err != nil {
 		t.Fatal(err)
 	}
 	utiltest.InstallAppExpectError(t, octx, verror.ErrNoAccess.ID)
diff --git a/services/device/internal/claim/claim.go b/services/device/internal/claim/claim.go
index 55202d8..06667e1 100644
--- a/services/device/internal/claim/claim.go
+++ b/services/device/internal/claim/claim.go
@@ -76,7 +76,7 @@
 	}
 	// TODO(ashankar): If the claim fails, would make sense
 	// to remove from roots as well.
-	if err := principal.AddToRoots(granted); err != nil {
+	if err := security.AddToRoots(principal, granted); err != nil {
 		return verror.New(errors.ErrInvalidBlessing, ctx)
 	}
 	if _, err := store.Set(granted, security.AllPrincipals); err != nil {
diff --git a/services/identity/internal/blesser/macaroon_test.go b/services/identity/internal/blesser/macaroon_test.go
index 541f903..1afc3fb 100644
--- a/services/identity/internal/blesser/macaroon_test.go
+++ b/services/identity/internal/blesser/macaroon_test.go
@@ -61,7 +61,7 @@
 	}
 	// But once it recognizes the provider, it should see exactly the name
 	// "provider/bugsbunny" for the caveat cOnlyMethodFoo.
-	user.AddToRoots(b)
+	security.AddToRoots(user, b)
 	binfo := user.BlessingsInfo(b)
 	if num := len(binfo); num != 1 {
 		t.Errorf("Got blessings with %d names, want exactly one name", num)
diff --git a/services/identity/internal/blesser/oauth_test.go b/services/identity/internal/blesser/oauth_test.go
index 6b56a72..63b7b5b 100644
--- a/services/identity/internal/blesser/oauth_test.go
+++ b/services/identity/internal/blesser/oauth_test.go
@@ -61,7 +61,7 @@
 	}
 	// But once it recognizes the provider, it should see exactly the name
 	// "provider/testemail@example.com/test-client".
-	user.AddToRoots(b)
+	security.AddToRoots(user, b)
 	binfo := user.BlessingsInfo(b)
 	if num := len(binfo); num != 1 {
 		t.Errorf("Got blessings with %d names, want exactly one name", num)
@@ -121,7 +121,7 @@
 	}
 	// But once it recognizes the provider, it should see exactly the name
 	// "provider/testemail@example.com/test-client".
-	user.AddToRoots(b)
+	security.AddToRoots(user, b)
 	binfo := user.BlessingsInfo(b)
 	if num := len(binfo); num != 1 {
 		t.Errorf("Got blessings with %d names, want exactly one name", num)
diff --git a/services/identity/internal/handlers/handlers_test.go b/services/identity/internal/handlers/handlers_test.go
index dae47f7..2b3282f 100644
--- a/services/identity/internal/handlers/handlers_test.go
+++ b/services/identity/internal/handlers/handlers_test.go
@@ -165,7 +165,7 @@
 	}
 
 	// Make the blessee trust the blesser's roots
-	if err := blesseePrin.AddToRoots(blesserPrin.BlessingStore().Default()); err != nil {
+	if err := security.AddToRoots(blesseePrin, blesserPrin.BlessingStore().Default()); err != nil {
 		t.Fatal(err)
 	}
 
diff --git a/services/internal/binarylib/perms_test.go b/services/internal/binarylib/perms_test.go
index d460cde..c6c53ed 100644
--- a/services/internal/binarylib/perms_test.go
+++ b/services/internal/binarylib/perms_test.go
@@ -146,8 +146,8 @@
 	prepDirectory(t, storedir)
 
 	otherPrincipal := testutil.NewPrincipal("other")
-	if err := otherPrincipal.AddToRoots(selfPrincipal.BlessingStore().Default()); err != nil {
-		t.Fatalf("otherPrincipal.AddToRoots() failed: %v", err)
+	if err := security.AddToRoots(otherPrincipal, selfPrincipal.BlessingStore().Default()); err != nil {
+		t.Fatalf("AddToRoots() failed: %v", err)
 	}
 	otherCtx, err := v23.WithPrincipal(selfCtx, otherPrincipal)
 	if err != nil {
@@ -429,8 +429,8 @@
 	prepDirectory(t, storedir)
 
 	otherPrincipal := testutil.NewPrincipal("other")
-	if err := otherPrincipal.AddToRoots(selfPrincipal.BlessingStore().Default()); err != nil {
-		t.Fatalf("otherPrincipal.AddToRoots() failed: %v", err)
+	if err := security.AddToRoots(otherPrincipal, selfPrincipal.BlessingStore().Default()); err != nil {
+		t.Fatalf("AddToRoots() failed: %v", err)
 	}
 
 	nmh := servicetest.RunCommand(t, sh, nil, binaryd, "bini", storedir)
diff --git a/services/mounttable/mounttablelib/mounttable_test.go b/services/mounttable/mounttablelib/mounttable_test.go
index f71d5cc..114fd36 100644
--- a/services/mounttable/mounttablelib/mounttable_test.go
+++ b/services/mounttable/mounttablelib/mounttable_test.go
@@ -910,7 +910,7 @@
 			// testutil.NewPrincipal has already setup each
 			// principal to use the same blessing for both server
 			// and client activities.
-			if err := p1.AddToRoots(v23.GetPrincipal(other).BlessingStore().Default()); err != nil {
+			if err := security.AddToRoots(p1, v23.GetPrincipal(other).BlessingStore().Default()); err != nil {
 				panic(err)
 			}
 		}
diff --git a/services/syncbase/signing/signing_test.go b/services/syncbase/signing/signing_test.go
index a91f2e5..1f7c2f0 100644
--- a/services/syncbase/signing/signing_test.go
+++ b/services/syncbase/signing/signing_test.go
@@ -87,7 +87,7 @@
 	}
 	for i := range principals {
 		for j := range principals {
-			principals[j].principal.AddToRoots(principals[i].blessings)
+			security.AddToRoots(principals[j].principal, principals[i].blessings)
 		}
 	}
 	return principals
@@ -304,7 +304,7 @@
 	pdList := []*principalDesc{author, validator, checker}
 	for i := 0; i != len(pdList); i++ {
 		for j := 0; j != len(pdList); j++ {
-			pdList[j].principal.AddToRoots(pdList[i].blessings)
+			security.AddToRoots(pdList[j].principal, pdList[i].blessings)
 		}
 	}
 
diff --git a/services/syncbase/signing/validationcache_test.go b/services/syncbase/signing/validationcache_test.go
index 2f6f68a..5491852 100644
--- a/services/syncbase/signing/validationcache_test.go
+++ b/services/syncbase/signing/validationcache_test.go
@@ -63,7 +63,7 @@
 	pdList := []*principalVDesc{author, validator, checker}
 	for i := 0; i != len(pdList); i++ {
 		for j := 0; j != len(pdList); j++ {
-			pdList[j].principal.AddToRoots(pdList[i].blessings)
+			security.AddToRoots(pdList[j].principal, pdList[i].blessings)
 		}
 	}
 
diff --git a/services/syncbase/testutil/util.go b/services/syncbase/testutil/util.go
index 7c40dba..7af6f70 100644
--- a/services/syncbase/testutil/util.go
+++ b/services/syncbase/testutil/util.go
@@ -281,8 +281,8 @@
 
 	// Have users of the prepared context treat root's public key as an authority
 	// on all blessings rooted at "root".
-	if err := p.AddToRoots(blessings); err != nil {
-		vlog.Fatal("p.AddToRoots() failed: ", err)
+	if err := security.AddToRoots(p, blessings); err != nil {
+		vlog.Fatal("AddToRoots() failed: ", err)
 	}
 
 	resCtx, err := v23.WithPrincipal(ctx, p)
diff --git a/services/wspr/internal/app/app.go b/services/wspr/internal/app/app.go
index 33087d9..28e2c9d 100644
--- a/services/wspr/internal/app/app.go
+++ b/services/wspr/internal/app/app.go
@@ -817,8 +817,7 @@
 
 // AddToRoots adds the provided blessing as a root.
 func (c *Controller) AddToRoots(_ *context.T, _ rpc.ServerCall, inputBlessings security.Blessings) error {
-	p := v23.GetPrincipal(c.ctx)
-	return p.AddToRoots(inputBlessings)
+	return security.AddToRoots(v23.GetPrincipal(c.ctx), inputBlessings)
 }
 
 // HandleGranterResponse handles the result of a Granter request.
diff --git a/services/wspr/internal/app/app_test.go b/services/wspr/internal/app/app_test.go
index 81cd981..32bcfc3 100644
--- a/services/wspr/internal/app/app_test.go
+++ b/services/wspr/internal/app/app_test.go
@@ -448,7 +448,7 @@
 	client := v23.GetClient(rt.controller.Context())
 	// And have the client recognize the server, otherwise it won't
 	// authorize calls to it.
-	v23.GetPrincipal(rt.controller.Context()).AddToRoots(v23.GetPrincipal(ctx).BlessingStore().Default())
+	security.AddToRoots(v23.GetPrincipal(rt.controller.Context()), v23.GetPrincipal(ctx).BlessingStore().Default())
 
 	if err != nil {
 		t.Fatalf("unable to create client: %v", err)
diff --git a/services/wspr/internal/principal/principal.go b/services/wspr/internal/principal/principal.go
index dc7dca2..3d4fd52 100644
--- a/services/wspr/internal/principal/principal.go
+++ b/services/wspr/internal/principal/principal.go
@@ -299,7 +299,7 @@
 	if _, err := ret.BlessingStore().Set(blessings, security.AllPrincipals); err != nil {
 		return nil, verror.New(errFailedToSetAllPrincipalBlessings, nil, err)
 	}
-	if err := ret.AddToRoots(blessings); err != nil {
+	if err := security.AddToRoots(ret, blessings); err != nil {
 		return nil, verror.New(errFailedToAddRoots, nil, err)
 	}
 	return ret, nil
diff --git a/test/modules/shell.go b/test/modules/shell.go
index e4eac10..c08c08b 100644
--- a/test/modules/shell.go
+++ b/test/modules/shell.go
@@ -353,7 +353,7 @@
 	if _, err := child.BlessingStore().Set(union, security.AllPrincipals); err != nil {
 		return nil, err
 	}
-	if err := child.AddToRoots(blessings); err != nil {
+	if err := security.AddToRoots(child, blessings); err != nil {
 		return nil, err
 	}
 
diff --git a/test/testutil/security.go b/test/testutil/security.go
index 2c673dd..97eb424 100644
--- a/test/testutil/security.go
+++ b/test/testutil/security.go
@@ -89,7 +89,7 @@
 //    b, _ := idp.NewBlessings(who, extension, caveats...)
 //    who.BlessingStore().SetDefault(b)
 //    who.BlessingStore().Set(b, security.AllPrincipals)
-//    who.AddToRoots(b)
+//    security.AddToRoots(who, b)
 func (idp *IDProvider) Bless(who security.Principal, extension string, caveats ...security.Caveat) error {
 	b, err := idp.NewBlessings(who, extension, caveats...)
 	if err != nil {