From nobody Fri Dec 19 07:19:03 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) client-ip=63.128.21.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1615549499; cv=none; d=zohomail.com; s=zohoarc; b=ZJJQApGhVi/3RteiKTi2NzKVQd86UXf0koPsQFloW1GRSJH1pWdYNk/YxlsT3sgm/A1cWcSzHIZ3AjGCjQwWmZroOiR6DJ8OPttdgGumEVM5BgjtmQ1k9YXctkLodN9dy3pojtfqsrwWUTH5LMasnM6jU09dvJQwWAi5w+hOgO0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1615549499; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=R3nUDh6pCcTQE6ZeooTue1UTwGZgCZiiExptmrv1B1c=; b=UNiIP76iXpuaDg6L0WOtjZSQHe8kudttwxMh/effBT0+SH6zwonhnlh9acSvqT93BrDQTfr5NEuWGFY8kWriWJ+W8NLNUDZ/HBOj2K74I6NXB8zYEco9bQ9Y1qiIZfsGtLBDr+NmuUZdDjZq6/jCAG50t7S6r8Rb1QAeRRRkzyk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [63.128.21.124]) by mx.zohomail.com with SMTPS id 1615549499531995.4630425759875; Fri, 12 Mar 2021 03:44:59 -0800 (PST) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-256-U85ypWCONxOHXVsWOxJ-oQ-1; Fri, 12 Mar 2021 06:44:56 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id A52F01966321; Fri, 12 Mar 2021 11:44:50 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 7E3135C1D1; Fri, 12 Mar 2021 11:44:49 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 216731800232; Fri, 12 Mar 2021 11:44:49 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 12CBhHLO024833 for ; Fri, 12 Mar 2021 06:43:17 -0500 Received: by smtp.corp.redhat.com (Postfix) id D4A9360657; Fri, 12 Mar 2021 11:43:17 +0000 (UTC) Received: from nautilus.redhat.com (unknown [10.40.192.123]) by smtp.corp.redhat.com (Postfix) with ESMTP id 04CA060636; Fri, 12 Mar 2021 11:43:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1615549498; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=R3nUDh6pCcTQE6ZeooTue1UTwGZgCZiiExptmrv1B1c=; b=KuCLi3bK/8TygJ73x9LfUNbjUgBiLOoNKC9xSR+04ZkAh1R587XovZLYdG0ZYX8QJvMbeN ZZHr+yRyWlFtS/8sBDXHEZWTisQ30Bv8imiRwUj2ZRjGZhQ/rt4BKO+6liJZnm+EwJJ75r Gv3V5S/sh5a/3UlJfsORcZKkCjl/URk= X-MC-Unique: U85ypWCONxOHXVsWOxJ-oQ-1 From: Erik Skultety To: libvir-list@redhat.com Subject: [libvirt PATCH 1/9] docs: html.in: Convert aclpolkit to rst Date: Fri, 12 Mar 2021 12:43:04 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-loop: libvir-list@redhat.com Cc: eskultet@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" Signed-off-by: Erik Skultety Reviewed-by: Peter Krempa --- 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 @@ - - - - -

Polkit access control

- -

- Libvirt's client access control framework a= llows - 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. -

- -
    - -

    Introduction

    - -

    - A default install of libvirt will typically use - 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 n= ames - 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

    - - - - - - - - - - - - - -
    AttributeDescription
    connect_driverName of the libvirt connection driver
    - -

    virDomainPtr

    - - - - - - - - - - - - - - - - - - - - - -
    AttributeDescription
    connect_driverName of the libvirt connection driver
    domain_nameName of the domain, unique to the local host
    domain_uuidUUID of the domain, globally unique
    - -

    virInterfacePtr

    - - - - - - - - - - - - - - - - - - - - - -
    AttributeDescription
    connect_driverName of the libvirt connection driver
    interface_nameName of the network interface, unique to the local host
    interface_macaddrMAC address of the network interface, not unique
    - -

    virNetworkPtr

    - - - - - - - - - - - - - - - - - - - - - -
    AttributeDescription
    connect_driverName of the libvirt connection driver
    network_nameName of the network, unique to the local host
    network_uuidUUID of the network, globally unique
    - -

    virNodeDevicePtr

    - - - - - - - - - - - - - - - - - -
    AttributeDescription
    connect_driverName of the libvirt connection driver
    node_device_nameName of the node device, unique to the local host
    - -

    virNWFilterPtr

    - - - - - - - - - - - - - - - - - - - - - -
    AttributeDescription
    connect_driverName of the libvirt connection driver
    nwfilter_nameName of the network filter, unique to the local host
    nwfilter_uuidUUID of the network filter, globally unique
    - -

    virSecretPtr

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    AttributeDescription
    connect_driverName of the libvirt connection driver
    secret_uuidUUID of the secret, globally unique
    secret_usage_volumeName of the associated volume, if any
    secret_usage_cephName of the associated Ceph server, if any
    secret_usage_targetName of the associated iSCSI target, if any
    secret_usage_nameName of the associated TLS secret, if any
    - -

    virStoragePoolPtr

    - - - - - - - - - - - - - - - - - - - - - -
    AttributeDescription
    connect_driverName of the libvirt connection driver
    pool_nameName of the storage pool, unique to the local host
    pool_uuidUUID of the storage pool, globally unique
    - -

    virStorageVolPtr

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    AttributeDescription
    connect_driverName of the libvirt connection driver
    pool_nameName of the storage pool, unique to the local host
    pool_uuidUUID of the storage pool, globally unique
    vol_nameName of the storage volume, unique to the pool
    vol_keyKey of the storage volume, globally unique
    - -

    Hypervisor Driver connect_driver

    -

    - The connect_driver parameter describes the - client's remote Connection Driver - name based on the URI used for the - connection. -

    -

    - 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 Driverconnect_driver name
    bhyvebhyve
    esxESX
    hypervHyper-V
    interfaceinterface
    xenXen
    lxcLXC
    networknetwork
    nodedevnodedev
    nwfilterNWFilter
    openvzOPENVZ
    qemuQEMU
    secretsecret
    storagestorage
    vboxVBOX
    vmwareVMWARE
    vzvz
    - - -

    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 - for a more complex example. -

    - -

    Example: restricting ability to connect to dri= vers

    - -

    - 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 =3D=3D "org.libvirt.api.connect.getattr" &&
    -        subject.user =3D=3D "berrange") {
    -          if (action.lookup("connect_driver") =3D=3D 'QEMU') {
    -            return polkit.Result.YES;
    -          } else {
    -            return polkit.Result.NO;
    -          }
    -    }
    -});
    -    
    - -

    Example: restricting access to a single domain<= /a>

    - -

    - 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 =3D=3D "org.libvirt.api.domain.getattr" &&
    -        subject.user =3D=3D "berrange") {
    -          if (action.lookup("connect_driver") =3D=3D 'LXC' &&
    -              action.lookup("domain_name") =3D=3D 'demo') {
    -            return polkit.Result.YES;
    -          } else {
    -            return polkit.Result.NO;
    -          }
    -    }
    -});
    -    
    - - 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 + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +Polkit access control +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Libvirt's client `access control framework `__ 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 `__ 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 `__ 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 +~~~~~~~~~~~~~ + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D +Attribute Description +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D +connect_driver Name of the libvirt connection driver +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D + +virDomainPtr +~~~~~~~~~~~~ + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D +Attribute Description +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D +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 +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D + +virInterfacePtr +~~~~~~~~~~~~~~~ + ++-------------------+-----------------------------------------------------= ----+ +| Attribute | Description = | ++=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D+ +| connect_driver | Name of the libvirt connection driver = | ++-------------------+-----------------------------------------------------= ----+ +| interface_name | Name of the network interface, unique to the local h= ost | ++-------------------+-----------------------------------------------------= ----+ +| interface_macaddr | MAC address of the network interface, not unique = | ++-------------------+-----------------------------------------------------= ----+ + +virNetworkPtr +~~~~~~~~~~~~~ + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +Attribute Description +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +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 +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +virNodeDevicePtr +~~~~~~~~~~~~~~~~ + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +Attribute Description +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +connect_driver Name of the libvirt connection driver +node_device_name Name of the node device, unique to the local host +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +virNWFilterPtr +~~~~~~~~~~~~~~ + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +Attribute Description +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +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 +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +virSecretPtr +~~~~~~~~~~~~ + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +Attribute Description +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +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 +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +virStoragePoolPtr +~~~~~~~~~~~~~~~~~ + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +Attribute Description +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +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 +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +virStorageVolPtr +~~~~~~~~~~~~~~~~ + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +Attribute Description +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +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 +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Hypervisor Driver connect_driver +-------------------------------- + +The ``connect_driver`` parameter describes the client's `remote +Connection Driver `__ name based on the `URI `__ +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 +~~~~~~~~~~~~~~~~~~~~~~ + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +Connection Driver ``connect_driver`` name +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +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 +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +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 `__ +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 =3D=3D "org.libvirt.api.connect.getattr" && + subject.user =3D=3D "berrange") { + if (action.lookup("connect_driver") =3D=3D '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 =3D=3D "org.libvirt.api.domain.getattr" && + subject.user =3D=3D "berrange") { + if (action.lookup("connect_driver") =3D=3D 'LXC' && + action.lookup("domain_name") =3D=3D '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 =3D [ =20 docs_html_in_files =3D [ '404', - 'aclpolkit', 'api_extension', 'api', 'apps', @@ -106,6 +105,7 @@ docs_html_in_files =3D [ ] =20 docs_rst_files =3D [ + 'aclpolkit', 'advanced-tests', 'best-practices', 'ci', --=20 2.29.2