code: func vetDeregisterWithACL(rule acl.Authorizer, subj *structs.DeregisterRequest,
  	ns *structs.NodeService, nc *structs.HealthCheck) error {
  
  	// Fast path if ACLs are not enabled.
  	if rule == nil {
  		return nil
  	}
  
  	// We don't apply sentinel in this path, since at this time sentinel
  	// only applies to create and update operations.
  
  	// This order must match the code in applyRegister() in fsm.go since it
  	// also evaluates things in this order, and will ignore fields based on
  	// this precedence. This lets us also ignore them from an ACL perspective.
  	if subj.ServiceID != "" {
  		if ns == nil {
  			return fmt.Errorf("Unknown service '%s'", subj.ServiceID)
  		}
  		if !rule.ServiceWrite(ns.Service, nil) {
  			return acl.ErrPermissionDenied
  		}
  	} else if subj.CheckID != "" {
  		if nc == nil {
  			return fmt.Errorf("Unknown check '%s'", subj.CheckID)
  		}
  		if nc.ServiceID != "" {
  			if !rule.ServiceWrite(nc.ServiceName, nil) {
  				return acl.ErrPermissionDenied
  			}
  		} else {
  			if !rule.NodeWrite(subj.Node, nil) {
  				return acl.ErrPermissionDenied
  			}
  		}
  	} else {
  		if !rule.NodeWrite(subj.Node, nil) {
  			return acl.ErrPermissionDenied
  		}
  	}
  
  	return nil
  }
docs: // vetDeregisterWithACL applies the given ACL's policy to the catalog update and
  // determines if it is allowed. Since the catalog deregister request is so
  // dynamic, this is a pretty complex algorithm and was worth breaking out of the
  // endpoint. The NodeService for the referenced service must be supplied, and can
  // be nil; similar for the HealthCheck for the referenced health check.