Audit File Permissions Across a Project in Python
Walks through every file and directory in a project tree and prints POSIX permissions plus owner UID.
Python code
25 linesimport os
import stat
from pathlib import Path
def audit_file_permissions(project_root):
"""Walk through project_root and print path, owner, and permissions for every file."""
results = []
for root, dirs, files in os.walk(project_root):
for name in files + dirs:
full_path = os.path.join(root, name)
try:
st = os.stat(full_path)
mode = st.st_mode
perms = stat.filemode(mode)
results.append((full_path, st.st_uid, perms))
except OSError:
continue
return results
if __name__ == "__main__":
# Example usage: audit the current working directory
project_path = Path.cwd()
entries = audit_file_permissions(project_path)
for path, uid, perms in entries:
print(f"{perms} UID={uid} {path}")
Output
drwxr-xr-x UID=1001 /home/user/project
-rw-r--r-- UID=1001 /home/user/project/README.md
-rw-r--r-- UID=1001 /home/user/project/main.py
drwx------ UID=1002 /home/user/project/secrets
How it works
The script uses os.walk to recursively traverse the project tree. For each entry (file or directory), it calls os.stat to retrieve the file's status block. stat.filemode converts the raw mode bits into the familiar rwx string. The result is a list of tuples that can be printed or further processed, e.g. to detect files with overly permissive settings.
The try/except OSError skips entries that cannot be stat'd (broken symlinks, permission denied) so the audit continues without crashing.
Common mistakes
- Forgetting to handle permission errors when walking subdirectories the user can't enter.
- Using `os.stat` on symlinks gives the target's mode; use `os.lstat` if you need the link's own mode.
- Assuming `st_uid` is a username string; it's an integer UID that requires `pwd.getpwuid` for a human name.
- Not filtering out directories when only file permissions matter.
Variations
- Use `pathlib.Path.rglob('*')` with `Path.stat()` for a more modern, object-oriented approach.
- Add `pwd.getpwuid(st_uid).pw_name` to display human-readable usernames instead of numeric UIDs.
Real-world use cases
- Pre-deployment CI check that no file in the release artifact has world-writable permissions.
- Security scan after a data breach to identify files owned by unexpected UIDs across a web application.
- Onboarding script that verifies all project files have consistent owner/group before pushing to production.
Sponsored
More from Files & data
- Automatically Detect Corrupted Files Using SHA-256 Checksums in Python easy
- Automatically Highlight Data Validation Errors Inside Excel Files in Python easy
- Build a Command-Line To-Do List Application with Data Persistence in Python easy
- Build a Personal Work Hours Tracker in Python medium
- Build a Python Script That Detects and Deletes Empty Files Across Folders easy
- Build a Secure Local Password Vault with Encrypted Storage in Python medium
Keep learning
Related tutorials and quizzes for this topic.