# Access configuration

WirePlumber includes a "client access" policy which defines access control rules for PipeWire clients.

## Rules

This policy can be configured with rules that can be used to match clients and apply default permissions to them.

Example:

    access.rules = [
      {
        matches = [
          {
            access = "flatpak"
            media.category = "Manager"
          }
        ]
        actions = {
          update-props = {
            access = "flatpak-manager"
            default_permissions = "all",
          }
        }
      }
      {
        matches = [
          {
            access = "flatpak"
          }
        ]
        actions = {
          update-props = {
            default_permissions = "rx"
          }
        }
      }
    ]

Possible permissions are any combination of:

> - `r`: client is allowed to read objects, i.e. "see" them on the registry and list their properties

> - `w`: client is allowed to write objects, i.e. call methods that modify their state

> - `x`: client is allowed to execute methods on objects; the `w` flag must also be present to call methods that modify the object

> - `m`: client is allowed to set metadata on objects

> - `l`: nodes of this client are allowed to link to other nodes that the client can't "see" (i.e. the client doesn't have `r` permission on them)

The special value `all` is also supported and it is synonym for `rwxm`

## Permission Managers

For more advanced use cases, WirePlumber supports permission managers that can apply per-object permissions dynamically based on rules and object interests. Permission managers are defined in the `access.permission-managers` section and then referenced by name in `access.rules`.

Example:

    access.permission-managers = [
      {
        name = "custom"
        default_permissions = "all"
        core_permissions = "rx"
        rules = [
          {
            matches = [
              {
                media.class = "Audio/Source"
              }
            ]
            actions = {
              set-permissions = "-"
            }
          }
        ]
      }
    ]

    access.rules = [
      {
        matches = [
          {
            application.name = "paplay"
          }
        ]
        actions = {
          update-props = {
            permission_manager_name = "custom"
          }
        }
      }
    ]

Each permission manager supports the following properties:

> - `name`: (required) a unique name used to reference the manager from `access.rules`

> - `default_permissions`: the fallback permissions applied to all objects that don't match any rule (applied as `PW_ID_ANY`)

> - `core_permissions`: permissions applied specifically to the PipeWire core object (`PW_ID_CORE`, ID 0). This is useful when you want to allow a client to interact with the core (e.g. enumerate objects, subscribe to events) while restricting access to individual objects. If not set, the `default_permissions` value is used for the core as well.

> - `rules`: a list of match rules with `set-permissions` actions that grant specific permissions to objects matching the given constraints

When both `default_permissions` and `permission_manager_name` are set in a rule's `update-props` action, `default_permissions` takes precedence and the permission manager is ignored.

## Introspecting Permissions from Scripts

Lua scripts can query the permission manager attached to a client at runtime using `client:get_permission_manager()`. This returns the `WpPermissionManager` object (or `nil` if none is attached), which can then be used to inspect the configured permissions.

Example:

    local client_om = ObjectManager { Interest { type = "client" } }
    client_om:activate()

    -- Check if a client has at least read + execute permissions
    local pm = client:get_permission_manager()
    if pm then
      local perms = pm:get_default_permissions()
      if (perms & Perm.RX) == Perm.RX then
        -- Client has sufficient permissions
      end
    end

This is useful for scripts that need to verify a client's trust level before performing privileged operations on its behalf (e.g. linking nodes into an audio chain).