Ken Muse

Avoiding Dubious Ownership in Dev Containers


It’s always best to run containers with the least privileges required. By default, most dev containers we construct using the default images are configured this way. Unfortunately, that may result in Git operations that fail with the message “detected dubious ownership in repository”. The fix is surprisingly simple.

This issue is easy to reproduce. You will typically see it under these conditions:

  • You are running the container with a non-root user, such as vscode
  • You attempt a Git branch or init operation

Suddenly, you receive an error on-screen and a logged message:

1fatal: detected dubious ownership in repository at '/workspace'
2To add an exception for this directory, call:
3
4    git config --global --add safe.directory /workspace

Why does this happen?

There are two reasons behind this error. First, a vulnerability (CVE-2022-24765) was discovered that could make it possible for untrusted users to take advantage of .git repositories. This was addressed by adding the safe.directory global configuration setting. Git now examines parent directories to determine whether the same user owns both directories. If not, it requires the directory to be whitelisted to enable trust. Without trust, Git will refuse to parse the configuration or run any hooks. This helps to preserve security in a multi-user environment and avoids the chance to apply settings from one user or account to another. When we’re running in a container as a non-root user, we’re effectively running in a multi-user environment and subject to this rule.

The second issue is caused by how Docker mounts file systems. Behind the scenes, the container runtime is responsible for properly handling file permissions and ownership. That process could be an entire post of its own, especially if we examine the differences between Linux, Windows, and macOS! When binding to a local folder, Docker will typically have to use the Docker process’ owner. This means that the folder in the container is often owned by root (UID 0). With a dev container, that typically means that /workspaces is owned by root while the folder containing the source code is owned by the the less privileged user (typically vscode, UID 1000). This creates a situation where the parent folder and code folder are owned by different users. Git will detect this multi-user scenario, triggering the error message.

How do I fix it?

There’s a simple workaround for this issue: add the following line to your devcontainer.json:

1"postStartCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}",

How does this work? As documented at vscode-remote-release#4855, any associated Dotfiles repository is installed after postCreateCommand and before postStartCommand and postAttachCommand. This ensures consistency for the last two commands. We can’t use most of the other lifecycle events that execute prior to postStartCommand. The process of initializing the Dotfiles could erase any .gitconfig created or customized before this point in time. In addition, a local dev container will copy the user’s .gitconfig into the environment if there was no .gitconfig provided by the Dotfiles repository. In short, any changes to .gitconfig before that event are likely to be overwritten and lost.

We also specify the path using the replacement variable ${containerWorkspaceFolder}. This allows the code to target the specific path to our source code. By running this command to add the current directory to safe.directory in .gitconfig, eliminating the warning.

There are (as always) other approaches that can be used to automate this process. For example, you could use a script in your Dotfiles repository to automatically add folders to safe.directory. For situations where you can modify the devcontainer.json, this approach provides a simple way to eliminate the problem.