Open-source project
mpartel/bindfs avatar
mpartel/bindfs

bindfs mirrors a directory with different permissions, which mount --bind cannot do

Mount a directory elsewhere with changed permissions.

533 stars74 forksCGPL-2.0

At a glance

What is it?
bindfs is a FUSE filesystem that mirrors one directory to another with the permissions changed, so a tree can be made read-only, executables stripped of their execute bit, or access granted to a named list of users, and it runs without root for most of those cases. It suits a sysadmin who needs to hand out restricted views of a shared directory, and it needs FUSE configured for other users to see the mount.
Who is it for?
bindfs fits a sysadmin who needs a restricted view of a directory for a specific group of people, since a plain bind mount inherits the source permissions and cannot express a different permission set. It does not fit a case where the change must be enforced on the original files rather than on a view of them, because bindfs changes what a user sees at the mount, not the underlying inode.
Can I use it commercially?
Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 33 days ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What it does that a bind mount cannot

bindfs is a FUSE filesystem for mirroring a directory to another directory, similarly to `mount --bind`, and the permissions of the mirrored directory can be altered in various ways.

The key point is that a normal bind mount does not let you change permissions. The mounted tree shows the source tree's own permission bits, and the only way to change them is to change them on the original files. bindfs inserts a layer where the permissions are computed, so you can present a different view of the same data.

The listed uses are concrete and each one is a thing you would otherwise have to solve with a copy.

Making a directory read-only is the simplest case, and it is the one that does not require root.

Making all executables non-executable is the same idea applied to a permission bit rather than to write access, which is useful when the executables are not the point of sharing the directory.

Sharing a directory with a list of users or groups is the most interesting case, because it is a per-mount access list rather than a change to the files.

Modifying permission bits using rules with chmod-like syntax is the general form, and it is the one that gets you out of the fixed list of operations above.

Changing the permissions with which files are created is about the mount point's umask behaviour rather than about existing files.

The project states that non-root users can use almost all features, but that most interesting use-cases need `user_allow_other` to be defined in `/etc/fuse.conf`. That last point is the operational reality of FUSE and it decides whether the mount is visible to other users at all.

Platform support, and what best-effort means here

bindfs is developed and tested primarily on Linux with FUSE 3, and the rest of the matrix is qualified.

Support for Linux with FUSE 2, for MacOS with fuse-t and for FreeBSD with fuse4bsd is best-effort. MacFUSE might work but is not properly supported, since it is impossible to test it without access to a physical Mac. The README says volunteer maintenance of MacFUSE support is welcome.

That is an unusually candid statement, and it explains why. A FUSE filesystem has to match the behaviour of the host kernel's FUSE implementation closely, and the MacFUSE implementation is a port with different semantics. The author is asking for help rather than claiming support, which is a better position than the alternative.

The library version requirements are also specific. FUSE 2.8.0 or above is required, and FUSE 3 is supported. When using FUSE 3, libfuse 3.10.2 or newer is recommended to avoid a bug with readdir, though it only seems to affect a few applications.

That readdir bug is worth knowing about because it is the kind of defect that shows up as a file listing that is intermittently short rather than an error message, and it affects the applications that read directories in unusual ways rather than the filesystem in general.

The homepage is bindfs.org, the project is C with a GPL-2.0-or-later licence, and the last push to the repository was on 2026-09-20 with no GitHub releases published.

Building it

On Linux, the build dependencies are installed with apt first.

The Linux build dependencies are installed with `apt install build-essential pkg-config libfuse3-dev`, or with libfuse-dev on older systems.

Or libfuse-dev on older systems. On MacOS you need XCode with the Developer Tools installed, pkg-config and fuse-t, with MacFuse support described as highly best-effort.

Then the standard autotools sequence.

code
    ./autogen.sh  # Only needed if you cloned the repo.
    ./configure
    make
    make install

The autogen.sh step is only needed when building from a clone, since a release tarball ships a pre-generated configure script. The rest is the familiar configure, make, make install.

Two post-install steps are mentioned, and both are conditional.

If you want the mounts made by non-root users to be visible to other users, you may have to add the line `user_allow_other` to `/etc/fuse.conf`. That is the FUSE-level permission that lets a non-root mount be seen by anyone rather than only by the mounting user.

On some systems, you may have to add your user to the `fuse` group, which is how the kernel device node is usually made accessible.

The usage documentation is not in the README beyond a pointer. The README says to see `bindfs --help` or the man-page for instructions and examples, so the tool's own help output is the reference rather than a hand-written document here. That is a reasonable choice for a command with a large option surface, and it is worth running `bindfs --help` before reading anything else.

MacOS mount options

There is one platform-specific section, and it is short.

Under osxfuse, the following extra options may be useful.

code
    -o local,allow_other,extended_security,noappledouble

The README points at the osxfuse wiki page on mount options for details.

Each of those four flags addresses a specific difference between MacFUSE and Linux FUSE. `local` keeps the mount local to the machine rather than exporting it over the network, which is the FUSE default behaviour on Linux but not something MacFUSE does the same way. `allow_other` is the same user_allow_other idea in option form, letting other users see the mount. `extended_security` maps the Unix ownership and permission model onto the Mac security model. `noappledouble` disables the AppleDouble sidecar files that MacFUSE otherwise creates to store resource-fork and extended-attribute data alongside files that cannot hold it.

That last one has a practical consequence worth understanding. If you are mirroring a directory to a Mac and the source contains files with extended attributes, the default behaviour creates hidden companion files, which is confusing if you are then syncing the mirrored tree somewhere else. Disabling it means such attributes are dropped rather than relocated.

The test suite, and the Vagrant runner

Bindfs comes with a test suite, and the README describes it honestly as somewhat brittle and messy. Some tests must be run as root, and some tests only work as non-root.

The whole suite is run with a single script.

The whole suite is run with `./test-all.sh`.

It requires Ruby and sudo, and it uses valgrind if it is installed. The valgrind part matters for a filesystem, because the failure modes of a FUSE implementation are often memory errors that show up much later as a corrupted directory listing, and a memory checker in the test loop is how you catch them.

The split between root and non-root tests is a direct consequence of the `user_allow_other` requirement. A mount created by a non-root user is only visible to others if the FUSE configuration permits it, so the suite has to cover both configurations.

There is also a set of Vagrant configs for running the test suite on a variety of systems, driven by `vagrant/test.rb`, with a --help option for the available flags. And a make target, `make vagrant-clean`, destroys all the bindfs Vagrant machines without removing the downloaded images, which is the right behaviour for a test harness you run repeatedly.

The CI setup runs the suite through a GitHub Actions workflow on the master branch, and the repository root has the usual autotools furniture: configure.ac, Makefile.am, autogen.sh, a ChangeLog, a TODO file, src/, tests/, test-all.sh, releasescript/ and vagrant/.

Where bindfs is the wrong choice

Four cases argue against it.

The first is when you need the original files changed. bindfs changes the permissions a user sees at the mount, and the underlying files keep their original mode bits. If your goal is that everyone on the system is unable to write the file, including processes that do not go through the mount, then chmod on the real files is the tool. The mount only affects the path it is mounted at.

The second is a performance-sensitive workload. Every operation goes through FUSE and a userspace daemon, so metadata operations and directory listings are much slower than on a native filesystem. For a directory tree that a build system scans repeatedly, that cost shows up.

The third is macOS or FreeBSD in production. The README is explicit that support there is best-effort and that MacFUSE is not properly supported because it cannot be tested without physical Mac hardware. If you need a supported answer, run the Linux build.

The alternative in the same direction is an ACL-aware filesystem. Linux POSIX ACLs with setfacl, or an NFS export with a restricted anonymous mapping, give you the same sharing of a directory with a list of users without a userspace filesystem in the path. The difference in approach is that bindfs needs no change to the storage at all, so the original tree keeps its own permissions and the restriction lives only in the view, and that is exactly what you want when you cannot modify the directory or when you want two different views of the same data. It is also the difference between a rule enforced by the kernel on every access and one enforced by a daemon that has to be running.

Editorial conclusion

bindfs fits a sysadmin who needs a restricted view of a directory for a specific group of people, since a plain bind mount inherits the source permissions and cannot express a different permission set. It does not fit a case where the change must be enforced on the original files rather than on a view of them, because bindfs changes what a user sees at the mount, not the underlying inode. Build it with `./configure`, `make` and `make install`, add `user_allow_other` to /etc/fuse.conf if non-root mounts should be visible to other users, and treat the MacOS and FreeBSD ports as best-effort.

Frequently asked questions

What is bindfs?

It is a FUSE filesystem that mirrors a directory to another directory, similarly to `mount --bind`, with the permissions of the mirrored directory altered in various ways. You can make a directory read-only, strip the execute bit from executables, share a directory with a list of users or groups, or modify permission bits using chmod-like rules.

How do I build and install bindfs?

Install the build dependencies first, with `apt install build-essential pkg-config libfuse3-dev` on Linux, then run `./autogen.sh` if you cloned the repository, `./configure`, `make` and `make install`. The autogen step is only needed for a clone, not for a release tarball.

Do I need root to use bindfs?

Non-root users can use almost all features, but most interesting use-cases need `user_allow_other` to be defined in `/etc/fuse.conf` so that mounts made by non-root users are visible to other users. On some systems you also need to add your user to the `fuse` group.

Which platforms does bindfs support?

It is developed and tested primarily on Linux with FUSE 3. Linux with FUSE 2, MacOS with fuse-t and FreeBSD with fuse4bsd are best-effort, and MacFUSE might work but is not properly supported since it cannot be tested without physical Mac hardware.

How do I run the bindfs test suite?

With `./test-all.sh`, which requires Ruby and sudo and uses valgrind if installed. Some tests must run as root and some only work as non-root. There is also a Vagrant runner at `vagrant/test.rb` for running the suite on a variety of systems, and `make vagrant-clean` destroys the machines without removing the downloaded images.

Official sources

  1. Issues
  2. License: GPL-2.0
  3. mpartel/bindfs on GitHub
  4. Project website
  5. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/mpartel-bindfs.svg)](https://hysenlabs.com/projects/mpartel-bindfs)

Was this useful?