The assumption is easy to absorb and hard to notice: a VPN connect hook runs as root, so the mount it starts should be arranged as root too. That reasoning produces a team directory the desktop user cannot open, a mount that disappears when the triggering service restarts, and an authentication prompt in a context where nobody can answer it. The hook and the mount are two different jobs, and only one of them needs privilege.

The Myth: Network Privilege Implies Mount Privilege

Raising an interface and authenticating to a file server are unrelated capabilities, and they normally belong to different accounts. The VPN component needs enough privilege to change routes and interfaces. The file-server account needs a key or a password, a host-key decision, and a home directory to mount into. Handing the second job's credentials to the first identity is how a network service ends up holding a user's key.

On a single-user laptop those may be the same account, and that coincidence is not a design.

Once a privileged hook does the mounting, three things go wrong quietly. The mount is owned by root, the user's agent is absent from that environment, and failures surface in the network service's log rather than in the session that cares. None of those are repaired by adding options to the mount command. They are repaired by giving the job to the session that owns the identity.

Why the Mount Belongs to the Logged-In User

An SSHFS mount is a FUSE mount owned by the process that created it, and access follows that ownership rather than the parent directory's mode. The reference recommends a regular user with a mountpoint that user owns, which is exactly why a mount created by a root process is awkward for everyone else. A permission change on the mountpoint does not repair it, because the obstacle is the mount's own owner.

Start from a manual baseline inside the user's session: an existing empty mountpoint under the home directory, an authorized account on the server, and a host key already verified through your approved process. Mount it by hand once and use it, because that proves the identity path works before any automation exists. Note what the command needed, meaning the account name, the export path and the private hostname. Keep that exact context for the automated version, since a working manual mount is the specification the trigger must reproduce.

sshfs [email protected]:/exports/team "$HOME/mnt/team"

Treat every name and path in that line as a placeholder, including the account and the export. A VPN account password is not automatically the storage account's credential.

What the Trigger Should Ask the Session to Do

The supported arrangement is a request from the network event to the user's session, not a borrowed credential. Scope the trigger to the connection you mean, by name or UUID, rather than to any interface that happens to be called tun0. That single change stops a second profile, a test tunnel or a colleague's debugging session from starting a mount.

The session-side action should look for the intended existing mount and then make one bounded attempt.

Do not retry on every poll, and do not keep prompting for a credential while the server is unreachable, because both turn a transient outage into an account lockout. An unattended service is a separate design with its own approved credential and host-verification arrangement in its own execution context, and it cannot rely on somebody having unlocked a graphical agent. Decide which of the two you are building before choosing where the code lives. Most of the confusion here comes from building one and expecting the other.

Disconnect Is a File-System Event, Not a Hook Event

A planned disconnect should finish file operations and unmount from the mounting user's session with the supported command for that filesystem type. Forcing a detach to make a hook return quickly is how applications lose their working directory and users lose confidence in the automation. A busy mount needs an application-level decision, such as closing the file or stopping the write, not a stronger signal. The hook's exit status is not the thing being optimised.

fusermount3 -u "$HOME/mnt/team"

Unexpected loss is a different case, and SSHFS documents that an interrupted operation can block while the transport reconnects.

The reconnect option restores the transport, and files opened before that reconnection can still return errors and need reopening. A returning VPN proves nothing about earlier handles or unsaved work. Choose the behaviour you want on an outage, whether that is pausing, surfacing an error or remounting on purpose, and test it with disposable files before anything depends on it.

Inyandiko zihuye