Signed-off-by: Erik Skultety <eskultet(a)redhat.com>
---
docs/aclpolkit.html.in | 523 -----------------------------------------
docs/aclpolkit.rst | 310 ++++++++++++++++++++++++
docs/meson.build | 2 +-
3 files changed, 311 insertions(+), 524 deletions(-)
delete mode 100644 docs/aclpolkit.html.in
create mode 100644 docs/aclpolkit.rst
diff --git a/docs/aclpolkit.html.in b/docs/aclpolkit.html.in
deleted file mode 100644
index a82001187e..0000000000
--- a/docs/aclpolkit.html.in
+++ /dev/null
@@ -1,523 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html>
-<html
xmlns="http://www.w3.org/1999/xhtml">
- <body>
- <h1>Polkit access control</h1>
-
- <p>
- Libvirt's client <a href="acl.html">access control
framework</a> allows
- administrators to setup fine grained permission rules across client users,
- managed objects and API operations. This allows client connections
- to be locked down to a minimal set of privileges. The polkit driver
- provides a simple implementation of the access control framework.
- </p>
-
- <ul id="toc"></ul>
-
- <h2><a id="intro">Introduction</a></h2>
-
- <p>
- A default install of libvirt will typically use
- <a
href="https://www.freedesktop.org/wiki/Software/polkit/">pol...
- to authenticate the initial user connection to libvirtd. This is a
- very coarse grained check though, either allowing full read-write
- access to all APIs, or just read-only access. The polkit access
- control driver in libvirt builds on this capability to allow for
- fine grained control over the operations a user may perform on an
- object.
- </p>
-
- <h2><a id="perms">Permission names</a></h2>
-
- <p>
- The libvirt <a href="acl.html#perms">object names and permission
names</a>
- are mapped onto polkit action names using the simple pattern:
- </p>
-
- <pre>org.libvirt.api.$object.$permission
-</pre>
-
- <p>
- The only caveat is that any underscore characters in the
- object or permission names are converted to hyphens. So,
- for example, the <code>search_storage_vols</code> permission
- on the <code>storage_pool</code> object maps to the polkit
- action:
- </p>
- <pre>org.libvirt.api.storage-pool.search-storage-vols
-</pre>
-
- <p>
- The default policy for any permission which corresponds to
- a "read only" operation, is to allow access. All other
- permissions default to deny access.
- </p>
-
- <h2><a id="attrs">Object identity
attributes</a></h2>
-
- <p>
- To allow polkit authorization rules to be written to match
- against individual object instances, libvirt provides a number
- of authorization detail attributes when performing a permission
- check. The set of attributes varies according to the type
- of object being checked
- </p>
-
- <h3><a id="object_connect">virConnectPtr</a></h3>
- <table>
- <thead>
- <tr>
- <th>Attribute</th>
- <th>Description</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>connect_driver</td>
- <td>Name of the libvirt connection driver</td>
- </tr>
- </tbody>
- </table>
-
- <h3><a id="object_domain">virDomainPtr</a></h3>
- <table>
- <thead>
- <tr>
- <th>Attribute</th>
- <th>Description</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>connect_driver</td>
- <td>Name of the libvirt connection driver</td>
- </tr>
- <tr>
- <td>domain_name</td>
- <td>Name of the domain, unique to the local host</td>
- </tr>
- <tr>
- <td>domain_uuid</td>
- <td>UUID of the domain, globally unique</td>
- </tr>
- </tbody>
- </table>
-
- <h3><a
id="object_interface">virInterfacePtr</a></h3>
- <table>
- <thead>
- <tr>
- <th>Attribute</th>
- <th>Description</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>connect_driver</td>
- <td>Name of the libvirt connection driver</td>
- </tr>
- <tr>
- <td>interface_name</td>
- <td>Name of the network interface, unique to the local host</td>
- </tr>
- <tr>
- <td>interface_macaddr</td>
- <td>MAC address of the network interface, not unique</td>
- </tr>
- </tbody>
- </table>
-
- <h3><a id="object_network">virNetworkPtr</a></h3>
- <table>
- <thead>
- <tr>
- <th>Attribute</th>
- <th>Description</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>connect_driver</td>
- <td>Name of the libvirt connection driver</td>
- </tr>
- <tr>
- <td>network_name</td>
- <td>Name of the network, unique to the local host</td>
- </tr>
- <tr>
- <td>network_uuid</td>
- <td>UUID of the network, globally unique</td>
- </tr>
- </tbody>
- </table>
-
- <h3><a
id="object_node_device">virNodeDevicePtr</a></h3>
- <table>
- <thead>
- <tr>
- <th>Attribute</th>
- <th>Description</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>connect_driver</td>
- <td>Name of the libvirt connection driver</td>
- </tr>
- <tr>
- <td>node_device_name</td>
- <td>Name of the node device, unique to the local host</td>
- </tr>
- </tbody>
- </table>
-
- <h3><a
id="object_nwfilter">virNWFilterPtr</a></h3>
- <table>
- <thead>
- <tr>
- <th>Attribute</th>
- <th>Description</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>connect_driver</td>
- <td>Name of the libvirt connection driver</td>
- </tr>
- <tr>
- <td>nwfilter_name</td>
- <td>Name of the network filter, unique to the local host</td>
- </tr>
- <tr>
- <td>nwfilter_uuid</td>
- <td>UUID of the network filter, globally unique</td>
- </tr>
- </tbody>
- </table>
-
- <h3><a id="object_secret">virSecretPtr</a></h3>
- <table>
- <thead>
- <tr>
- <th>Attribute</th>
- <th>Description</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>connect_driver</td>
- <td>Name of the libvirt connection driver</td>
- </tr>
- <tr>
- <td>secret_uuid</td>
- <td>UUID of the secret, globally unique</td>
- </tr>
- <tr>
- <td>secret_usage_volume</td>
- <td>Name of the associated volume, if any</td>
- </tr>
- <tr>
- <td>secret_usage_ceph</td>
- <td>Name of the associated Ceph server, if any</td>
- </tr>
- <tr>
- <td>secret_usage_target</td>
- <td>Name of the associated iSCSI target, if any</td>
- </tr>
- <tr>
- <td>secret_usage_name</td>
- <td>Name of the associated TLS secret, if any</td>
- </tr>
- </tbody>
- </table>
-
- <h3><a
id="object_storage_pool">virStoragePoolPtr</a></h3>
- <table>
- <thead>
- <tr>
- <th>Attribute</th>
- <th>Description</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>connect_driver</td>
- <td>Name of the libvirt connection driver</td>
- </tr>
- <tr>
- <td>pool_name</td>
- <td>Name of the storage pool, unique to the local host</td>
- </tr>
- <tr>
- <td>pool_uuid</td>
- <td>UUID of the storage pool, globally unique</td>
- </tr>
- </tbody>
- </table>
-
- <h3><a
id="object_storage_vol">virStorageVolPtr</a></h3>
- <table>
- <thead>
- <tr>
- <th>Attribute</th>
- <th>Description</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>connect_driver</td>
- <td>Name of the libvirt connection driver</td>
- </tr>
- <tr>
- <td>pool_name</td>
- <td>Name of the storage pool, unique to the local host</td>
- </tr>
- <tr>
- <td>pool_uuid</td>
- <td>UUID of the storage pool, globally unique</td>
- </tr>
- <tr>
- <td>vol_name</td>
- <td>Name of the storage volume, unique to the pool</td>
- </tr>
- <tr>
- <td>vol_key</td>
- <td>Key of the storage volume, globally unique</td>
- </tr>
- </tbody>
- </table>
-
- <h2><a id="connect_driver">Hypervisor Driver
connect_driver</a></h2>
- <p>
- The <code>connect_driver</code> parameter describes the
- client's <a href="remote.html">remote Connection
Driver</a>
- name based on the <a href="uri.html">URI</a> used for the
- connection.
- </p>
- <p>
- <span class="since">Since 4.1.0</span>, when calling an API
- outside the scope of the primary connection driver, the
- primary driver will attempt to open a secondary connection
- to the specific API driver in order to process the API. For
- example, when hypervisor domain processing needs to make an
- API call within the storage driver or the network filter driver
- an attempt to open a connection to the "storage" or "nwfilter"
- driver will be made. Similarly, a "storage" primary connection
- may need to create a connection to the "secret" driver in order
- to process secrets for the API. If successful, then calls to
- those API's will occur in the <code>connect_driver</code> context
- of the secondary connection driver rather than in the context of
- the primary driver. This affects the <code>connect_driver</code>
- returned from rule generation from the <code>action.loookup</code>
- function. The following table provides a list of the various
- connection drivers and the <code>connect_driver</code> name
- used by each regardless of primary or secondary connection.
- The access denied error message from libvirt will list the
- connection driver by name that denied the access.
- </p>
-
- <h3><a id="object_connect_driver">Connection Driver
Name</a></h3>
- <table>
- <thead>
- <tr>
- <th>Connection Driver</th>
- <th><code>connect_driver</code> name</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>bhyve</td>
- <td>bhyve</td>
- </tr>
- <tr>
- <td>esx</td>
- <td>ESX</td>
- </tr>
- <tr>
- <td>hyperv</td>
- <td>Hyper-V</td>
- </tr>
- <tr>
- <td>interface</td>
- <td>interface</td>
- </tr>
- <tr>
- <td>xen</td>
- <td>Xen</td>
- </tr>
- <tr>
- <td>lxc</td>
- <td>LXC</td>
- </tr>
- <tr>
- <td>network</td>
- <td>network</td>
- </tr>
- <tr>
- <td>nodedev</td>
- <td>nodedev</td>
- </tr>
- <tr>
- <td>nwfilter</td>
- <td>NWFilter</td>
- </tr>
- <tr>
- <td>openvz</td>
- <td>OPENVZ</td>
- </tr>
- <tr>
- <td>qemu</td>
- <td>QEMU</td>
- </tr>
- <tr>
- <td>secret</td>
- <td>secret</td>
- </tr>
- <tr>
- <td>storage</td>
- <td>storage</td>
- </tr>
- <tr>
- <td>vbox</td>
- <td>VBOX</td>
- </tr>
- <tr>
- <td>vmware</td>
- <td>VMWARE</td>
- </tr>
- <tr>
- <td>vz</td>
- <td>vz</td>
- </tr>
- </tbody>
- </table>
-
-
- <h2><a id="user">User identity attributes</a></h2>
-
- <p>
- At this point in time, the only attribute provided by
- libvirt to identify the user invoking the operation
- is the PID of the client program. This means that the
- polkit access control driver is only useful if connections
- to libvirt are restricted to its UNIX domain socket. If
- connections are being made to a TCP socket, no identifying
- information is available and access will be denied.
- Also note that if the client is connecting via an SSH
- tunnel, it is the local SSH user that will be identified.
- In future versions, it is expected that more information
- about the client user will be provided, including the
- SASL / Kerberos username and/or x509 distinguished
- name obtained from the authentication provider in use.
- </p>
-
-
- <h2><a id="checks">Writing access control
policies</a></h2>
-
- <p>
- If using versions of polkit prior to 0.106 then it is only
- possible to validate (user, permission) pairs via the
<code>.pkla</code>
- files. Fully validation of the (user, permission, object) triple
- requires the new JavaScript <code>.rules</code> support that
- was introduced in version 0.106. The latter is what will be
- described here.
- </p>
-
- <p>
- Libvirt does not ship any rules files by default. It merely
- provides a definition of the default behaviour for each
- action (permission). As noted earlier, permissions which
- correspond to read-only operations in libvirt will be allowed
- to all users by default; everything else is denied by default.
- Defining custom rules requires creation of a file in the
- <code>/etc/polkit-1/rules.d</code> directory with a name
- chosen by the administrator (<code>100-libvirt-acl.rules</code>
- would be a reasonable choice). See the <code>polkit(8)</code>
- manual page for a description of how to write these files
- in general. The key idea is to create a file containing
- something like
- </p>
-
- <pre>
-polkit.addRule(function(action, subject) {
- ....logic to check 'action' and 'subject'...
-});
- </pre>
-
- <p>
- In this code snippet above, the <code>action</code> object
- instance will represent the libvirt permission being checked
- along with identifying attributes for the object it is being
- applied to. The <code>subject</code> meanwhile will identify
- the libvirt client app (with the caveat above about it only
- dealing with local clients connected via the UNIX socket).
- On the <code>action</code> object, the permission name is
- accessible via the <code>id</code> attribute, while the
- object identifying attributes are exposed via the
- <code>lookup</code> method.
- </p>
-
- <p>
- See
- <a
href="https://gitlab.com/libvirt/libvirt/-/tree/master/examples/polk...
code</a>
- for a more complex example.
- </p>
-
- <h3><a id="exconnect">Example: restricting ability to connect
to drivers</a></h3>
-
- <p>
- Consider a local user <code>berrange</code>
- who has been granted permission to connect to libvirt in
- full read-write mode. The goal is to only allow them to
- use the <code>QEMU</code> driver and not the Xen or LXC
- drivers which are also available in libvirtd.
- To achieve this we need to write a rule which checks
- whether the <code>connect_driver</code> attribute
- is <code>QEMU</code>, and match on an action
- name of <code>org.libvirt.api.connect.getattr</code>. Using
- the javascript rules format, this ends up written as
- </p>
-
- <pre>
-polkit.addRule(function(action, subject) {
- if (action.id == "org.libvirt.api.connect.getattr" &&
- subject.user == "berrange") {
- if (action.lookup("connect_driver") == 'QEMU') {
- return polkit.Result.YES;
- } else {
- return polkit.Result.NO;
- }
- }
-});
- </pre>
-
- <h3><a id="exdomain">Example: restricting access to a single
domain</a></h3>
-
- <p>
- Consider a local user <code>berrange</code>
- who has been granted permission to connect to libvirt in
- full read-write mode. The goal is to only allow them to
- see the domain called <code>demo</code> on the LXC driver.
- To achieve this we need to write a rule which checks
- whether the <code>connect_driver</code> attribute
- is <code>LXC</code> and the <code>domain_name</code>
- attribute is <code>demo</code>, and match on an action
- name of <code>org.libvirt.api.domain.getattr</code>. Using
- the javascript rules format, this ends up written as
- </p>
-
- <pre>
-polkit.addRule(function(action, subject) {
- if (action.id == "org.libvirt.api.domain.getattr" &&
- subject.user == "berrange") {
- if (action.lookup("connect_driver") == 'LXC'
&&
- action.lookup("domain_name") == 'demo') {
- return polkit.Result.YES;
- } else {
- return polkit.Result.NO;
- }
- }
-});
- </pre>
- </body>
-</html>
diff --git a/docs/aclpolkit.rst b/docs/aclpolkit.rst
new file mode 100644
index 0000000000..09e5d9ea27
--- /dev/null
+++ b/docs/aclpolkit.rst
@@ -0,0 +1,310 @@
+.. role:: since
+
+=====================
+Polkit access control
+=====================
+
+Libvirt's client `access control framework <acl.html>`__ allows
+administrators to setup fine grained permission rules across client
+users, managed objects and API operations. This allows client
+connections to be locked down to a minimal set of privileges. The polkit
+driver provides a simple implementation of the access control framework.
+
+.. contents::
+
+Introduction
+------------
+
+A default install of libvirt will typically use
+`polkit <
https://www.freedesktop.org/wiki/Software/polkit/>`__ to
+authenticate the initial user connection to libvirtd. This is a very
+coarse grained check though, either allowing full read-write access to
+all APIs, or just read-only access. The polkit access control driver in
+libvirt builds on this capability to allow for fine grained control over
+the operations a user may perform on an object.
+
+Permission names
+----------------
+
+The libvirt `object names and permission names <acl.html#perms>`__ are
+mapped onto polkit action names using the simple pattern:
+
+::
+
+ org.libvirt.api.$object.$permission
+
+The only caveat is that any underscore characters in the object or
+permission names are converted to hyphens. So, for example, the
+``search_storage_vols`` permission on the ``storage_pool`` object maps
+to the polkit action:
+
+::
+
+ org.libvirt.api.storage-pool.search-storage-vols
+
+The default policy for any permission which corresponds to a "read only"
+operation, is to allow access. All other permissions default to deny
+access.
+
+Object identity attributes
+--------------------------
+
+To allow polkit authorization rules to be written to match against
+individual object instances, libvirt provides a number of authorization
+detail attributes when performing a permission check. The set of
+attributes varies according to the type of object being checked
+
+virConnectPtr
+~~~~~~~~~~~~~
+
+============== =====================================
+Attribute Description
+============== =====================================
+connect_driver Name of the libvirt connection driver
+============== =====================================
+
+virDomainPtr
+~~~~~~~~~~~~
+
+============== ============================================
+Attribute Description
+============== ============================================
+connect_driver Name of the libvirt connection driver
+domain_name Name of the domain, unique to the local host
+domain_uuid UUID of the domain, globally unique
+============== ============================================
+
+virInterfacePtr
+~~~~~~~~~~~~~~~
+
++-------------------+---------------------------------------------------------+
+| Attribute | Description |
++===================+=========================================================+
+| connect_driver | Name of the libvirt connection driver |
++-------------------+---------------------------------------------------------+
+| interface_name | Name of the network interface, unique to the local host |
++-------------------+---------------------------------------------------------+
+| interface_macaddr | MAC address of the network interface, not unique |
++-------------------+---------------------------------------------------------+
+
+virNetworkPtr
+~~~~~~~~~~~~~
+
+============== =============================================
+Attribute Description
+============== =============================================
+connect_driver Name of the libvirt connection driver
+network_name Name of the network, unique to the local host
+network_uuid UUID of the network, globally unique
+============== =============================================
+
+virNodeDevicePtr
+~~~~~~~~~~~~~~~~
+
+================ =================================================
+Attribute Description
+================ =================================================
+connect_driver Name of the libvirt connection driver
+node_device_name Name of the node device, unique to the local host
+================ =================================================
+
+virNWFilterPtr
+~~~~~~~~~~~~~~
+
+============== ====================================================
+Attribute Description
+============== ====================================================
+connect_driver Name of the libvirt connection driver
+nwfilter_name Name of the network filter, unique to the local host
+nwfilter_uuid UUID of the network filter, globally unique
+============== ====================================================
+
+virSecretPtr
+~~~~~~~~~~~~
+
+=================== ===========================================
+Attribute Description
+=================== ===========================================
+connect_driver Name of the libvirt connection driver
+secret_uuid UUID of the secret, globally unique
+secret_usage_volume Name of the associated volume, if any
+secret_usage_ceph Name of the associated Ceph server, if any
+secret_usage_target Name of the associated iSCSI target, if any
+secret_usage_name Name of the associated TLS secret, if any
+=================== ===========================================
+
+virStoragePoolPtr
+~~~~~~~~~~~~~~~~~
+
+============== ==================================================
+Attribute Description
+============== ==================================================
+connect_driver Name of the libvirt connection driver
+pool_name Name of the storage pool, unique to the local host
+pool_uuid UUID of the storage pool, globally unique
+============== ==================================================
+
+virStorageVolPtr
+~~~~~~~~~~~~~~~~
+
+============== ==================================================
+Attribute Description
+============== ==================================================
+connect_driver Name of the libvirt connection driver
+pool_name Name of the storage pool, unique to the local host
+pool_uuid UUID of the storage pool, globally unique
+vol_name Name of the storage volume, unique to the pool
+vol_key Key of the storage volume, globally unique
+============== ==================================================
+
+Hypervisor Driver connect_driver
+--------------------------------
+
+The ``connect_driver`` parameter describes the client's `remote
+Connection Driver <remote.html>`__ name based on the `URI <uri.html>`__
+used for the connection.
+
+:since:`Since 4.1.0`, when calling an API outside the scope of the primary
+connection driver, the primary driver will attempt to open a secondary
+connection to the specific API driver in order to process the API. For
+example, when hypervisor domain processing needs to make an API call
+within the storage driver or the network filter driver an attempt to
+open a connection to the "storage" or "nwfilter" driver will be
made.
+Similarly, a "storage" primary connection may need to create a
+connection to the "secret" driver in order to process secrets for the
+API. If successful, then calls to those API's will occur in the
+``connect_driver`` context of the secondary connection driver rather
+than in the context of the primary driver. This affects the
+``connect_driver`` returned from rule generation from the
+``action.loookup`` function. The following table provides a list of the
+various connection drivers and the ``connect_driver`` name used by each
+regardless of primary or secondary connection. The access denied error
+message from libvirt will list the connection driver by name that denied
+the access.
+
+Connection Driver Name
+~~~~~~~~~~~~~~~~~~~~~~
+
+================= =======================
+Connection Driver ``connect_driver`` name
+================= =======================
+bhyve bhyve
+esx ESX
+hyperv Hyper-V
+interface interface
+xen Xen
+lxc LXC
+network network
+nodedev nodedev
+nwfilter NWFilter
+openvz OPENVZ
+qemu QEMU
+secret secret
+storage storage
+vbox VBOX
+vmware VMWARE
+vz vz
+================= =======================
+
+User identity attributes
+------------------------
+
+At this point in time, the only attribute provided by libvirt to
+identify the user invoking the operation is the PID of the client
+program. This means that the polkit access control driver is only useful
+if connections to libvirt are restricted to its UNIX domain socket. If
+connections are being made to a TCP socket, no identifying information
+is available and access will be denied. Also note that if the client is
+connecting via an SSH tunnel, it is the local SSH user that will be
+identified. In future versions, it is expected that more information
+about the client user will be provided, including the SASL / Kerberos
+username and/or x509 distinguished name obtained from the authentication
+provider in use.
+
+Writing access control policies
+-------------------------------
+
+If using versions of polkit prior to 0.106 then it is only possible to
+validate (user, permission) pairs via the ``.pkla`` files. Fully
+validation of the (user, permission, object) triple requires the new
+JavaScript ``.rules`` support that was introduced in version 0.106. The
+latter is what will be described here.
+
+Libvirt does not ship any rules files by default. It merely provides a
+definition of the default behaviour for each action (permission). As
+noted earlier, permissions which correspond to read-only operations in
+libvirt will be allowed to all users by default; everything else is
+denied by default. Defining custom rules requires creation of a file in
+the ``/etc/polkit-1/rules.d`` directory with a name chosen by the
+administrator (``100-libvirt-acl.rules`` would be a reasonable choice).
+See the ``polkit(8)`` manual page for a description of how to write
+these files in general. The key idea is to create a file containing
+something like
+
+::
+
+ polkit.addRule(function(action, subject) {
+ ....logic to check 'action' and 'subject'...
+ });
+
+In this code snippet above, the ``action`` object instance will
+represent the libvirt permission being checked along with identifying
+attributes for the object it is being applied to. The ``subject``
+meanwhile will identify the libvirt client app (with the caveat above
+about it only dealing with local clients connected via the UNIX socket).
+On the ``action`` object, the permission name is accessible via the
+``id`` attribute, while the object identifying attributes are exposed
+via the ``lookup`` method.
+
+See `source
+code <
https://gitlab.com/libvirt/libvirt/-/tree/master/examples/polkit>`__
+for a more complex example.
+
+Example: restricting ability to connect to drivers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Consider a local user ``berrange`` who has been granted permission to
+connect to libvirt in full read-write mode. The goal is to only allow
+them to use the ``QEMU`` driver and not the Xen or LXC drivers which are
+also available in libvirtd. To achieve this we need to write a rule
+which checks whether the ``connect_driver`` attribute is ``QEMU``, and
+match on an action name of ``org.libvirt.api.connect.getattr``. Using
+the javascript rules format, this ends up written as
+
+::
+
+ polkit.addRule(function(action, subject) {
+ if (action.id == "org.libvirt.api.connect.getattr" &&
+ subject.user == "berrange") {
+ if (action.lookup("connect_driver") == 'QEMU') {
+ return polkit.Result.YES;
+ } else {
+ return polkit.Result.NO;
+ }
+ }
+ });
+
+Example: restricting access to a single domain
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Consider a local user ``berrange`` who has been granted permission to
+connect to libvirt in full read-write mode. The goal is to only allow
+them to see the domain called ``demo`` on the LXC driver. To achieve
+this we need to write a rule which checks whether the ``connect_driver``
+attribute is ``LXC`` and the ``domain_name`` attribute is ``demo``, and
+match on an action name of ``org.libvirt.api.domain.getattr``. Using the
+javascript rules format, this ends up written as
+
+::
+
+ polkit.addRule(function(action, subject) {
+ if (action.id == "org.libvirt.api.domain.getattr" &&
+ subject.user == "berrange") {
+ if (action.lookup("connect_driver") == 'LXC' &&
+ action.lookup("domain_name") == 'demo') {
+ return polkit.Result.YES;
+ } else {
+ return polkit.Result.NO;
+ }
+ }
+ });
diff --git a/docs/meson.build b/docs/meson.build
index 5536005125..0f402bbf6a 100644
--- a/docs/meson.build
+++ b/docs/meson.build
@@ -32,7 +32,6 @@ docs_assets = [
docs_html_in_files = [
'404',
- 'aclpolkit',
'api_extension',
'api',
'apps',
@@ -106,6 +105,7 @@ docs_html_in_files = [
]
docs_rst_files = [
+ 'aclpolkit',
'advanced-tests',
'best-practices',
'ci',
--
2.29.2