s/etag/version/

Resolves https://github.com/veyron/release-issues/issues/1736.

MultiPart: 2/3

Change-Id: I3fadd2d0f5cc71958704738424af8f63794cd876
diff --git a/profiles/internal/naming/namespace/acl.go b/profiles/internal/naming/namespace/acl.go
index d47e4ea..cdb00ce 100644
--- a/profiles/internal/naming/namespace/acl.go
+++ b/profiles/internal/naming/namespace/acl.go
@@ -15,10 +15,10 @@
 )
 
 // setAccessListInMountTable sets the AccessList in a single server.
-func setAccessListInMountTable(ctx *context.T, client rpc.Client, name string, acl access.Permissions, etag, id string, opts []rpc.CallOpt) (s status) {
+func setAccessListInMountTable(ctx *context.T, client rpc.Client, name string, acl access.Permissions, version, id string, opts []rpc.CallOpt) (s status) {
 	s.id = id
 	ctx, _ = context.WithTimeout(ctx, callTimeout)
-	call, err := client.StartCall(ctx, name, "SetPermissions", []interface{}{acl, etag}, append(opts, options.NoResolve{})...)
+	call, err := client.StartCall(ctx, name, "SetPermissions", []interface{}{acl, version}, append(opts, options.NoResolve{})...)
 	s.err = err
 	if err != nil {
 		return
@@ -27,21 +27,21 @@
 	return
 }
 
-func (ns *namespace) SetPermissions(ctx *context.T, name string, acl access.Permissions, etag string, opts ...naming.NamespaceOpt) error {
+func (ns *namespace) SetPermissions(ctx *context.T, name string, acl access.Permissions, version string, opts ...naming.NamespaceOpt) error {
 	defer vlog.LogCall()()
 	client := v23.GetClient(ctx)
 
 	// Apply to all mount tables implementing the name.
 	f := func(ctx *context.T, mt, id string) status {
-		return setAccessListInMountTable(ctx, client, mt, acl, etag, id, getCallOpts(opts))
+		return setAccessListInMountTable(ctx, client, mt, acl, version, id, getCallOpts(opts))
 	}
 	err := ns.dispatch(ctx, name, f, opts)
-	vlog.VI(1).Infof("SetPermissions(%s, %v, %s) -> %v", name, acl, etag, err)
+	vlog.VI(1).Infof("SetPermissions(%s, %v, %s) -> %v", name, acl, version, err)
 	return err
 }
 
 // GetPermissions gets an AccessList from a mount table.
-func (ns *namespace) GetPermissions(ctx *context.T, name string, opts ...naming.NamespaceOpt) (acl access.Permissions, etag string, err error) {
+func (ns *namespace) GetPermissions(ctx *context.T, name string, opts ...naming.NamespaceOpt) (acl access.Permissions, version string, err error) {
 	defer vlog.LogCall()()
 	client := v23.GetClient(ctx)
 
@@ -58,6 +58,6 @@
 		err = serr
 		return
 	}
-	err = call.Finish(&acl, &etag)
+	err = call.Finish(&acl, &version)
 	return
 }
diff --git a/profiles/internal/naming/namespace/acl_test.go b/profiles/internal/naming/namespace/acl_test.go
index e7ef23c..3cc7cb5 100644
--- a/profiles/internal/naming/namespace/acl_test.go
+++ b/profiles/internal/naming/namespace/acl_test.go
@@ -137,11 +137,11 @@
 	}
 
 	// Set/Get the mount point's AccessList.
-	acl, etag, err := ns.GetPermissions(rootCtx, "a/b/c")
+	acl, version, err := ns.GetPermissions(rootCtx, "a/b/c")
 	if err != nil {
 		t.Fatalf("GetPermissions a/b/c: %s", err)
 	}
-	if err := ns.SetPermissions(rootCtx, "a/b/c", openAccessList, etag); err != nil {
+	if err := ns.SetPermissions(rootCtx, "a/b/c", openAccessList, version); err != nil {
 		t.Fatalf("SetPermissions a/b/c: %s", err)
 	}
 	nacl, _, err := ns.GetPermissions(rootCtx, "a/b/c")
@@ -154,8 +154,8 @@
 
 	// Now Set/Get the parallel mount point's AccessList.
 	name := "a/b/c/d/e"
-	etag = "" // Parallel setacl with any other value is dangerous
-	if err := ns.SetPermissions(rootCtx, name, openAccessList, etag); err != nil {
+	version = "" // Parallel setacl with any other value is dangerous
+	if err := ns.SetPermissions(rootCtx, name, openAccessList, version); err != nil {
 		t.Fatalf("SetPermissions %s: %s", name, err)
 	}
 	nacl, _, err = ns.GetPermissions(rootCtx, name)
@@ -187,7 +187,7 @@
 	// Create mount points accessible only by root's key.
 	name = "a/b/c/d/f"
 	deadbody := "/the:8888/rain"
-	if err := ns.SetPermissions(rootCtx, name, closedAccessList, etag); err != nil {
+	if err := ns.SetPermissions(rootCtx, name, closedAccessList, version); err != nil {
 		t.Fatalf("SetPermissions %s: %s", name, err)
 	}
 	nacl, _, err = ns.GetPermissions(rootCtx, name)
@@ -215,7 +215,7 @@
 
 	// Create a mount point via Serve accessible only by root's key.
 	name = "a/b/c/d/g"
-	if err := ns.SetPermissions(rootCtx, name, closedAccessList, etag); err != nil {
+	if err := ns.SetPermissions(rootCtx, name, closedAccessList, version); err != nil {
 		t.Fatalf("SetPermissions %s: %s", name, err)
 	}
 	server, err := v23.NewServer(rootCtx)
diff --git a/profiles/internal/testing/mocks/naming/namespace.go b/profiles/internal/testing/mocks/naming/namespace.go
index cef0067..6a7e1ef 100644
--- a/profiles/internal/testing/mocks/naming/namespace.go
+++ b/profiles/internal/testing/mocks/naming/namespace.go
@@ -160,13 +160,13 @@
 	return nil
 }
 
-func (ns *namespaceMock) GetPermissions(ctx *context.T, name string, opts ...naming.NamespaceOpt) (acl access.Permissions, etag string, err error) {
+func (ns *namespaceMock) GetPermissions(ctx *context.T, name string, opts ...naming.NamespaceOpt) (acl access.Permissions, version string, err error) {
 	defer vlog.LogCall()()
 	panic("Calling GetPermissions on a mock namespace.  This is not supported.")
 	return nil, "", nil
 }
 
-func (ns *namespaceMock) SetPermissions(ctx *context.T, name string, acl access.Permissions, etag string, opts ...naming.NamespaceOpt) error {
+func (ns *namespaceMock) SetPermissions(ctx *context.T, name string, acl access.Permissions, version string, opts ...naming.NamespaceOpt) error {
 	defer vlog.LogCall()()
 	panic("Calling SetPermissions on a mock namespace.  This is not supported.")
 	return nil
diff --git a/services/application/application/impl_test.go b/services/application/application/impl_test.go
index dc93bb8..5a3749b 100644
--- a/services/application/application/impl_test.go
+++ b/services/application/application/impl_test.go
@@ -94,8 +94,8 @@
 	return nil
 }
 
-func (s *server) SetPermissions(_ rpc.ServerCall, acl access.Permissions, etag string) error {
-	vlog.VI(2).Infof("%v.SetPermissions(%v, %v) was called", acl, etag)
+func (s *server) SetPermissions(_ rpc.ServerCall, acl access.Permissions, version string) error {
+	vlog.VI(2).Infof("%v.SetPermissions(%v, %v) was called", acl, version)
 	return nil
 }
 
diff --git a/services/application/applicationd/acl_test.go b/services/application/applicationd/acl_test.go
index c715f85..bd7e3da 100644
--- a/services/application/applicationd/acl_test.go
+++ b/services/application/applicationd/acl_test.go
@@ -122,11 +122,11 @@
 	}
 
 	vlog.VI(2).Infof("Accessing the Permission Lists of the root returns a (simulated) list providing default authorization.")
-	acl, etag, err := repostub.GetPermissions(ctx)
+	acl, version, err := repostub.GetPermissions(ctx)
 	if err != nil {
 		t.Fatalf("GetPermissions should not have failed: %v", err)
 	}
-	if got, want := etag, ""; got != want {
+	if got, want := version, ""; got != want {
 		t.Fatalf("GetPermissions got %v, want %v", got, want)
 	}
 	expected := access.Permissions{
@@ -159,7 +159,7 @@
 		t.Fatalf("SetPermissions failed: %v", err)
 	}
 
-	acl, etag, err = repostub.GetPermissions(ctx)
+	acl, version, err = repostub.GetPermissions(ctx)
 	if err != nil {
 		t.Fatalf("GetPermissions should not have failed: %v", err)
 	}
@@ -174,14 +174,14 @@
 	}
 
 	// Other takes control.
-	acl, etag, err = repostub.GetPermissions(otherCtx)
+	acl, version, err = repostub.GetPermissions(otherCtx)
 	if err != nil {
 		t.Fatalf("GetPermissions 2 should not have failed: %v", err)
 	}
 	acl["Admin"] = access.AccessList{
 		In:    []security.BlessingPattern{"root/other"},
 		NotIn: []string{}}
-	if err = repostub.SetPermissions(otherCtx, acl, etag); err != nil {
+	if err = repostub.SetPermissions(otherCtx, acl, version); err != nil {
 		t.Fatalf("SetPermissions failed: %v", err)
 	}
 
@@ -315,14 +315,14 @@
 	}
 
 	vlog.VI(2).Infof("Self gives other full access to repo/search/...")
-	newAccessList, etag, err := v1stub.GetPermissions(ctx)
+	newAccessList, version, err := v1stub.GetPermissions(ctx)
 	if err != nil {
 		t.Fatalf("GetPermissions should not have failed: %v", err)
 	}
 	for _, tag := range access.AllTypicalTags() {
 		newAccessList.Add("root/other", string(tag))
 	}
-	if err := v1stub.SetPermissions(ctx, newAccessList, etag); err != nil {
+	if err := v1stub.SetPermissions(ctx, newAccessList, version); err != nil {
 		t.Fatalf("SetPermissions failed: %v", err)
 	}
 
@@ -379,12 +379,12 @@
 	}
 
 	// Self gives other write perms on base.
-	newAccessList, etag, err = repostub.GetPermissions(ctx)
+	newAccessList, version, err = repostub.GetPermissions(ctx)
 	if err != nil {
 		t.Fatalf("GetPermissions should not have failed: %v", err)
 	}
 	newAccessList["Write"] = access.AccessList{In: []security.BlessingPattern{"root/other", "root/self"}}
-	if err := repostub.SetPermissions(ctx, newAccessList, etag); err != nil {
+	if err := repostub.SetPermissions(ctx, newAccessList, version); err != nil {
 		t.Fatalf("SetPermissions failed: %v", err)
 	}
 
diff --git a/services/application/applicationd/service.go b/services/application/applicationd/service.go
index 397e540..3a0938b 100644
--- a/services/application/applicationd/service.go
+++ b/services/application/applicationd/service.go
@@ -248,7 +248,7 @@
 	return ch, nil
 }
 
-func (i *appRepoService) GetPermissions(call rpc.ServerCall) (acl access.Permissions, etag string, err error) {
+func (i *appRepoService) GetPermissions(call rpc.ServerCall) (acl access.Permissions, version string, err error) {
 	name, _, err := parse(call.Context(), i.suffix)
 	if err != nil {
 		return nil, "", err
@@ -257,15 +257,15 @@
 	defer i.store.Unlock()
 	path := naming.Join("/acls", name, "data")
 
-	acl, etag, err = getAccessList(i.store, path)
+	acl, version, err = getAccessList(i.store, path)
 	if verror.ErrorID(err) == verror.ErrNoExist.ID {
 		return acls.NilAuthPermissions(call), "", nil
 	}
 
-	return acl, etag, err
+	return acl, version, err
 }
 
-func (i *appRepoService) SetPermissions(call rpc.ServerCall, acl access.Permissions, etag string) error {
+func (i *appRepoService) SetPermissions(call rpc.ServerCall, acl access.Permissions, version string) error {
 	name, _, err := parse(call.Context(), i.suffix)
 	if err != nil {
 		return err
@@ -273,7 +273,7 @@
 	i.store.Lock()
 	defer i.store.Unlock()
 	path := naming.Join("/acls", name, "data")
-	return setAccessList(i.store, path, acl, etag)
+	return setAccessList(i.store, path, acl, version)
 }
 
 // getAccessList fetches a Permissions out of the Memstore at the provided path.
@@ -294,25 +294,25 @@
 		return nil, "", err
 	}
 
-	etag, err := acls.ComputeEtag(acl)
+	version, err := acls.ComputeVersion(acl)
 	if err != nil {
 		return nil, "", err
 	}
-	return acl, etag, nil
+	return acl, version, nil
 }
 
 // setAccessList writes a Permissions into the Memstore at the provided path.
 // where path is expected to have already been cleaned by naming.Join.
-func setAccessList(store *fs.Memstore, path string, acl access.Permissions, etag string) error {
-	_, oetag, err := getAccessList(store, path)
+func setAccessList(store *fs.Memstore, path string, acl access.Permissions, version string) error {
+	_, oversion, err := getAccessList(store, path)
 	if verror.ErrorID(err) == verror.ErrNoExist.ID {
-		oetag = etag
+		oversion = version
 	} else if err != nil {
 		return err
 	}
 
-	if oetag != etag {
-		return verror.NewErrBadEtag(nil)
+	if oversion != version {
+		return verror.NewErrBadVersion(nil)
 	}
 
 	tname, err := store.BindTransactionRoot("").CreateTransaction(nil)
diff --git a/services/binary/binary/impl_test.go b/services/binary/binary/impl_test.go
index 3fe3ca6..f833c02 100644
--- a/services/binary/binary/impl_test.go
+++ b/services/binary/binary/impl_test.go
@@ -81,11 +81,11 @@
 	return nil
 }
 
-func (s *server) GetPermissions(rpc.ServerCall) (acl access.Permissions, etag string, err error) {
+func (s *server) GetPermissions(rpc.ServerCall) (acl access.Permissions, version string, err error) {
 	return nil, "", nil
 }
 
-func (s *server) SetPermissions(call rpc.ServerCall, acl access.Permissions, etag string) error {
+func (s *server) SetPermissions(call rpc.ServerCall, acl access.Permissions, version string) error {
 	return nil
 }
 
diff --git a/services/binary/binarylib/acl_test.go b/services/binary/binarylib/acl_test.go
index acdfda9..8dbf0ba 100644
--- a/services/binary/binarylib/acl_test.go
+++ b/services/binary/binarylib/acl_test.go
@@ -215,7 +215,7 @@
 	}
 
 	vlog.VI(2).Infof("Validate the AccessList file on bini/private.")
-	acl, etag, err := b("bini/private").GetPermissions(selfCtx)
+	acl, version, err := b("bini/private").GetPermissions(selfCtx)
 	if err != nil {
 		t.Fatalf("GetPermissions failed: %v", err)
 	}
@@ -238,7 +238,7 @@
 		acl.Clear("self", string(tag))
 		acl.Add("self/$", string(tag))
 	}
-	if err := b("bini/private").SetPermissions(selfCtx, acl, etag); err != nil {
+	if err := b("bini/private").SetPermissions(selfCtx, acl, version); err != nil {
 		t.Fatalf("SetPermissions failed: %v", err)
 	}
 
diff --git a/services/binary/binarylib/service.go b/services/binary/binarylib/service.go
index 71ee821..5a83d94 100644
--- a/services/binary/binarylib/service.go
+++ b/services/binary/binarylib/service.go
@@ -370,17 +370,17 @@
 	return ch, nil
 }
 
-func (i *binaryService) GetPermissions(call rpc.ServerCall) (acl access.Permissions, etag string, err error) {
+func (i *binaryService) GetPermissions(call rpc.ServerCall) (acl access.Permissions, version string, err error) {
 
-	acl, etag, err = i.aclstore.Get(aclPath(i.state.rootDir, i.suffix))
+	acl, version, err = i.aclstore.Get(aclPath(i.state.rootDir, i.suffix))
 
 	if os.IsNotExist(err) {
 		// No AccessList file found which implies a nil authorizer. This results in default authorization.
 		return acls.NilAuthPermissions(call), "", nil
 	}
-	return acl, etag, err
+	return acl, version, err
 }
 
-func (i *binaryService) SetPermissions(_ rpc.ServerCall, acl access.Permissions, etag string) error {
-	return i.aclstore.Set(aclPath(i.state.rootDir, i.suffix), acl, etag)
+func (i *binaryService) SetPermissions(_ rpc.ServerCall, acl access.Permissions, version string) error {
+	return i.aclstore.Set(aclPath(i.state.rootDir, i.suffix), acl, version)
 }
diff --git a/services/device/device/acl_impl.go b/services/device/device/acl_impl.go
index 0b02e14..5eacbfa 100644
--- a/services/device/device/acl_impl.go
+++ b/services/device/device/acl_impl.go
@@ -107,10 +107,10 @@
 
 	// Set the AccessLists on the specified names.
 	for {
-		objAccessList, etag := make(access.Permissions), ""
+		objAccessList, version := make(access.Permissions), ""
 		if !forceSet {
 			var err error
-			if objAccessList, etag, err = device.ApplicationClient(vanaName).GetPermissions(gctx); err != nil {
+			if objAccessList, version, err = device.ApplicationClient(vanaName).GetPermissions(gctx); err != nil {
 				return fmt.Errorf("GetPermissions(%s) failed: %v", vanaName, err)
 			}
 		}
@@ -124,8 +124,8 @@
 				}
 			}
 		}
-		switch err := device.ApplicationClient(vanaName).SetPermissions(gctx, objAccessList, etag); {
-		case err != nil && verror.ErrorID(err) != verror.ErrBadEtag.ID:
+		switch err := device.ApplicationClient(vanaName).SetPermissions(gctx, objAccessList, version); {
+		case err != nil && verror.ErrorID(err) != verror.ErrBadVersion.ID:
 			return fmt.Errorf("SetPermissions(%s) failed: %v", vanaName, err)
 		case err == nil:
 			return nil
diff --git a/services/device/device/acl_test.go b/services/device/device/acl_test.go
index 820dc73..cc4a0cc 100644
--- a/services/device/device/acl_test.go
+++ b/services/device/device/acl_test.go
@@ -52,8 +52,8 @@
 				In: []security.BlessingPattern{"other", "self"},
 			},
 		},
-		etag: "anEtagForToday",
-		err:  nil,
+		version: "aVersionForToday",
+		err:     nil,
 	}})
 
 	if err := cmd.Execute([]string{"acl", "get", deviceName}); err != nil {
@@ -138,10 +138,10 @@
 				NotIn: []string{"other/bob"},
 			},
 		},
-		etag: "anEtagForToday",
-		err:  nil,
+		version: "aVersionForToday",
+		err:     nil,
 	},
-		verror.NewErrBadEtag(nil),
+		verror.NewErrBadVersion(nil),
 		GetPermissionsResponse{
 			acl: access.Permissions{
 				"Admin": access.AccessList{
@@ -152,8 +152,8 @@
 					NotIn: []string{"other/bob/baddevice"},
 				},
 			},
-			etag: "anEtagForTomorrow",
-			err:  nil,
+			version: "aVersionForTomorrow",
+			err:     nil,
 		},
 		nil,
 	})
@@ -199,7 +199,7 @@
 					NotIn: []string(nil),
 				},
 			},
-			etag: "anEtagForToday",
+			version: "aVersionForToday",
 		},
 		"GetPermissions",
 		SetPermissionsStimulus{
@@ -218,7 +218,7 @@
 					NotIn: []string(nil),
 				},
 			},
-			etag: "anEtagForTomorrow",
+			version: "aVersionForTomorrow",
 		},
 	}
 
@@ -231,9 +231,9 @@
 
 	// GetPermissions fails.
 	tape.SetResponses([]interface{}{GetPermissionsResponse{
-		acl:  access.Permissions{},
-		etag: "anEtagForToday",
-		err:  verror.New(errOops, nil),
+		acl:     access.Permissions{},
+		version: "aVersionForToday",
+		err:     verror.New(errOops, nil),
 	},
 	})
 
@@ -256,15 +256,15 @@
 	stdout.Reset()
 	stderr.Reset()
 
-	// SetPermissions fails with something other than a bad etag failure.
+	// SetPermissions fails with something other than a bad version failure.
 	tape.SetResponses([]interface{}{GetPermissionsResponse{
 		acl: access.Permissions{
 			"Read": access.AccessList{
 				In: []security.BlessingPattern{"other", "self"},
 			},
 		},
-		etag: "anEtagForToday",
-		err:  nil,
+		version: "aVersionForToday",
+		err:     nil,
 	},
 		verror.New(errOops, nil),
 	})
@@ -288,7 +288,7 @@
 					NotIn: []string(nil),
 				},
 			},
-			etag: "anEtagForToday",
+			version: "aVersionForToday",
 		},
 	}
 
diff --git a/services/device/device/devicemanager_mock_test.go b/services/device/device/devicemanager_mock_test.go
index c54f1c0..7c8e2d8 100644
--- a/services/device/device/devicemanager_mock_test.go
+++ b/services/device/device/devicemanager_mock_test.go
@@ -245,25 +245,25 @@
 
 // Mock AccessList getting and setting
 type GetPermissionsResponse struct {
-	acl  access.Permissions
-	etag string
-	err  error
+	acl     access.Permissions
+	version string
+	err     error
 }
 
 type SetPermissionsStimulus struct {
-	fun  string
-	acl  access.Permissions
-	etag string
+	fun     string
+	acl     access.Permissions
+	version string
 }
 
-func (mni *mockDeviceInvoker) SetPermissions(_ rpc.ServerCall, acl access.Permissions, etag string) error {
-	return mni.simpleCore(SetPermissionsStimulus{"SetPermissions", acl, etag}, "SetPermissions")
+func (mni *mockDeviceInvoker) SetPermissions(_ rpc.ServerCall, acl access.Permissions, version string) error {
+	return mni.simpleCore(SetPermissionsStimulus{"SetPermissions", acl, version}, "SetPermissions")
 }
 
 func (mni *mockDeviceInvoker) GetPermissions(rpc.ServerCall) (access.Permissions, string, error) {
 	ir := mni.tape.Record("GetPermissions")
 	r := ir.(GetPermissionsResponse)
-	return r.acl, r.etag, r.err
+	return r.acl, r.version, r.err
 }
 
 func (mni *mockDeviceInvoker) Debug(rpc.ServerCall) (string, error) {
diff --git a/services/device/device/local_install.go b/services/device/device/local_install.go
index 02bc6b1..6c1ba9c 100644
--- a/services/device/device/local_install.go
+++ b/services/device/device/local_install.go
@@ -200,11 +200,11 @@
 	return errNotImplemented
 }
 
-func (binaryInvoker) GetPermissions(call rpc.ServerCall) (acl access.Permissions, etag string, err error) {
+func (binaryInvoker) GetPermissions(call rpc.ServerCall) (acl access.Permissions, version string, err error) {
 	return nil, "", errNotImplemented
 }
 
-func (binaryInvoker) SetPermissions(call rpc.ServerCall, acl access.Permissions, etag string) error {
+func (binaryInvoker) SetPermissions(call rpc.ServerCall, acl access.Permissions, version string) error {
 	return errNotImplemented
 }
 
@@ -213,7 +213,7 @@
 func (i envelopeInvoker) Match(rpc.ServerCall, []string) (application.Envelope, error) {
 	return application.Envelope(i), nil
 }
-func (envelopeInvoker) GetPermissions(rpc.ServerCall) (acl access.Permissions, etag string, err error) {
+func (envelopeInvoker) GetPermissions(rpc.ServerCall) (acl access.Permissions, version string, err error) {
 	return nil, "", errNotImplemented
 }
 
diff --git a/services/device/device/publish.go b/services/device/device/publish.go
index 84d3c47..828aaad 100644
--- a/services/device/device/publish.go
+++ b/services/device/device/publish.go
@@ -68,7 +68,7 @@
 	if readBlessings == "" {
 		return nil
 	}
-	acl, etag, err := permissions.ObjectClient(von).GetPermissions(gctx)
+	acl, version, err := permissions.ObjectClient(von).GetPermissions(gctx)
 	if err != nil {
 		// TODO(caprita): This is a workaround until we sort out the
 		// default AccessLists for applicationd (see issue #1317).  At that
@@ -82,7 +82,7 @@
 			acl.Add(security.BlessingPattern(blessing), string(tag))
 		}
 	}
-	if err := permissions.ObjectClient(von).SetPermissions(gctx, acl, etag); err != nil {
+	if err := permissions.ObjectClient(von).SetPermissions(gctx, acl, version); err != nil {
 		return err
 	}
 	fmt.Fprintf(cmd.Stdout(), "Added patterns %q to Read,Resolve AccessList for %q\n", readBlessings, von)
diff --git a/services/device/internal/impl/app_service.go b/services/device/internal/impl/app_service.go
index 3e0395b..322b8d9 100644
--- a/services/device/internal/impl/app_service.go
+++ b/services/device/internal/impl/app_service.go
@@ -1350,7 +1350,7 @@
 }
 
 // TODO(rjkroege): Consider maintaining an in-memory Permissions cache.
-func (i *appService) SetPermissions(call rpc.ServerCall, acl access.Permissions, etag string) error {
+func (i *appService) SetPermissions(call rpc.ServerCall, acl access.Permissions, version string) error {
 	dir, isInstance, err := dirFromSuffix(i.suffix, i.config.Root)
 	if err != nil {
 		return err
@@ -1361,10 +1361,10 @@
 			return err
 		}
 	}
-	return i.aclstore.Set(path.Join(dir, "acls"), acl, etag)
+	return i.aclstore.Set(path.Join(dir, "acls"), acl, version)
 }
 
-func (i *appService) GetPermissions(call rpc.ServerCall) (acl access.Permissions, etag string, err error) {
+func (i *appService) GetPermissions(call rpc.ServerCall) (acl access.Permissions, version string, err error) {
 	dir, _, err := dirFromSuffix(i.suffix, i.config.Root)
 	if err != nil {
 		return nil, "", err
diff --git a/services/device/internal/impl/debug_acls_test.go b/services/device/internal/impl/debug_acls_test.go
index 629998d..6f0f865 100644
--- a/services/device/internal/impl/debug_acls_test.go
+++ b/services/device/internal/impl/debug_acls_test.go
@@ -22,12 +22,12 @@
 
 func updateAccessList(t *testing.T, ctx *context.T, blessing, right string, name ...string) {
 	accessStub := permissions.ObjectClient(naming.Join(name...))
-	acl, etag, err := accessStub.GetPermissions(ctx)
+	acl, version, err := accessStub.GetPermissions(ctx)
 	if err != nil {
 		t.Fatalf(testutil.FormatLogLine(2, "GetPermissions(%v) failed %v", name, err))
 	}
 	acl.Add(security.BlessingPattern(blessing), right)
-	if err = accessStub.SetPermissions(ctx, acl, etag); err != nil {
+	if err = accessStub.SetPermissions(ctx, acl, version); err != nil {
 		t.Fatalf(testutil.FormatLogLine(2, "SetPermissions(%v, %v, %v) failed: %v", name, blessing, right, err))
 	}
 }
diff --git a/services/device/internal/impl/device_service.go b/services/device/internal/impl/device_service.go
index 6b57514..18eba41 100644
--- a/services/device/internal/impl/device_service.go
+++ b/services/device/internal/impl/device_service.go
@@ -626,12 +626,12 @@
 	return nil
 }
 
-func (s *deviceService) SetPermissions(_ rpc.ServerCall, acl access.Permissions, etag string) error {
+func (s *deviceService) SetPermissions(_ rpc.ServerCall, acl access.Permissions, version string) error {
 	d := AclDir(s.disp.config)
-	return s.disp.aclstore.Set(d, acl, etag)
+	return s.disp.aclstore.Set(d, acl, version)
 }
 
-func (s *deviceService) GetPermissions(rpc.ServerCall) (acl access.Permissions, etag string, err error) {
+func (s *deviceService) GetPermissions(rpc.ServerCall) (acl access.Permissions, version string, err error) {
 	d := AclDir(s.disp.config)
 	return s.disp.aclstore.Get(d)
 }
diff --git a/services/device/internal/impl/impl_test.go b/services/device/internal/impl/impl_test.go
index 8533727..521d126 100644
--- a/services/device/internal/impl/impl_test.go
+++ b/services/device/internal/impl/impl_test.go
@@ -456,7 +456,8 @@
 		t.Fatalf("script changed")
 	}
 
-	// Try issuing an update with a binary that has a different major version number. It should fail
+	// Try issuing an update with a binary that has a different major version
+	// number. It should fail.
 	resolveExpectNotFound(t, ctx, "v2.5DM") // Ensure a clean slate.
 	*envelope = envelopeFromShell(sh, dmEnv, deviceManagerV10Cmd, application.DeviceManagerTitle, "v2.5DM")
 	updateDeviceExpectError(t, ctx, "v2DM", impl.ErrOperationFailed.ID)
@@ -1024,14 +1025,16 @@
 	if err := expectedAccessList.WriteTo(&b); err != nil {
 		t.Fatalf("Failed to save AccessList:%v", err)
 	}
+	// Note, "version" below refers to the Permissions version, not the device
+	// manager version.
 	md5hash := md5.Sum(b.Bytes())
-	expectedETAG := hex.EncodeToString(md5hash[:])
-	acl, etag, err := deviceStub.GetPermissions(selfCtx)
+	expectedVersion := hex.EncodeToString(md5hash[:])
+	acl, version, err := deviceStub.GetPermissions(selfCtx)
 	if err != nil {
 		t.Fatal(err)
 	}
-	if etag != expectedETAG {
-		t.Fatalf("getAccessList expected:%v(%v), got:%v(%v)", expectedAccessList, expectedETAG, acl, etag)
+	if version != expectedVersion {
+		t.Fatalf("getAccessList expected:%v(%v), got:%v(%v)", expectedAccessList, expectedVersion, acl, version)
 	}
 	// Install from octx should fail, since it does not match the AccessList.
 	installAppExpectError(t, octx, verror.ErrNoAccess.ID)
@@ -1041,9 +1044,9 @@
 		newAccessList.Add("root/other", string(tag))
 	}
 	if err := deviceStub.SetPermissions(selfCtx, newAccessList, "invalid"); err == nil {
-		t.Fatalf("SetPermissions should have failed with invalid etag")
+		t.Fatalf("SetPermissions should have failed with invalid version")
 	}
-	if err := deviceStub.SetPermissions(selfCtx, newAccessList, etag); err != nil {
+	if err := deviceStub.SetPermissions(selfCtx, newAccessList, version); err != nil {
 		t.Fatal(err)
 	}
 	// Install should now fail with selfCtx, which no longer matches the
diff --git a/services/device/internal/impl/mock_repo_test.go b/services/device/internal/impl/mock_repo_test.go
index c249f73..6f2bece 100644
--- a/services/device/internal/impl/mock_repo_test.go
+++ b/services/device/internal/impl/mock_repo_test.go
@@ -76,11 +76,11 @@
 	return i.envelope, nil
 }
 
-func (i *arInvoker) GetPermissions(rpc.ServerCall) (acl access.Permissions, etag string, err error) {
+func (i *arInvoker) GetPermissions(rpc.ServerCall) (acl access.Permissions, version string, err error) {
 	return nil, "", nil
 }
 
-func (i *arInvoker) SetPermissions(_ rpc.ServerCall, acl access.Permissions, etag string) error {
+func (i *arInvoker) SetPermissions(_ rpc.ServerCall, acl access.Permissions, version string) error {
 	return nil
 }
 
@@ -170,10 +170,10 @@
 	return nil
 }
 
-func (i *brInvoker) GetPermissions(call rpc.ServerCall) (acl access.Permissions, etag string, err error) {
+func (i *brInvoker) GetPermissions(call rpc.ServerCall) (acl access.Permissions, version string, err error) {
 	return nil, "", nil
 }
 
-func (i *brInvoker) SetPermissions(call rpc.ServerCall, acl access.Permissions, etag string) error {
+func (i *brInvoker) SetPermissions(call rpc.ServerCall, acl access.Permissions, version string) error {
 	return nil
 }
diff --git a/services/groups/internal/memstore/memstore.go b/services/groups/internal/memstore/memstore.go
index 89b2825..3a5ae6c 100644
--- a/services/groups/internal/memstore/memstore.go
+++ b/services/groups/internal/memstore/memstore.go
@@ -15,8 +15,8 @@
 )
 
 type entry struct {
-	v    interface{}
-	etag int
+	v       interface{}
+	version int
 }
 
 type memstore struct {
@@ -30,14 +30,14 @@
 	return &memstore{data: map[string]*entry{}}
 }
 
-func (st *memstore) Get(k string) (v interface{}, etag string, err error) {
+func (st *memstore) Get(k string) (v interface{}, version string, err error) {
 	st.mu.Lock()
 	defer st.mu.Unlock()
 	e, ok := st.data[k]
 	if !ok {
 		return nil, "", &server.ErrUnknownKey{Key: k}
 	}
-	return e.v, strconv.Itoa(e.etag), nil
+	return e.v, strconv.Itoa(e.version), nil
 }
 
 func (st *memstore) Insert(k string, v interface{}) error {
@@ -50,39 +50,39 @@
 	return nil
 }
 
-func (st *memstore) Update(k string, v interface{}, etag string) error {
+func (st *memstore) Update(k string, v interface{}, version string) error {
 	st.mu.Lock()
 	defer st.mu.Unlock()
 	e, ok := st.data[k]
 	if !ok {
 		return &server.ErrUnknownKey{Key: k}
 	}
-	if err := e.checkEtag(etag); err != nil {
+	if err := e.checkVersion(version); err != nil {
 		return err
 	}
 	e.v = v
-	e.etag++
+	e.version++
 	return nil
 }
 
-func (st *memstore) Delete(k string, etag string) error {
+func (st *memstore) Delete(k string, version string) error {
 	st.mu.Lock()
 	defer st.mu.Unlock()
 	e, ok := st.data[k]
 	if !ok {
 		return &server.ErrUnknownKey{Key: k}
 	}
-	if err := e.checkEtag(etag); err != nil {
+	if err := e.checkVersion(version); err != nil {
 		return err
 	}
 	delete(st.data, k)
 	return nil
 }
 
-func (e *entry) checkEtag(etag string) error {
-	newEtag := strconv.Itoa(e.etag)
-	if etag != newEtag {
-		return &server.ErrBadEtag{}
+func (e *entry) checkVersion(version string) error {
+	newVersion := strconv.Itoa(e.version)
+	if version != newVersion {
+		return &server.ErrBadVersion{}
 	}
 	return nil
 }
diff --git a/services/groups/internal/server/group.go b/services/groups/internal/server/group.go
index 51a92bb..2d04399 100644
--- a/services/groups/internal/server/group.go
+++ b/services/groups/internal/server/group.go
@@ -68,54 +68,54 @@
 	return nil
 }
 
-func (g *group) Delete(call rpc.ServerCall, etag string) error {
-	return g.readModifyWrite(call, etag, func(gd *groupData, etagSt string) error {
-		return g.m.st.Delete(g.name, etagSt)
+func (g *group) Delete(call rpc.ServerCall, version string) error {
+	return g.readModifyWrite(call, version, func(gd *groupData, versionSt string) error {
+		return g.m.st.Delete(g.name, versionSt)
 	})
 }
 
-func (g *group) Add(call rpc.ServerCall, entry groups.BlessingPatternChunk, etag string) error {
-	return g.update(call, etag, func(gd *groupData) {
+func (g *group) Add(call rpc.ServerCall, entry groups.BlessingPatternChunk, version string) error {
+	return g.update(call, version, func(gd *groupData) {
 		gd.Entries[entry] = struct{}{}
 	})
 }
 
-func (g *group) Remove(call rpc.ServerCall, entry groups.BlessingPatternChunk, etag string) error {
-	return g.update(call, etag, func(gd *groupData) {
+func (g *group) Remove(call rpc.ServerCall, entry groups.BlessingPatternChunk, version string) error {
+	return g.update(call, version, func(gd *groupData) {
 		delete(gd.Entries, entry)
 	})
 }
 
 // TODO(sadovsky): Replace fake implementation with real implementation.
-func (g *group) Get(call rpc.ServerCall, req groups.GetRequest, reqEtag string) (res groups.GetResponse, etag string, err error) {
-	gd, etag, err := g.getInternal(call)
+func (g *group) Get(call rpc.ServerCall, req groups.GetRequest, reqVersion string) (res groups.GetResponse, version string, err error) {
+	gd, version, err := g.getInternal(call)
 	if err != nil {
 		return groups.GetResponse{}, "", err
 	}
-	return groups.GetResponse{Entries: gd.Entries}, etag, nil
+	return groups.GetResponse{Entries: gd.Entries}, version, nil
 }
 
 // TODO(sadovsky): Replace fake implementation with real implementation.
-func (g *group) Rest(call rpc.ServerCall, req groups.RestRequest, reqEtag string) (res groups.RestResponse, etag string, err error) {
-	_, etag, err = g.getInternal(call)
+func (g *group) Rest(call rpc.ServerCall, req groups.RestRequest, reqVersion string) (res groups.RestResponse, version string, err error) {
+	_, version, err = g.getInternal(call)
 	if err != nil {
 		return groups.RestResponse{}, "", err
 	}
-	return groups.RestResponse{}, etag, nil
+	return groups.RestResponse{}, version, nil
 }
 
-func (g *group) SetPermissions(call rpc.ServerCall, acl access.Permissions, etag string) error {
-	return g.update(call, etag, func(gd *groupData) {
+func (g *group) SetPermissions(call rpc.ServerCall, acl access.Permissions, version string) error {
+	return g.update(call, version, func(gd *groupData) {
 		gd.AccessList = acl
 	})
 }
 
-func (g *group) GetPermissions(call rpc.ServerCall) (acl access.Permissions, etag string, err error) {
-	gd, etag, err := g.getInternal(call)
+func (g *group) GetPermissions(call rpc.ServerCall) (acl access.Permissions, version string, err error) {
+	gd, version, err := g.getInternal(call)
 	if err != nil {
 		return nil, "", err
 	}
-	return gd.AccessList, etag, nil
+	return gd.AccessList, version, nil
 }
 
 ////////////////////////////////////////
@@ -136,8 +136,8 @@
 }
 
 // Returns a VDL-compatible error. Performs access check.
-func (g *group) getInternal(call rpc.ServerCall) (gd groupData, etag string, err error) {
-	v, etag, err := g.m.st.Get(g.name)
+func (g *group) getInternal(call rpc.ServerCall) (gd groupData, version string, err error) {
+	v, version, err := g.m.st.Get(g.name)
 	if err != nil {
 		if _, ok := err.(*ErrUnknownKey); ok {
 			// TODO(sadovsky): Return NoExist if appropriate.
@@ -152,39 +152,39 @@
 	if err := g.authorize(call, gd.AccessList); err != nil {
 		return groupData{}, "", err
 	}
-	return gd, etag, nil
+	return gd, version, nil
 }
 
 // Returns a VDL-compatible error. Performs access check.
-func (g *group) update(call rpc.ServerCall, etag string, fn func(gd *groupData)) error {
-	return g.readModifyWrite(call, etag, func(gd *groupData, etagSt string) error {
+func (g *group) update(call rpc.ServerCall, version string, fn func(gd *groupData)) error {
+	return g.readModifyWrite(call, version, func(gd *groupData, versionSt string) error {
 		fn(gd)
-		return g.m.st.Update(g.name, *gd, etagSt)
+		return g.m.st.Update(g.name, *gd, versionSt)
 	})
 }
 
 // Returns a VDL-compatible error. Performs access check.
 // fn should perform the "modify, write" part of "read, modify, write", and
 // should return a Store error.
-func (g *group) readModifyWrite(call rpc.ServerCall, etag string, fn func(gd *groupData, etagSt string) error) error {
+func (g *group) readModifyWrite(call rpc.ServerCall, version string, fn func(gd *groupData, versionSt string) error) error {
 	// Transaction retry loop.
 	for i := 0; i < 3; i++ {
-		gd, etagSt, err := g.getInternal(call)
+		gd, versionSt, err := g.getInternal(call)
 		if err != nil {
 			return err
 		}
 		// Fail early if possible.
-		if etag != "" && etag != etagSt {
-			return verror.NewErrBadEtag(call.Context())
+		if version != "" && version != versionSt {
+			return verror.NewErrBadVersion(call.Context())
 		}
-		if err := fn(&gd, etagSt); err != nil {
-			if err, ok := err.(*ErrBadEtag); ok {
-				// Retry on etag error if the original etag was empty.
-				if etag != "" {
-					return verror.NewErrBadEtag(call.Context())
+		if err := fn(&gd, versionSt); err != nil {
+			if err, ok := err.(*ErrBadVersion); ok {
+				// Retry on version error if the original version was empty.
+				if version != "" {
+					return verror.NewErrBadVersion(call.Context())
 				}
 			} else {
-				// Abort on non-etag error.
+				// Abort on non-version error.
 				return verror.New(verror.ErrInternal, call.Context(), err)
 			}
 		} else {
diff --git a/services/groups/internal/server/server_test.go b/services/groups/internal/server/server_test.go
index e9299cc..a01d355 100644
--- a/services/groups/internal/server/server_test.go
+++ b/services/groups/internal/server/server_test.go
@@ -44,13 +44,13 @@
 	return res
 }
 
-func getEtagOrDie(g groups.GroupClientStub, ctx *context.T, t *testing.T) string {
-	_, etag, err := g.Get(ctx, groups.GetRequest{}, "")
+func getVersionOrDie(g groups.GroupClientStub, ctx *context.T, t *testing.T) string {
+	_, version, err := g.Get(ctx, groups.GetRequest{}, "")
 	if err != nil {
 		debug.PrintStack()
 		t.Fatal("Get failed: ", err)
 	}
-	return etag
+	return version
 }
 
 func bpc(chunk string) groups.BlessingPatternChunk {
@@ -91,7 +91,8 @@
 		vlog.Fatal("s.Listen() failed: ", err)
 	}
 
-	// TODO(sadovsky): Pass in an AccessList and test AccessList-checking in Group.Create().
+	// TODO(sadovsky): Pass in an AccessList and test AccessList-checking in
+	// Group.Create().
 	acl := access.Permissions{}
 	m := server.NewManager(memstore.New(), acl)
 
@@ -179,8 +180,8 @@
 		t.Fatal("Create should have failed")
 	}
 
-	// Create a group with an AccessList and a few entries, including some redundant
-	// ones.
+	// Create a group with an AccessList and a few entries, including some
+	// redundant ones.
 	g = groups.GroupClient(naming.JoinAddressName(serverName, "grpB"))
 	acl = access.Permissions{}
 	// Allow Admin and Read so that we can call GetPermissions and Get.
@@ -206,19 +207,19 @@
 	ctx, serverName, cleanup := setupOrDie()
 	defer cleanup()
 
-	// Create a group with a default AccessList and no entries, check that we can delete
-	// it.
+	// Create a group with a default AccessList and no entries, check that we can
+	// delete it.
 	g := groups.GroupClient(naming.JoinAddressName(serverName, "grpA"))
 	if err := g.Create(ctx, nil, nil); err != nil {
 		t.Fatal("Create failed: ", err)
 	}
-	// Delete with bad etag should fail.
-	if err := g.Delete(ctx, "20"); verror.ErrorID(err) != verror.ErrBadEtag.ID {
-		t.Fatal("Delete should have failed with etag error")
+	// Delete with bad version should fail.
+	if err := g.Delete(ctx, "20"); verror.ErrorID(err) != verror.ErrBadVersion.ID {
+		t.Fatal("Delete should have failed with version error")
 	}
-	// Delete with correct etag should succeed.
-	etag := getEtagOrDie(g, ctx, t)
-	if err := g.Delete(ctx, etag); err != nil {
+	// Delete with correct version should succeed.
+	version := getVersionOrDie(g, ctx, t)
+	if err := g.Delete(ctx, version); err != nil {
 		t.Fatal("Delete failed: ", err)
 	}
 	// Check that the group was actually deleted.
@@ -231,7 +232,7 @@
 	if err := g.Create(ctx, nil, bpcSlice("foo", "bar", "foo")); err != nil {
 		t.Fatal("Create failed: ", err)
 	}
-	// Delete with empty etag should succeed.
+	// Delete with empty version should succeed.
 	if err := g.Delete(ctx, ""); err != nil {
 		t.Fatal("Delete failed: ", err)
 	}
@@ -244,8 +245,8 @@
 		t.Fatal("Create failed: ", err)
 	}
 
-	// Create a group with an AccessList that disallows Delete(), check that Delete()
-	// fails.
+	// Create a group with an AccessList that disallows Delete(), check that
+	// Delete() fails.
 	g = groups.GroupClient(naming.JoinAddressName(serverName, "grpC"))
 	acl := access.Permissions{}
 	acl.Add(security.BlessingPattern("server/client"), string(access.Admin))
@@ -276,73 +277,75 @@
 	}
 
 	var aclBefore, aclAfter access.Permissions
-	var etagBefore, etagAfter string
+	var versionBefore, versionAfter string
 
-	getAccessListAndEtagOrDie := func() (access.Permissions, string) {
-		// Doesn't use getEtagOrDie since that requires access.Read permission.
-		acl, etag, err := g.GetPermissions(ctx)
+	getAccessListAndVersionOrDie := func() (access.Permissions, string) {
+		// Doesn't use getVersionOrDie since that requires access.Read permission.
+		acl, version, err := g.GetPermissions(ctx)
 		if err != nil {
 			debug.PrintStack()
 			t.Fatal("GetPermissions failed: ", err)
 		}
-		return acl, etag
+		return acl, version
 	}
 
-	// SetPermissions with bad etag should fail.
-	aclBefore, etagBefore = getAccessListAndEtagOrDie()
-	if err := g.SetPermissions(ctx, myacl, "20"); verror.ErrorID(err) != verror.ErrBadEtag.ID {
-		t.Fatal("SetPermissions should have failed with etag error")
+	// SetPermissions with bad version should fail.
+	aclBefore, versionBefore = getAccessListAndVersionOrDie()
+	if err := g.SetPermissions(ctx, myacl, "20"); verror.ErrorID(err) != verror.ErrBadVersion.ID {
+		t.Fatal("SetPermissions should have failed with version error")
 	}
-	// Since SetPermissions failed, the AccessList and etag should not have changed.
-	aclAfter, etagAfter = getAccessListAndEtagOrDie()
+	// Since SetPermissions failed, the AccessList and version should not have
+	// changed.
+	aclAfter, versionAfter = getAccessListAndVersionOrDie()
 	if !reflect.DeepEqual(aclBefore, aclAfter) {
 		t.Errorf("AccessLists do not match: want %v, got %v", aclBefore, aclAfter)
 	}
-	if etagBefore != etagAfter {
-		t.Errorf("Etags do not match: want %v, got %v", etagBefore, etagAfter)
+	if versionBefore != versionAfter {
+		t.Errorf("Versions do not match: want %v, got %v", versionBefore, versionAfter)
 	}
 
-	// SetPermissions with correct etag should succeed.
-	aclBefore, etagBefore = aclAfter, etagAfter
-	if err := g.SetPermissions(ctx, myacl, etagBefore); err != nil {
+	// SetPermissions with correct version should succeed.
+	aclBefore, versionBefore = aclAfter, versionAfter
+	if err := g.SetPermissions(ctx, myacl, versionBefore); err != nil {
 		t.Fatal("SetPermissions failed: ", err)
 	}
-	// Check that the AccessList and etag actually changed.
-	aclAfter, etagAfter = getAccessListAndEtagOrDie()
+	// Check that the AccessList and version actually changed.
+	aclAfter, versionAfter = getAccessListAndVersionOrDie()
 	if !reflect.DeepEqual(myacl, aclAfter) {
 		t.Errorf("AccessLists do not match: want %v, got %v", myacl, aclAfter)
 	}
-	if etagBefore == etagAfter {
-		t.Errorf("Etags should not match: %v", etagBefore)
+	if versionBefore == versionAfter {
+		t.Errorf("Versions should not match: %v", versionBefore)
 	}
 
-	// SetPermissions with empty etag should succeed.
-	aclBefore, etagBefore = aclAfter, etagAfter
+	// SetPermissions with empty version should succeed.
+	aclBefore, versionBefore = aclAfter, versionAfter
 	myacl.Add(security.BlessingPattern("server/client"), string(access.Read))
 	if err := g.SetPermissions(ctx, myacl, ""); err != nil {
 		t.Fatal("SetPermissions failed: ", err)
 	}
-	// Check that the AccessList and etag actually changed.
-	aclAfter, etagAfter = getAccessListAndEtagOrDie()
+	// Check that the AccessList and version actually changed.
+	aclAfter, versionAfter = getAccessListAndVersionOrDie()
 	if !reflect.DeepEqual(myacl, aclAfter) {
 		t.Errorf("AccessLists do not match: want %v, got %v", myacl, aclAfter)
 	}
-	if etagBefore == etagAfter {
-		t.Errorf("Etags should not match: %v", etagBefore)
+	if versionBefore == versionAfter {
+		t.Errorf("Versions should not match: %v", versionBefore)
 	}
 
-	// SetPermissions with unchanged AccessList should succeed, and etag should still change.
-	aclBefore, etagBefore = aclAfter, etagAfter
+	// SetPermissions with unchanged AccessList should succeed, and version should
+	// still change.
+	aclBefore, versionBefore = aclAfter, versionAfter
 	if err := g.SetPermissions(ctx, myacl, ""); err != nil {
 		t.Fatal("SetPermissions failed: ", err)
 	}
-	// Check that the AccessList did not change and the etag did change.
-	aclAfter, etagAfter = getAccessListAndEtagOrDie()
+	// Check that the AccessList did not change and the version did change.
+	aclAfter, versionAfter = getAccessListAndVersionOrDie()
 	if !reflect.DeepEqual(aclBefore, aclAfter) {
 		t.Errorf("AccessLists do not match: want %v, got %v", aclBefore, aclAfter)
 	}
-	if etagBefore == etagAfter {
-		t.Errorf("Etags should not match: %v", etagBefore)
+	if versionBefore == versionAfter {
+		t.Errorf("Versions should not match: %v", versionBefore)
 	}
 
 	// Take away our access. SetPermissions and GetPermissions should fail.
@@ -373,35 +376,35 @@
 		t.Errorf("Entries do not match: want %v, got %v", want, got)
 	}
 
-	var etagBefore, etagAfter string
-	etagBefore = getEtagOrDie(g, ctx, t)
-	// Add with bad etag should fail.
-	if err := g.Add(ctx, bpc("foo"), "20"); verror.ErrorID(err) != verror.ErrBadEtag.ID {
-		t.Fatal("Add should have failed with etag error")
+	var versionBefore, versionAfter string
+	versionBefore = getVersionOrDie(g, ctx, t)
+	// Add with bad version should fail.
+	if err := g.Add(ctx, bpc("foo"), "20"); verror.ErrorID(err) != verror.ErrBadVersion.ID {
+		t.Fatal("Add should have failed with version error")
 	}
-	// Etag should not have changed.
-	etagAfter = getEtagOrDie(g, ctx, t)
-	if etagBefore != etagAfter {
-		t.Errorf("Etags do not match: want %v, got %v", etagBefore, etagAfter)
+	// Version should not have changed.
+	versionAfter = getVersionOrDie(g, ctx, t)
+	if versionBefore != versionAfter {
+		t.Errorf("Versions do not match: want %v, got %v", versionBefore, versionAfter)
 	}
 
-	// Add an entry, verify it was added and the etag changed.
-	etagBefore = etagAfter
-	if err := g.Add(ctx, bpc("foo"), etagBefore); err != nil {
+	// Add an entry, verify it was added and the version changed.
+	versionBefore = versionAfter
+	if err := g.Add(ctx, bpc("foo"), versionBefore); err != nil {
 		t.Fatal("Add failed: ", err)
 	}
 	want, got = bpcSet("foo"), getEntriesOrDie(g, ctx, t)
 	if !entriesEqual(want, got) {
 		t.Errorf("Entries do not match: want %v, got %v", want, got)
 	}
-	etagAfter = getEtagOrDie(g, ctx, t)
-	if etagBefore == etagAfter {
-		t.Errorf("Etags should not match: %v", etagBefore)
+	versionAfter = getVersionOrDie(g, ctx, t)
+	if versionBefore == versionAfter {
+		t.Errorf("Versions should not match: %v", versionBefore)
 	}
 
-	// Add another entry, verify it was added and the etag changed.
-	etagBefore = etagAfter
-	// Add with empty etag should succeed.
+	// Add another entry, verify it was added and the version changed.
+	versionBefore = versionAfter
+	// Add with empty version should succeed.
 	if err := g.Add(ctx, bpc("bar"), ""); err != nil {
 		t.Fatal("Add failed: ", err)
 	}
@@ -409,27 +412,28 @@
 	if !entriesEqual(want, got) {
 		t.Errorf("Entries do not match: want %v, got %v", want, got)
 	}
-	etagAfter = getEtagOrDie(g, ctx, t)
-	if etagBefore == etagAfter {
-		t.Errorf("Etags should not match: %v", etagBefore)
+	versionAfter = getVersionOrDie(g, ctx, t)
+	if versionBefore == versionAfter {
+		t.Errorf("Versions should not match: %v", versionBefore)
 	}
 
-	// Add "bar" again, verify entries are still ["foo", "bar"] and the etag
+	// Add "bar" again, verify entries are still ["foo", "bar"] and the version
 	// changed.
-	etagBefore = etagAfter
-	if err := g.Add(ctx, bpc("bar"), etagBefore); err != nil {
+	versionBefore = versionAfter
+	if err := g.Add(ctx, bpc("bar"), versionBefore); err != nil {
 		t.Fatal("Add failed: ", err)
 	}
 	want, got = bpcSet("foo", "bar"), getEntriesOrDie(g, ctx, t)
 	if !entriesEqual(want, got) {
 		t.Errorf("Entries do not match: want %v, got %v", want, got)
 	}
-	etagAfter = getEtagOrDie(g, ctx, t)
-	if etagBefore == etagAfter {
-		t.Errorf("Etags should not match: %v", etagBefore)
+	versionAfter = getVersionOrDie(g, ctx, t)
+	if versionBefore == versionAfter {
+		t.Errorf("Versions should not match: %v", versionBefore)
 	}
 
-	// Create a group with an AccessList that disallows Add(), check that Add() fails.
+	// Create a group with an AccessList that disallows Add(), check that Add()
+	// fails.
 	g = groups.GroupClient(naming.JoinAddressName(serverName, "grpB"))
 	acl := access.Permissions{}
 	acl.Add(security.BlessingPattern("server/client"), string(access.Admin))
@@ -458,35 +462,35 @@
 		t.Errorf("Entries do not match: want %v, got %v", want, got)
 	}
 
-	var etagBefore, etagAfter string
-	etagBefore = getEtagOrDie(g, ctx, t)
-	// Remove with bad etag should fail.
-	if err := g.Remove(ctx, bpc("foo"), "20"); verror.ErrorID(err) != verror.ErrBadEtag.ID {
-		t.Fatal("Remove should have failed with etag error")
+	var versionBefore, versionAfter string
+	versionBefore = getVersionOrDie(g, ctx, t)
+	// Remove with bad version should fail.
+	if err := g.Remove(ctx, bpc("foo"), "20"); verror.ErrorID(err) != verror.ErrBadVersion.ID {
+		t.Fatal("Remove should have failed with version error")
 	}
-	// Etag should not have changed.
-	etagAfter = getEtagOrDie(g, ctx, t)
-	if etagBefore != etagAfter {
-		t.Errorf("Etags do not match: want %v, got %v", etagBefore, etagAfter)
+	// Version should not have changed.
+	versionAfter = getVersionOrDie(g, ctx, t)
+	if versionBefore != versionAfter {
+		t.Errorf("Versions do not match: want %v, got %v", versionBefore, versionAfter)
 	}
 
-	// Remove an entry, verify it was removed and the etag changed.
-	etagBefore = etagAfter
-	if err := g.Remove(ctx, bpc("foo"), etagBefore); err != nil {
+	// Remove an entry, verify it was removed and the version changed.
+	versionBefore = versionAfter
+	if err := g.Remove(ctx, bpc("foo"), versionBefore); err != nil {
 		t.Fatal("Remove failed: ", err)
 	}
 	want, got = bpcSet("bar"), getEntriesOrDie(g, ctx, t)
 	if !entriesEqual(want, got) {
 		t.Errorf("Entries do not match: want %v, got %v", want, got)
 	}
-	etagAfter = getEtagOrDie(g, ctx, t)
-	if etagBefore == etagAfter {
-		t.Errorf("Etags should not match: %v", etagBefore)
+	versionAfter = getVersionOrDie(g, ctx, t)
+	if versionBefore == versionAfter {
+		t.Errorf("Versions should not match: %v", versionBefore)
 	}
 
-	// Remove another entry, verify it was removed and the etag changed.
-	etagBefore = etagAfter
-	// Remove with empty etag should succeed.
+	// Remove another entry, verify it was removed and the version changed.
+	versionBefore = versionAfter
+	// Remove with empty version should succeed.
 	if err := g.Remove(ctx, bpc("bar"), ""); err != nil {
 		t.Fatal("Remove failed: ", err)
 	}
@@ -494,27 +498,27 @@
 	if !entriesEqual(want, got) {
 		t.Errorf("Entries do not match: want %v, got %v", want, got)
 	}
-	etagAfter = getEtagOrDie(g, ctx, t)
-	if etagBefore == etagAfter {
-		t.Errorf("Etags should not match: %v", etagBefore)
+	versionAfter = getVersionOrDie(g, ctx, t)
+	if versionBefore == versionAfter {
+		t.Errorf("Versions should not match: %v", versionBefore)
 	}
 
-	// Remove "bar" again, verify entries are still [] and the etag changed.
-	etagBefore = etagAfter
-	if err := g.Remove(ctx, bpc("bar"), etagBefore); err != nil {
+	// Remove "bar" again, verify entries are still [] and the version changed.
+	versionBefore = versionAfter
+	if err := g.Remove(ctx, bpc("bar"), versionBefore); err != nil {
 		t.Fatal("Remove failed: ", err)
 	}
 	want, got = bpcSet(), getEntriesOrDie(g, ctx, t)
 	if !entriesEqual(want, got) {
 		t.Errorf("Entries do not match: want %v, got %v", want, got)
 	}
-	etagAfter = getEtagOrDie(g, ctx, t)
-	if etagBefore == etagAfter {
-		t.Errorf("Etags should not match: %v", etagBefore)
+	versionAfter = getVersionOrDie(g, ctx, t)
+	if versionBefore == versionAfter {
+		t.Errorf("Versions should not match: %v", versionBefore)
 	}
 
-	// Create a group with an AccessList that disallows Remove(), check that Remove()
-	// fails.
+	// Create a group with an AccessList that disallows Remove(), check that
+	// Remove() fails.
 	g = groups.GroupClient(naming.JoinAddressName(serverName, "grpB"))
 	acl := access.Permissions{}
 	acl.Add(security.BlessingPattern("server/client"), string(access.Admin))
diff --git a/services/groups/internal/server/store.go b/services/groups/internal/server/store.go
index b523c65..83f605e 100644
--- a/services/groups/internal/server/store.go
+++ b/services/groups/internal/server/store.go
@@ -4,27 +4,27 @@
 
 package server
 
-// Store is a key-value store that uses etags for optimistic concurrency
-// control. The etags passed to Update and Delete must come from Get. If in the
-// meantime some client has called Update or Delete on the same key, the etag
-// will be stale and the method call will fail.
+// Store is a key-value store that uses versions for optimistic concurrency
+// control. The versions passed to Update and Delete must come from Get. If in
+// the meantime some client has called Update or Delete on the same key, the
+// version will be stale and the method call will fail.
 //
-// Note, this API disallows empty etags to simplify implementation. The group
-// server is the only client of this API and always specifies etags.
+// Note, this API disallows empty versions to simplify implementation. The group
+// server is the only client of this API and always specifies versions.
 type Store interface {
 	// Fails if the given key is unknown (ErrUnknownKey).
-	Get(k string) (v interface{}, etag string, err error)
+	Get(k string) (v interface{}, version string, err error)
 
 	// Fails if an entry already exists for the given key (ErrKeyAlreadyExists).
 	Insert(k string, v interface{}) error
 
 	// Fails if the given key is unknown (ErrUnknownKey).
-	// Fails if etag doesn't match (ErrBadEtag).
-	Update(k string, v interface{}, etag string) error
+	// Fails if version doesn't match (ErrBadVersion).
+	Update(k string, v interface{}, version string) error
 
 	// Fails if the given key is unknown (ErrUnknownKey).
-	// Fails if etag doesn't match (ErrBadEtag).
-	Delete(k string, etag string) error
+	// Fails if version doesn't match (ErrBadVersion).
+	Delete(k string, version string) error
 }
 
 ////////////////////////////////////////
@@ -46,8 +46,8 @@
 	return "key already exists: " + err.Key
 }
 
-type ErrBadEtag struct{}
+type ErrBadVersion struct{}
 
-func (err *ErrBadEtag) Error() string {
-	return "etag is out of date"
+func (err *ErrBadVersion) Error() string {
+	return "version is out of date"
 }
diff --git a/services/internal/acls/aclaccess.go b/services/internal/acls/aclaccess.go
index 2091d4f..9be795e 100644
--- a/services/internal/acls/aclaccess.go
+++ b/services/internal/acls/aclaccess.go
@@ -97,27 +97,26 @@
 		vlog.Errorf("ReadPermissions(%s) failed: %v", aclpath, err)
 		return nil, "", err
 	}
-	etag, err := ComputeEtag(acl)
+	version, err := ComputeVersion(acl)
 	if err != nil {
-		vlog.Errorf("acls.ComputeEtag failed: %v", err)
+		vlog.Errorf("acls.ComputeVersion failed: %v", err)
 		return nil, "", err
 	}
-	return acl, etag, nil
+	return acl, version, nil
 }
 
-// Set writes the specified Permissions to the provided
-// directory with enforcement of etag synchronization mechanism and
-// locking.
-func (store PathStore) Set(dir string, acl access.Permissions, etag string) error {
+// Set writes the specified Permissions to the provided directory with
+// enforcement of version synchronization mechanism and locking.
+func (store PathStore) Set(dir string, acl access.Permissions, version string) error {
 	aclpath := filepath.Join(dir, aclName)
 	sigpath := filepath.Join(dir, sigName)
 	defer store.lockPath(dir)()
-	_, oetag, err := getCore(store.principal, aclpath, sigpath)
+	_, oversion, err := getCore(store.principal, aclpath, sigpath)
 	if err != nil && !os.IsNotExist(err) {
 		return verror.New(ErrOperationFailed, nil)
 	}
-	if len(etag) > 0 && etag != oetag {
-		return verror.NewErrBadEtag(nil)
+	if len(version) > 0 && version != oversion {
+		return verror.NewErrBadVersion(nil)
 	}
 	return write(store.principal, aclpath, sigpath, dir, acl)
 }
diff --git a/services/internal/acls/etag.go b/services/internal/acls/version.go
similarity index 66%
rename from services/internal/acls/etag.go
rename to services/internal/acls/version.go
index 50d84bf..4b8839a 100644
--- a/services/internal/acls/etag.go
+++ b/services/internal/acls/version.go
@@ -14,16 +14,16 @@
 	"v.io/v23/security/access"
 )
 
-// ComputeEtag produces the tag value returned by access.GetPermissions() (per
-// v.io/v23/security/access/service.vdl) that GetPermissions()/SetPermissions()
+// ComputeVersion produces the tag value returned by access.GetPermissions()
+// (per v23/services/permissions/service.vdl) that GetPermissions/SetPermissions
 // use to determine if the AccessLists have been asynchronously modified.
-func ComputeEtag(acl access.Permissions) (string, error) {
+func ComputeVersion(acl access.Permissions) (string, error) {
 	b := new(bytes.Buffer)
 	if err := acl.WriteTo(b); err != nil {
 		return "", err
 	}
 
 	md5hash := md5.Sum(b.Bytes())
-	etag := hex.EncodeToString(md5hash[:])
-	return etag, nil
+	version := hex.EncodeToString(md5hash[:])
+	return version, nil
 }
diff --git a/services/mounttable/mounttablelib/mounttable.go b/services/mounttable/mounttablelib/mounttable.go
index c7a803d..6e1c19d 100644
--- a/services/mounttable/mounttablelib/mounttable.go
+++ b/services/mounttable/mounttablelib/mounttable.go
@@ -733,7 +733,7 @@
 	ch <- naming.GlobReplyEntry{naming.MountEntry{Name: "", Servers: servers}}
 }
 
-func (ms *mountContext) SetPermissions(call rpc.ServerCall, tam access.Permissions, etag string) error {
+func (ms *mountContext) SetPermissions(call rpc.ServerCall, tam access.Permissions, version string) error {
 	vlog.VI(2).Infof("SetPermissions %q", ms.name)
 	mt := ms.mt
 
@@ -748,7 +748,7 @@
 	}
 	n.parent.Unlock()
 	defer n.Unlock()
-	n.acls, err = n.acls.Set(etag, tam)
+	n.acls, err = n.acls.Set(version, tam)
 	if err == nil {
 		n.explicitAccessLists = true
 	}
@@ -769,6 +769,6 @@
 	}
 	n.parent.Unlock()
 	defer n.Unlock()
-	etag, tam := n.acls.Get()
-	return tam, etag, nil
+	version, tam := n.acls.Get()
+	return tam, version, nil
 }
diff --git a/services/mounttable/mounttablelib/mounttable_test.go b/services/mounttable/mounttablelib/mounttable_test.go
index 72e3fcf..300e997 100644
--- a/services/mounttable/mounttablelib/mounttable_test.go
+++ b/services/mounttable/mounttablelib/mounttable_test.go
@@ -72,7 +72,7 @@
 	}
 }
 
-func doGetPermissions(t *testing.T, ctx *context.T, ep, suffix string, shouldSucceed bool) (acl access.Permissions, etag string) {
+func doGetPermissions(t *testing.T, ctx *context.T, ep, suffix string, shouldSucceed bool) (acl access.Permissions, version string) {
 	name := naming.JoinAddressName(ep, suffix)
 	client := v23.GetClient(ctx)
 	call, err := client.StartCall(ctx, name, "GetPermissions", nil, options.NoResolve{})
@@ -82,7 +82,7 @@
 		}
 		boom(t, "Failed to GetPermissions %s: %s", name, err)
 	}
-	if err := call.Finish(&acl, &etag); err != nil {
+	if err := call.Finish(&acl, &version); err != nil {
 		if !shouldSucceed {
 			return
 		}
@@ -91,10 +91,10 @@
 	return
 }
 
-func doSetPermissions(t *testing.T, ctx *context.T, ep, suffix string, acl access.Permissions, etag string, shouldSucceed bool) {
+func doSetPermissions(t *testing.T, ctx *context.T, ep, suffix string, acl access.Permissions, version string, shouldSucceed bool) {
 	name := naming.JoinAddressName(ep, suffix)
 	client := v23.GetClient(ctx)
-	call, err := client.StartCall(ctx, name, "SetPermissions", []interface{}{acl, etag}, options.NoResolve{})
+	call, err := client.StartCall(ctx, name, "SetPermissions", []interface{}{acl, version}, options.NoResolve{})
 	if err != nil {
 		if !shouldSucceed {
 			return
@@ -311,14 +311,14 @@
 	checkContents(t, bobCtx, naming.JoinAddressName(mtAddr, "a/b/falls"), "falls mainly on the plain", false)
 
 	// Test getting/setting AccessLists.
-	acl, etag := doGetPermissions(t, rootCtx, mtAddr, "stuff", true)
-	doSetPermissions(t, rootCtx, mtAddr, "stuff", acl, "xyzzy", false) // bad etag
-	doSetPermissions(t, rootCtx, mtAddr, "stuff", acl, etag, true)     // good etag
-	_, netag := doGetPermissions(t, rootCtx, mtAddr, "stuff", true)
-	if netag == etag {
-		boom(t, "etag didn't change after SetPermissions: %s", netag)
+	acl, version := doGetPermissions(t, rootCtx, mtAddr, "stuff", true)
+	doSetPermissions(t, rootCtx, mtAddr, "stuff", acl, "xyzzy", false) // bad version
+	doSetPermissions(t, rootCtx, mtAddr, "stuff", acl, version, true)  // correct version
+	_, nversion := doGetPermissions(t, rootCtx, mtAddr, "stuff", true)
+	if nversion == version {
+		boom(t, "version didn't change after SetPermissions: %s", nversion)
 	}
-	doSetPermissions(t, rootCtx, mtAddr, "stuff", acl, "", true) // no etag
+	doSetPermissions(t, rootCtx, mtAddr, "stuff", acl, "", true) // no version
 
 	// Bob should be able to create nodes under the mounttable root but not alice.
 	doSetPermissions(t, aliceCtx, mtAddr, "onlybob", acl, "", false)
diff --git a/services/mounttable/mounttablelib/neighborhood.go b/services/mounttable/mounttablelib/neighborhood.go
index 15e2d4f..3be9878 100644
--- a/services/mounttable/mounttablelib/neighborhood.go
+++ b/services/mounttable/mounttablelib/neighborhood.go
@@ -290,10 +290,10 @@
 	}
 }
 
-func (*neighborhoodService) SetPermissions(call rpc.ServerCall, acl access.Permissions, etag string) error {
+func (*neighborhoodService) SetPermissions(call rpc.ServerCall, acl access.Permissions, version string) error {
 	return verror.New(errDoesntImplementSetPermissions, call.Context())
 }
 
-func (*neighborhoodService) GetPermissions(call rpc.ServerCall) (acl access.Permissions, etag string, err error) {
+func (*neighborhoodService) GetPermissions(call rpc.ServerCall) (acl access.Permissions, version string, err error) {
 	return nil, "", nil
 }
diff --git a/services/mounttable/mounttablelib/tamg.go b/services/mounttable/mounttablelib/tamg.go
index c421205..26a8597 100644
--- a/services/mounttable/mounttablelib/tamg.go
+++ b/services/mounttable/mounttablelib/tamg.go
@@ -31,10 +31,10 @@
 	if len(genstr) > 0 {
 		gen, err := strconv.ParseInt(genstr, 10, 32)
 		if err != nil {
-			return b, verror.NewErrBadEtag(nil)
+			return b, verror.NewErrBadVersion(nil)
 		}
 		if gen >= 0 && int32(gen) != b.generation {
-			return b, verror.NewErrBadEtag(nil)
+			return b, verror.NewErrBadVersion(nil)
 		}
 	}
 	b.tam = tam
diff --git a/services/wspr/internal/namespace/namespace.vdl b/services/wspr/internal/namespace/namespace.vdl
index bfb3849..9e06768 100644
--- a/services/wspr/internal/namespace/namespace.vdl
+++ b/services/wspr/internal/namespace/namespace.vdl
@@ -36,9 +36,9 @@
 	// SetRoots sets the current mounttable roots.
 	SetRoots(roots []string) error
 	// SetPermissions sets the AccessList in a node in a mount table.
-	SetPermissions(name string, acl access.Permissions, etag string) error
+	SetPermissions(name string, acl access.Permissions, version string) error
 	// GetPermissions returns the AccessList in a node in a mount table.
-	GetPermissions(name string) (acl access.Permissions, etag string | error)
+	GetPermissions(name string) (acl access.Permissions, version string | error)
 	// Delete deletes the name from the mounttable and, if requested, any subtree.
 	Delete(name string, deleteSubtree bool) error
 }
diff --git a/services/wspr/internal/namespace/namespace.vdl.go b/services/wspr/internal/namespace/namespace.vdl.go
index a15e808..cfe0fc8 100644
--- a/services/wspr/internal/namespace/namespace.vdl.go
+++ b/services/wspr/internal/namespace/namespace.vdl.go
@@ -48,9 +48,9 @@
 	// SetRoots sets the current mounttable roots.
 	SetRoots(ctx *context.T, roots []string, opts ...rpc.CallOpt) error
 	// SetPermissions sets the AccessList in a node in a mount table.
-	SetPermissions(ctx *context.T, name string, acl access.Permissions, etag string, opts ...rpc.CallOpt) error
+	SetPermissions(ctx *context.T, name string, acl access.Permissions, version string, opts ...rpc.CallOpt) error
 	// GetPermissions returns the AccessList in a node in a mount table.
-	GetPermissions(ctx *context.T, name string, opts ...rpc.CallOpt) (acl access.Permissions, etag string, err error)
+	GetPermissions(ctx *context.T, name string, opts ...rpc.CallOpt) (acl access.Permissions, version string, err error)
 	// Delete deletes the name from the mounttable and, if requested, any subtree.
 	Delete(ctx *context.T, name string, deleteSubtree bool, opts ...rpc.CallOpt) error
 }
@@ -269,9 +269,9 @@
 	// SetRoots sets the current mounttable roots.
 	SetRoots(call rpc.ServerCall, roots []string) error
 	// SetPermissions sets the AccessList in a node in a mount table.
-	SetPermissions(call rpc.ServerCall, name string, acl access.Permissions, etag string) error
+	SetPermissions(call rpc.ServerCall, name string, acl access.Permissions, version string) error
 	// GetPermissions returns the AccessList in a node in a mount table.
-	GetPermissions(call rpc.ServerCall, name string) (acl access.Permissions, etag string, err error)
+	GetPermissions(call rpc.ServerCall, name string) (acl access.Permissions, version string, err error)
 	// Delete deletes the name from the mounttable and, if requested, any subtree.
 	Delete(call rpc.ServerCall, name string, deleteSubtree bool) error
 }
@@ -301,9 +301,9 @@
 	// SetRoots sets the current mounttable roots.
 	SetRoots(call rpc.ServerCall, roots []string) error
 	// SetPermissions sets the AccessList in a node in a mount table.
-	SetPermissions(call rpc.ServerCall, name string, acl access.Permissions, etag string) error
+	SetPermissions(call rpc.ServerCall, name string, acl access.Permissions, version string) error
 	// GetPermissions returns the AccessList in a node in a mount table.
-	GetPermissions(call rpc.ServerCall, name string) (acl access.Permissions, etag string, err error)
+	GetPermissions(call rpc.ServerCall, name string) (acl access.Permissions, version string, err error)
 	// Delete deletes the name from the mounttable and, if requested, any subtree.
 	Delete(call rpc.ServerCall, name string, deleteSubtree bool) error
 }
@@ -481,9 +481,9 @@
 			Name: "SetPermissions",
 			Doc:  "// SetPermissions sets the AccessList in a node in a mount table.",
 			InArgs: []rpc.ArgDesc{
-				{"name", ``}, // string
-				{"acl", ``},  // access.Permissions
-				{"etag", ``}, // string
+				{"name", ``},    // string
+				{"acl", ``},     // access.Permissions
+				{"version", ``}, // string
 			},
 		},
 		{
@@ -493,8 +493,8 @@
 				{"name", ``}, // string
 			},
 			OutArgs: []rpc.ArgDesc{
-				{"acl", ``},  // access.Permissions
-				{"etag", ``}, // string
+				{"acl", ``},     // access.Permissions
+				{"version", ``}, // string
 			},
 		},
 		{
diff --git a/services/wspr/internal/namespace/request_handler.go b/services/wspr/internal/namespace/request_handler.go
index ca8c62e..6112c90 100644
--- a/services/wspr/internal/namespace/request_handler.go
+++ b/services/wspr/internal/namespace/request_handler.go
@@ -98,8 +98,8 @@
 	return nil
 }
 
-func (s *Server) SetPermissions(call rpc.ServerCall, name string, acl access.Permissions, etag string) error {
-	return s.ns.SetPermissions(call.Context(), name, acl, etag)
+func (s *Server) SetPermissions(call rpc.ServerCall, name string, acl access.Permissions, version string) error {
+	return s.ns.SetPermissions(call.Context(), name, acl, version)
 }
 
 func (s *Server) GetPermissions(call rpc.ServerCall, name string) (access.Permissions, string, error) {