Add relabel option to secrets

On selinux enabled system, the secrets cannot be read without proper
relabeling or correct policy being set.

This patch enables user to instruc podman-copose to use :z or :Z podman
volume options to make podman relabel the file under bind-mount.

More info here:
https://unix.stackexchange.com/questions/728801/host-wide-consequences-of-setting-selinux-z-z-option-on-container-bind-mounts?rq=1

Signed-off-by: Jaroslav Henner <1187265+jarovo@users.noreply.github.com>
This commit is contained in:
Jaroslav Henner 2025-05-19 00:16:04 +02:00
parent c26e188991
commit 82d7622c45
No known key found for this signature in database
4 changed files with 42 additions and 1 deletions

View File

@ -27,6 +27,22 @@ services:
For explanations of these extensions, please refer to the [Podman Documentation](https://docs.podman.io/).
## Secrets
The following extension keys are available under `secret` configuration:
x-podman.relabel - Configure SELinux relabeling
For example, the following configures custom-secret to use mount with private and unshared content.
Only the current container can use a private volume.
```yml
secrets:
custom-secret:
x-podman.relabel: Z
```
For explanations of these extensions, please refer to the [podman-run --volume documentation](https://docs.podman.io/en/latest/markdown/podman-run.1.html#volume-v-source-volume-host-dir-container-dir-options)).
## Network management
The following extension keys are available under network configuration:

View File

@ -0,0 +1 @@
- Add relabel option to secret to make possible to read the secret file by the contained process.

View File

@ -577,6 +577,7 @@ def get_secret_args(compose, cnt, secret, podman_is_building=False):
declared_secret = compose.declared_secrets[secret_name]
source_file = declared_secret.get("file")
x_podman_relabel = declared_secret.get("x-podman.relabel")
dest_file = ""
secret_opts = ""
@ -618,7 +619,18 @@ def get_secret_args(compose, cnt, secret, podman_is_building=False):
dest_file = f"/run/secrets/{sec}"
else:
dest_file = secret_target
volume_ref = ["--volume", f"{source_file}:{dest_file}:ro,rprivate,rbind"]
mount_options = 'ro,rprivate,rbind'
selinux_relabel_to_mount_option_map = {None: "", "z": ",z", "Z": ",Z"}
try:
mount_options += selinux_relabel_to_mount_option_map[x_podman_relabel]
except KeyError as exc:
raise ValueError(
f'ERROR: Run secret "{secret_name} has invalid "relabel" option related '
+ f' to SELinux "{x_podman_relabel}". Expected "z" "Z" or nothing.'
) from exc
volume_ref = ["--volume", f"{source_file}:{dest_file}:{mount_options}"]
if secret_uid or secret_gid or secret_mode:
sec = secret_target if secret_target else secret_name

View File

@ -302,6 +302,18 @@ class TestContainerToArgsSecrets(unittest.IsolatedAsyncioTestCase):
"file_secret",
repo_root() + "/test_dirname/my_secret:/run/secrets/file_secret:ro,rprivate,rbind",
),
(
"relabel",
{"file_secret": {"file": "./my_secret", "x-podman.relabel": "Z"}},
"file_secret",
repo_root() + "/test_dirname/my_secret:/run/secrets/file_secret:ro,rprivate,rbind,Z",
),
(
"relabel",
{"file_secret": {"file": "./my_secret", "x-podman.relabel": "z"}},
"file_secret",
repo_root() + "/test_dirname/my_secret:/run/secrets/file_secret:ro,rprivate,rbind,z",
),
(
"custom_target_name",
{