diff --git a/lib/constants.py b/lib/constants.py
index 4fa186e9f62be332f0136f1e656e0163686f6fee..92c3523b72eefe507d6da3e2676129f5a061de16 100644
--- a/lib/constants.py
+++ b/lib/constants.py
@@ -670,6 +670,7 @@ HV_VNC_X509 = "vnc_x509_path"
 HV_VNC_X509_VERIFY = "vnc_x509_verify"
 HV_KVM_SPICE_BIND = "spice_bind"
 HV_KVM_SPICE_IP_VERSION = "spice_ip_version"
+HV_KVM_SPICE_PASSWORD_FILE = "spice_password_file"
 HV_ACPI = "acpi"
 HV_PAE = "pae"
 HV_USE_BOOTLOADER = "use_bootloader"
@@ -715,6 +716,7 @@ HVS_PARAMETER_TYPES = {
   HV_VNC_X509_VERIFY: VTYPE_BOOL,
   HV_KVM_SPICE_BIND: VTYPE_STRING,
   HV_KVM_SPICE_IP_VERSION: VTYPE_INT,
+  HV_KVM_SPICE_PASSWORD_FILE: VTYPE_STRING,
   HV_ACPI: VTYPE_BOOL,
   HV_PAE: VTYPE_BOOL,
   HV_USE_BOOTLOADER: VTYPE_BOOL,
@@ -1295,6 +1297,7 @@ HVC_DEFAULTS = {
     HV_VNC_PASSWORD_FILE: "",
     HV_KVM_SPICE_BIND: "",
     HV_KVM_SPICE_IP_VERSION: IFACE_NO_IP_VERSION_SPECIFIED,
+    HV_KVM_SPICE_PASSWORD_FILE: "",
     HV_KVM_FLOPPY_IMAGE_PATH: "",
     HV_CDROM_IMAGE_PATH: "",
     HV_KVM_CDROM2_IMAGE_PATH: "",
diff --git a/lib/hypervisor/hv_kvm.py b/lib/hypervisor/hv_kvm.py
index 6aa2374a42a9d5037f37df549125ab5b77f613f2..fe9b9c877e5284dbbe5bdc1ad0599ed815ae9c55 100644
--- a/lib/hypervisor/hv_kvm.py
+++ b/lib/hypervisor/hv_kvm.py
@@ -418,6 +418,7 @@ class KVMHypervisor(hv_base.BaseHypervisor):
                          x in constants.VALID_IP_VERSIONS),
        "the SPICE IP version should be 4 or 6",
        None, None),
+    constants.HV_KVM_SPICE_PASSWORD_FILE: hv_base.OPT_FILE_CHECK,
     constants.HV_KVM_FLOPPY_IMAGE_PATH: hv_base.OPT_FILE_CHECK,
     constants.HV_CDROM_IMAGE_PATH: hv_base.OPT_FILE_CHECK,
     constants.HV_KVM_CDROM2_IMAGE_PATH: hv_base.OPT_FILE_CHECK,
@@ -1015,8 +1016,10 @@ class KVMHypervisor(hv_base.BaseHypervisor):
         # ValidateParameters checked it.
         spice_address = spice_bind
 
-      spice_arg = "addr=%s,port=%s,disable-ticketing" % (spice_address,
-                                                         instance.network_port)
+      spice_arg = "addr=%s,port=%s" % (spice_address, instance.network_port)
+      if not hvp[constants.HV_KVM_SPICE_PASSWORD_FILE]:
+        spice_arg = "%s,disable-ticketing" % spice_arg
+
       if spice_ip_version:
         spice_arg = "%s,ipv%s" % (spice_arg, spice_ip_version)
 
@@ -1236,6 +1239,26 @@ class KVMHypervisor(hv_base.BaseHypervisor):
       change_cmd = "change vnc password %s" % vnc_pwd
       self._CallMonitorCommand(instance.name, change_cmd)
 
+    # Setting SPICE password. We are not vulnerable to malicious passwordless
+    # connection attempts because SPICE by default does not allow connections
+    # if neither a password nor the "disable_ticketing" options are specified.
+    # As soon as we send the password via QMP, that password is a valid ticket
+    # for connection.
+    spice_password_file = conf_hvp[constants.HV_KVM_SPICE_PASSWORD_FILE]
+    if spice_password_file:
+      try:
+        spice_pwd = utils.ReadOneLineFile(spice_password_file, strict=True)
+        qmp = QmpConnection(self._InstanceQmpMonitor(instance.name))
+        qmp.connect()
+        arguments = {
+            "protocol": "spice",
+            "password": spice_pwd,
+        }
+        qmp.Execute("set_password", arguments)
+      except EnvironmentError, err:
+        raise errors.HypervisorError("Failed to open SPICE password file %s: %s"
+                                     % (spice_password_file, err))
+
     for filename in temp_files:
       utils.RemoveFile(filename)
 
@@ -1558,8 +1581,9 @@ class KVMHypervisor(hv_base.BaseHypervisor):
                                      " security model is 'none' or 'pool'")
 
     spice_bind = hvparams[constants.HV_KVM_SPICE_BIND]
+    spice_ip_version = hvparams[constants.HV_KVM_SPICE_IP_VERSION]
+    spice_password_file = hvparams[constants.HV_KVM_SPICE_PASSWORD_FILE]
     if spice_bind:
-      spice_ip_version = hvparams[constants.HV_KVM_SPICE_IP_VERSION]
       if spice_ip_version != constants.IFACE_NO_IP_VERSION_SPECIFIED:
         # if an IP version is specified, the spice_bind parameter must be an
         # IP of that family
@@ -1574,6 +1598,17 @@ class KVMHypervisor(hv_base.BaseHypervisor):
           raise errors.HypervisorError("spice: got an IPv6 address (%s), but"
                                        " the specified IP version is %s" %
                                        (spice_bind, spice_ip_version))
+    else:
+      if spice_ip_version:
+        raise errors.HypervisorError("spice: the %s option is useless"
+                                     " without %s" %
+                                     (constants.HV_KVM_SPICE_IP_VERSION,
+                                      constants.HV_KVM_SPICE_BIND))
+      if spice_password_file:
+        raise errors.HypervisorError("spice: the %s option is useless"
+                                     " without %s" %
+                                     (constants.HV_KVM_SPICE_PASSWORD_FILE,
+                                      constants.HV_KVM_SPICE_BIND))
 
   @classmethod
   def ValidateParameters(cls, hvparams):
diff --git a/man/gnt-instance.rst b/man/gnt-instance.rst
index 5d906a40399a1bec58936ba33251b34faa492bd3..c3a0c920a050674a009d423c66b902c0540f9558 100644
--- a/man/gnt-instance.rst
+++ b/man/gnt-instance.rst
@@ -300,6 +300,13 @@ spice\_ip\_version
     this case, if the ``spice_ip_version`` parameter is not used, the
     default IP version of the cluster will be used.
 
+spice\_password\_file
+    Valid for the KVM hypervisor.
+
+    Specifies a file containing the password that must be used when
+    connecting via the SPICE protocol. If the option is not specified,
+    passwordless connections are allowed.
+
 acpi
     Valid for the Xen HVM and KVM hypervisors.