PyFACL
A Python library for parsing and checking POSIX File Access Control Lists (FACL).
Documentation: https://pyfacl.readthedocs.io/en/latest/
Installation
From PyPI
pip install pyfacl
Usage
Python
The simplest way to check permissions is with the top-level pyfacl.has_permission function:
import pyfacl
# Case 1 — check a single file/directory (default)
pyfacl.has_permission("/path/to/file", "user:user2:r-x")
# Case 2 — trace through entire directory hierarchy (trace=True)
# The permission must be granted at every level from / down to the target path.
pyfacl.has_permission("/path/to/file", "user:user2:r-x", trace=True)
# Case 3 — can-execute check (can_execute=True)
# The user/group must have execute (--x) on every parent directory up to the path,
# and the specified permission+mode for the target path only.
pyfacl.has_permission("/path/to/file", "user:user2:r-x", can_execute=True)
All three cases accept the same optional arguments:
| Argument | Default | Description |
|---|---|---|
mode |
"at_least" |
"exact", "at_least", or "at_most" |
trace |
False |
Check every directory level |
can_execute |
False |
Check execute on parents, specified perm on target |
v |
0 |
Verbosity level |
Note:
trace=Trueandcan_execute=Truecannot be used together.
Permission Modes
exact: Permissions must match exactlyat_least: Must have at least the specified permissionsat_most: Must have at most the specified permissions
CLI
The CLI tool checks permissions through the entire directory hierarchy, checks whether the permissions are met and identifies which permission rule applies at each level.
pyfacl trace /path/to/file user:<user2>:r-x --mode exact
Example output:
$ pyfacl trace /data1/collab002/sail/example/permission/folder user:user2:r-x
0) ✅ other::r-x /
1) ✅ other::r-x /data1
2) ✅ group::rwx /data1/collab002
3) ✅ group::r-x /data1/collab002/sail
4) ✅ group::r-x /data1/collab002/sail/example
5) ❌ user:user2:--x /data1/collab002/sail/example/permission
6) ✅ group::r-x /data1/collab002/sail/example/permission/folder
In this trace, items 0-4 and 6 show ✅ passing permissions, while item 5 shows ❌ failing permissions where the user only has execute (--x) but needs read+execute (r-x).
However, often we only care about if the user has the required permission for the final file/directory, not the full trace. For that, we can use the has command:
$ pyfacl has /path/to/file user:<user2>:r-x --mode exact
0) ✅ other::r-x /
1) ✅ other::r-x /data1
2) ✅ group::rwx /data1/collab002
3) ✅ group::r-x /data1/collab002/sail
4) ✅ group::r-x /data1/collab002/sail/example
5) ✅ user:user2:--x /data1/collab002/sail/example/permission
6) ✅ group::r-x /data1/collab002/sail/example/permission/folder
Python (class-based API)
The lower-level class-based API gives more control and is useful when you need the detailed trace output or want to reuse a parsed FACL object.
Check one file/folder permission
from pyfacl import FACL
# Initialize and parse FACL for a file/directory
facl = FACL(path="/path/to/file")
# Check permissions with different modes
facl.has_permission("user:user2:r-x", mode="exact") # exact match
facl.has_permission("user:user2:r--", mode="at_least") # has at least read
facl.has_permission("user:user2:rwx", mode="at_most") # has at most rwx
Check trace through directory hierarchy
from pyfacl import FACLTrace
# Initialize FACLTrace for a directory
facl_trace = FACLTrace(path="/path/to/directory", v=1)
# Trace permissions for a specific user
trace_result = facl_trace.has_permission("user:user2:r-x", mode="at_least")
Check if user/group can navigate to and has permission for a file/directory
from pyfacl import FACLHas
# Initialize FACLHas for a file/directory
facl_has = FACLHas(path="/path/to/file")
# Check if user/group has execute on all parents and the specified perm on the target
has_permission = facl_has.has_permission("user:user2:r-x", mode="at_least")
Development
Setup Development Environment
pip install -e ".[dev]"
pre-commit install
Run Pre-commit Checks
pre-commit run --all-files
Metadata
Release files for pyfacl 1.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pyfacl-1.5.0.tar.gz | 10.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pyfacl-1.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 21.8 kB
Release files / pyfacl-1.5.0.tar.gz
| Download URL | pyfacl-1.5.0.tar.gz |
|---|---|
| Size | 10.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ada4f2243dfc4679324f563850f1e3d53d0bc2ad00398547e63b4015e35eb279
|
|
BLAKE2b-256 checksum How to use checksums |
b197ac66100607887946b1ee29ccb644601ace47f3c0e371492c31b5c2c390fd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.1.3 CPython/3.12.9 Linux/4.18.0-425.19.2.el8_7.x86_64
|
Release files / pyfacl-1.5.0-py3-none-any.whl
| Download URL | pyfacl-1.5.0-py3-none-any.whl |
|---|---|
| Size | 11.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d826632b2791157a8435af9be4c5f1270421a7bb4cb0690350b73245154f8b6a
|
|
BLAKE2b-256 checksum How to use checksums |
64a53eba89a981de474b25bdb8dfea35b77fdaafb806013ed71e054ec382f9c8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.1.3 CPython/3.12.9 Linux/4.18.0-425.19.2.el8_7.x86_64
|