Dev container and SELinux

After creating a new project + dev container using VSCode on a Fedora 43 system, I have observed what appears to be permission related issues.

Now, I am not entirely convinced if this is an actual bug nor if it is, which product the bug is caused by. For all I know it might be either or both.

Is this known or expected behavior? If it is, is ther a setting I need to change to allow this? Is there some information I should redirect to the team maintaining the vscode-remote-release project?

  • VSCode Version:
Version: 1.105.1
Commit: 7d842fb85a0275a4a8e4d7e040d2625abbf7f084
Date: 2025-10-14T22:33:36.618Z
Electron: 37.6.0
ElectronBuildId: 12502201
Chromium: 138.0.7204.251
Node.js: 22.19.0
V8: 13.8.258.32-electron.0
OS: Linux x64 6.17.5-300.fc43.x86_64
1.105.1
7d842fb85a0275a4a8e4d7e040d2625abbf7f084
x64
  • Local OS Version: Fedora 43 (freshly installed 42 and upgraded to 43)
$ uname -a
Linux laptop 6.17.5-300.fc43.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Oct 23 15:35:13 UTC 2025 x86_64 GNU/  Linux
$ cat /etc/os-release 
NAME="Fedora Linux"
VERSION="43 (Workstation Edition)"
RELEASE_TYPE=stable
ID=fedora
VERSION_ID=43
VERSION_CODENAME=""
PRETTY_NAME="Fedora Linux 43 (Workstation Edition)"
ANSI_COLOR="0;38;2;60;110;180"
LOGO=fedora-logo-icon
CPE_NAME="cpe:/o:fedoraproject:fedora:43"
DEFAULT_HOSTNAME="fedora"
HOME_URL="https://fedoraproject.org/"
DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora/f43/"
SUPPORT_URL="https://ask.fedoraproject.org/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Fedora"
REDHAT_BUGZILLA_PRODUCT_VERSION=43
REDHAT_SUPPORT_PRODUCT="Fedora"
REDHAT_SUPPORT_PRODUCT_VERSION=43
SUPPORT_END=2026-12-02
VARIANT="Workstation Edition"
VARIANT_ID=workstation
$ sestatus 
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Memory protection checking:     actual (secure)
Max kernel policy version:      35
  • Remote OS Version: "image": "mcr.microsoft.com/devcontainers/python:2-3.12-bullseye"
  • Remote Extension/Connection Type: Dev Containers
  • Logs: see below

Steps to Reproduce:

  1. create new, empty project
  2. add main.py with content (just to rule out the cause being an empty source directory):
    if __name__ == "__main__":
     print("main called")
    
  3. add default dev container based on mcr.microsoft.com/devcontainers/python:2-3.12-bullseye
  4. build dev container
  5. when build succeeds observe empty workspace in file explorer
  6. execute :
     vscode âžś /workspaces/testQwe $ python main.py
     python: can't open file '/workspaces/testQwe/main.py': [Errno 13] Permission denied
     vscode âžś /workspaces/testQwe $ ls
     ls: cannot open directory '.': Permission denied
    
  7. close remote connection
  8. temporarily disable SELinux by
$ sudo setenforce 0
  1. Rebuild dev container
  2. observe populated file explorer and successful re-execution of step 6.

Does this issue occur when you try this locally?: No
Does this issue occur when you try this locally and all extensions are disabled?: No

Dev container build log:

Bug report:

I am having a hard time reading the log, it would have been nice to see the actual devcontainer.json you are using.

In any case, container volume errors with SELinux are usually a result of incorrect labels. To get the system to label the volumes correctly, you need append the :z (two or more containers sharing the same label) or :Z (private label, only valid for a single container) options to a volume mount. See the info on volumes in the podman-run man page for more information.

In devcontainer.json, this would look something like this:

{
    "name": "python",
    "image": "mcr.microsoft.com/devcontainers/python:2-3.12-bullseye",
    "workspaceMount": "source=${localWorkspaceFolder}/,target=/workspace,type=bind,consistency=cached,Z",
    "workspaceFolder": "/workspace",
    [...]

Notice the ,Z option at the end of "workspaceMount=...,Z".

1 Like

There are also more verbose alternatives (if, like me, you find it difficult to remember which one is Z and which is z).

"workspaceMount=..,relabel=private" (same as Z)

or

"workspaceMount=..,relabel=shared" (same as z)

1 Like

Cool, I did not know that. And yes, I have to look it up every time, too. :slight_smile:

Though, for devcontainers it should only make a difference if you intend to open the same workspace in multiple VS Code instances and devcontainers in parallel.

I am having a hard time reading the log, it would have been nice to see the actual devcontainer.json you are using.

Yeah, the log is not super great but the devcontainer.json was a vanilla/default one generated by the vscode extension with no modifications.

If am I understaning this correctly, in order for this to work on a SELinux enabled system, I need to have the system label the bind mounts properly? If that is so, I would have expected this to be handled by the devcontainer extension for VSCode in the first place. Guess I need to update the bug report with this information.

Though, for devcontainers it should only make a difference if you intend to open the same workspace in multiple VS Code instances and devcontainers in parallel.

Which as far as I remember, was not the case (but not ruling out that it could have been).

I will give it a go when I am back at work tomorrow (my box at home is not running Fedora yet). Will post update.

Thanks.

I think I wasn’t very clear in my post. This was referring to @pg-tips’s comment about the difference between :z and :Z. And this difference is only relevant if you try to access files from more than one container (which requires the shared label). As long as your devcontainer.json has either of them, it should work, at least for the first container instance.

In any case, if you use the shared label, you should be good, even if you start multiple instances, though this technically lowers the isolation between containers.

Correct. When mounting a volume into a container with SELinux, you need to tell your container solution which labels to apply. It cannot know this. With Podman, this is done by adding :(z|Z) after a -v option:

podman run -d --name busybox-iostat -v ./src:/dest:Z busybox iostat 1 

Check out this article for a longer explanation.

I doubt they will consider this a bug, it is just the normal behavior of containers on SELinux systems. But it is worth a try.

I can see the attraction of VSCode auto-adding the “relabel” bit to the mount spec for you.

On the other hand, the devcontainer JSON is supposed to be an open standard, and you could argue that IDEs shouldn’t be making changes that cause the same JSON to behave differently on different IDEs.

1 Like

You are on a roll today, teaching me new things. :grinning_face: I was actually looking for documentation about the devcontainer.json file (I wasn’t looking too hard, though).

1 Like