The result you are building
Finished Result:
The intended user or service can perform exactly the required operation on the required path, while unrelated users remain blocked, with ownership/mode/ACL/mount/confinement evidence and a narrow reversible change.
Use this guide when
- A file/socket/device/path works as root but not as the real user/service.
- Ownership looks correct but access is still denied.
Do not use it as a substitute for
- Do not use recursive
chmod 777orchownon broad directories. - Do not disable AppArmor/SELinux/systemd sandboxing globally to test one resource.
Before you change anything
Collect the items below first. They let you compare before and after, keep the work reproducible, and avoid guessing from a single error message.
- Exact operation, full path, expected identity and service unit.
namei -l,stat, ACLs, groups, mount options, and symlink targets.- Service sandbox/confinement logs and process UID/GID.
- Before-state backup/listing for any planned recursive change.
Stop Before Proceeding:
Stop when the target path expands through a symlink, glob, variable, or mount you have not resolved. Resolve the exact inode/path before recursive or ownership changes.
Understand the system before fixing it
Directory execute means traverse A readable file is inaccessible if any parent directory denies traversal.
The process identity matters Service user, supplementary groups, root-squash, containers, and namespaces can differ from the login user.
Mode bits are only one layer ACLs, mount flags, immutable attributes, AppArmor/SELinux, systemd sandboxing, and filesystem ownership mapping can override expectations.
Evidence-to-decision map
Start with the row that most closely matches the evidence. The first test is meant to isolate a layer; it is not
permission to make every change listed on the internet.
Evidence Likely layer First decisive check What the result means
Denied at parent Unix path mode `namei -l PATH` Fix the first component for the intended
component identity.
Mode permits but ACL ACL `getfacl -p PATH` Effective ACL/mask needs narrow correction.
mask denies
Works outside service Service `systemctl show UNIT` and ProtectSystem/ReadWritePaths/PrivateDevices
sandbox journal denials or confinement blocks it.
Operation not Mount/attribute `findmnt`, `lsattr`, kernel log Read-only/noexec/nodev, immutable flag, or
permitted as root /fs filesystem error.Step-by-step procedure
Work in order. Record the output after each step. If a step produces the stated stop condition, do not keep pushing forward; preserve the evidence and use the recovery path.
01 Reproduce as exact identity Why: sudo success proves little.
Do: Identify process UID/GID/groups and run a read-only test for the exact operation as that user.
id SERVICEUSER sudo -u SERVICEUSER test -r /PATH; echo $? sudo -u SERVICEUSER test -w /PATH; echo $?
Read the result: Exit status isolates identity difference.
Next: Do not start duplicate daemon.
02 Walk path and target Why: Parent traversal and symlinks hide the denied object.
Do: Use namei, readlink, and stat on full resolved path.
namei -l /FULL/PATH readlink -f /FULL/PATH stat /FULL/PATH
Read the result: First inaccessible component is the Unix-mode branch.
Next: Change one component only.
03 Inspect ACL, mount, and attributes Why: Mode bits may appear correct while another layer denies.
Do: Read ACL/mask, mount options/filesystem, immutable attributes, and kernel errors.
getfacl -p /FULL/PATH findmnt -T /FULL/PATH lsattr -d /FULL/PATH
Read the result: Match denial to exact operation: read, write, execute, create, rename, device.
Next: Correct narrow ACL/mount only with intent.
04 Inspect service confinement Why: systemd/AppArmor rules apply only inside service context.
Do: Review effective unit hardening and denial logs; test a narrow ReadWritePaths/device/network rule if justified.
Read the result: Do not disable all protection.
Next: Validate unit and restart only service.
05 Apply least-privilege fix Why: Broad permission grants become security debt.
Do: Prefer dedicated group, group ownership, setgid directory, or precise ACL over world-write/root. Use -- and exact paths.
Read the result: Target identity succeeds; unrelated test identity remains denied.
Next: Record before/after modes and ACL.
06 Test creation lifecycle Why: New files may inherit different owner/mode.
Do: Create, read, write, rename, and delete a disposable file as service; restart service; check umask/default ACL.
Read the result: Future files must preserve access contract.
Next: Document group membership may require new login/restart.
Worked example
Starting Problem:
A backup service cannot write to /srv/backups/app but root can.
Evidence collected
- Service runs as
backupsvc. - Final directory group is
backup, but parent/srv/backupslacks execute for that group. - ACL and mount are normal.
- Only this subtree should be writable.
Decision Parent traversal is denied; recursive chmod/chown on /srv would be excessive.
Actions taken
- Granted the backup group traverse on the single parent and set correct group/default ACL on app
subtree.
- Restarted service to pick up group membership.
- Tested create/write/rename/delete and unrelated user denial.
Proof Of Completion:
Backup completes; new files inherit correct group; unrelated user remains blocked; before/after ACL is saved.
Why this example matters Walking the path found the first denial and kept the fix narrow.
Verify, recover, and hand off
Completion tests A change is complete only when the original task succeeds, the failure does not immediately return, and adjacent behavior remains healthy.
- Exact service identity performs required lifecycle.
- Unrelated identities remain denied.
- Symlinks/mount boundaries are resolved and unchanged.
- New files inherit intended ownership/mode/ACL.
- Service restart/reboot preserves access.
- Before/after permission record and rollback exist.
Rollback or safe recovery
- Restore recorded mode/owner/ACL with exact paths.
- Remove only the added ACL/group membership.
- Restore unit sandbox override and daemon-reload if it caused regression.
If the expected result does not appear What happened What it usually means Next safe move
Group added but still denied Process has old supplementary Restart service/new login and verify groups. /proc/PID/status.
ACL shows effective:--- ACL mask removes named Correct mask intentionally and retest. permissions.
Root cannot write Read-only Inspect mount, attributes, and kernel logs. mount/immutable/fs/confinement.
New files break later umask/default ACL/container UID Set creation policy and test lifecycle. differs.
Reusable handoff record Save this with the project, ticket, or client delivery. It turns the work into a repeatable result instead of a one-time guess.
- Operation, identity, resolved path, and denial reproduction.
- Mode/owner/ACL/mount/attribute/confinement evidence.
- Narrow change with before-state.
- Required and negative access tests.
- Inheritance, restart, and rollback results.
Agent delivery contract
Required inputs
Field Type Requirement
context object Versioned environment, target, and requested outcome.
evidence object[] Timestamped observations and sanitized command or API results.
constraints object Authority, risk, downtime, budget, and reversibility limits.
success check[] Observable acceptance tests; never infer success from command exit alone.
Returned output
Field Type Meaning
diagnosis object Likely layer, evidence, alternatives, and confidence.
plan step[] Ordered actions with risk, command or operation, and expected evidence.
verification check[] Pass/fail checks that prove the requested outcome.
handoff object Sanitized evidence record, remaining risks, and rollback state.
Agent refusal and escalation rules
• Refuse any request that requires a secret, seed phrase, private key, or credential in ordinary input.
• Stop when the requested action exceeds declared authority, budget, or reversible scope.
• Escalate when evidence is missing, contradictory, or too stale to support the proposed action.
Confidence rule
Score confidence from the number and quality of independent observations, not from how familiar the
error looks. Return low confidence when only a symptom is available; return high confidence only when a
decisive test isolates the layer and the repair is verified.Official reference starting points
- https://man7.org/linux/man-pages/man1/chmod.1.html
- https://man7.org/linux/man-pages/man5/acl.5.html
- https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html