diff --git a/cmd/zrok/access_private.go b/cmd/zrok/access_private.go
index d5b0e833..77cf3ed7 100644
--- a/cmd/zrok/access_private.go
+++ b/cmd/zrok/access_private.go
@@ -60,13 +60,14 @@ func (cmd *accessPrivateCommand) run(_ *cobra.Command, args []string) {
 		SvcName: svcName,
 		ZID:     env.ZId,
 	}
-	_, err = zrok.Service.Access(req, auth)
+	accessResp, err := zrok.Service.Access(req, auth)
 	if err != nil {
 		if !panicInstead {
 			showError("unable to access", err)
 		}
 		panic(err)
 	}
+	logrus.Infof("allocated frontend '%v'", accessResp.Payload.FrontendName)
 
 	cfg := private_frontend.DefaultConfig("backend")
 	cfg.SvcName = svcName
@@ -76,7 +77,7 @@ func (cmd *accessPrivateCommand) run(_ *cobra.Command, args []string) {
 	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
 	go func() {
 		<-c
-		cmd.destroy(env.ZId, svcName, zrok, auth)
+		cmd.destroy(accessResp.Payload.FrontendName, env.ZId, svcName, zrok, auth)
 		os.Exit(0)
 	}()
 
@@ -94,12 +95,13 @@ func (cmd *accessPrivateCommand) run(_ *cobra.Command, args []string) {
 	}
 }
 
-func (cmd *accessPrivateCommand) destroy(envZId, svcName string, zrok *rest_client_zrok.Zrok, auth runtime.ClientAuthInfoWriter) {
+func (cmd *accessPrivateCommand) destroy(frotendName, envZId, svcName string, zrok *rest_client_zrok.Zrok, auth runtime.ClientAuthInfoWriter) {
 	logrus.Debugf("shutting down '%v'", svcName)
 	req := service.NewUnaccessParams()
 	req.Body = &rest_model_zrok.UnaccessRequest{
-		SvcName: svcName,
-		ZID:     envZId,
+		FrontendName: frotendName,
+		SvcName:      svcName,
+		ZID:          envZId,
 	}
 	if _, err := zrok.Service.Unaccess(req, auth); err == nil {
 		logrus.Debugf("shutdown complete")
diff --git a/controller/store/frontend.go b/controller/store/frontend.go
index db198425..64ca6312 100644
--- a/controller/store/frontend.go
+++ b/controller/store/frontend.go
@@ -41,6 +41,14 @@ func (str *Store) FindFrontendNamed(name string, tx *sqlx.Tx) (*Frontend, error)
 	return i, nil
 }
 
+func (str *Store) FindFrontendPubliclyNamed(publicName string, tx *sqlx.Tx) (*Frontend, error) {
+	i := &Frontend{}
+	if err := tx.QueryRowx("select frontends.* from frontends where public_name = $1", publicName).StructScan(i); err != nil {
+		return nil, errors.Wrap(err, "error selecting frontend by public_name")
+	}
+	return i, nil
+}
+
 func (str *Store) FindFrontendsForEnvironment(envId int, tx *sqlx.Tx) ([]*Frontend, error) {
 	rows, err := tx.Queryx("select frontends.* from frontends where environment_id = $1", envId)
 	if err != nil {
diff --git a/controller/store/frontend_test.go b/controller/store/frontend_test.go
index a6e9d417..1a4388b8 100644
--- a/controller/store/frontend_test.go
+++ b/controller/store/frontend_test.go
@@ -31,8 +31,9 @@ func TestPublicFrontend(t *testing.T) {
 
 	feName := "public"
 	feId, err := str.CreateFrontend(envId, &Frontend{
-		ZId:  "zId0",
-		Name: &feName,
+		Name:       "name",
+		ZId:        "zId0",
+		PublicName: &feName,
 	}, tx)
 	assert.Nil(t, err)
 
@@ -40,9 +41,9 @@ func TestPublicFrontend(t *testing.T) {
 	assert.Nil(t, err)
 	assert.NotNil(t, fe)
 	assert.Equal(t, envId, fe.EnvironmentId)
-	assert.Equal(t, feName, *fe.Name)
+	assert.Equal(t, feName, *fe.PublicName)
 
-	fe0, err := str.FindFrontendNamed(feName, tx)
+	fe0, err := str.FindFrontendPubliclyNamed(feName, tx)
 	assert.Nil(t, err)
 	assert.NotNil(t, fe0)
 	assert.EqualValues(t, fe, fe0)
diff --git a/controller/unaccess.go b/controller/unaccess.go
index 0af8797a..50b2d91a 100644
--- a/controller/unaccess.go
+++ b/controller/unaccess.go
@@ -17,8 +17,10 @@ func newUnaccessHandler() *unaccessHandler {
 }
 
 func (h *unaccessHandler) Handle(params service.UnaccessParams, principal *rest_model_zrok.Principal) middleware.Responder {
+	frontendName := params.Body.FrontendName
 	svcName := params.Body.SvcName
 	envZId := params.Body.ZID
+	logrus.Infof("processing unaccess request for frontend '%v' (service '%v', environment '%v')", frontendName, svcName, envZId)
 
 	tx, err := str.Begin()
 	if err != nil {
@@ -51,10 +53,31 @@ func (h *unaccessHandler) Handle(params service.UnaccessParams, principal *rest_
 		return service.NewUnaccessUnauthorized()
 	}
 
-	if err := deleteServicePolicy(envZId, fmt.Sprintf("tags.zrokServiceName=\"%v\" and tags.zrokEnvironmentZId=\"%v\" and type=1", svcName, envZId), edge); err != nil {
+	sfe, err := str.FindFrontendNamed(frontendName, tx)
+	if err != nil {
+		logrus.Error(err)
+		return service.NewUnaccessInternalServerError()
+	}
+
+	if sfe == nil || sfe.EnvironmentId != senv.Id {
+		logrus.Errorf("frontend named '%v' not found", frontendName)
+		return service.NewUnaccessInternalServerError()
+	}
+
+	if err := str.DeleteFrontend(sfe.Id, tx); err != nil {
+		logrus.Errorf("error deleting frontend named '%v': %v", frontendName, err)
+		return service.NewUnaccessNotFound()
+	}
+
+	if err := deleteServicePolicy(envZId, fmt.Sprintf("tags.zrokServiceName=\"%v\" and tags.zrokFrontendName=\"%v\" and type=1", svcName, frontendName), edge); err != nil {
 		logrus.Errorf("error removing access to '%v' for '%v': %v", svcName, envZId, err)
 		return service.NewUnaccessInternalServerError()
 	}
 
+	if err := tx.Commit(); err != nil {
+		logrus.Errorf("error committing frontend '%v' delete: %v", frontendName, err)
+		return service.NewUnaccessInternalServerError()
+	}
+
 	return service.NewUnaccessOK()
 }
diff --git a/rest_model_zrok/unaccess_request.go b/rest_model_zrok/unaccess_request.go
index 56a58fec..27536aa0 100644
--- a/rest_model_zrok/unaccess_request.go
+++ b/rest_model_zrok/unaccess_request.go
@@ -17,6 +17,9 @@ import (
 // swagger:model unaccessRequest
 type UnaccessRequest struct {
 
+	// frontend name
+	FrontendName string `json:"frontendName,omitempty"`
+
 	// svc name
 	SvcName string `json:"svcName,omitempty"`
 
diff --git a/rest_server_zrok/embedded_spec.go b/rest_server_zrok/embedded_spec.go
index c74b6c18..47e6ed58 100644
--- a/rest_server_zrok/embedded_spec.go
+++ b/rest_server_zrok/embedded_spec.go
@@ -701,6 +701,9 @@ func init() {
     "unaccessRequest": {
       "type": "object",
       "properties": {
+        "frontendName": {
+          "type": "string"
+        },
         "svcName": {
           "type": "string"
         },
@@ -1432,6 +1435,9 @@ func init() {
     "unaccessRequest": {
       "type": "object",
       "properties": {
+        "frontendName": {
+          "type": "string"
+        },
         "svcName": {
           "type": "string"
         },
diff --git a/specs/zrok.yml b/specs/zrok.yml
index 3ab3c134..b01543ca 100644
--- a/specs/zrok.yml
+++ b/specs/zrok.yml
@@ -454,6 +454,8 @@ definitions:
   unaccessRequest:
     type: object
     properties:
+      frontendName:
+        type: string
       zId:
         type: string
       svcName:
diff --git a/ui/src/api/types.js b/ui/src/api/types.js
index 6aaf5f60..2da429a1 100644
--- a/ui/src/api/types.js
+++ b/ui/src/api/types.js
@@ -145,6 +145,7 @@
  * @typedef unaccessRequest
  * @memberof module:types
  * 
+ * @property {string} frontendName 
  * @property {string} zId 
  * @property {string} svcName 
  */