Skip to content

Instantly share code, notes, and snippets.

@ChekhWasTaken
Last active May 19, 2026 22:12
Show Gist options
  • Select an option

  • Save ChekhWasTaken/7e486f562283efae0163b3fa6193fc57 to your computer and use it in GitHub Desktop.

Select an option

Save ChekhWasTaken/7e486f562283efae0163b3fa6193fc57 to your computer and use it in GitHub Desktop.
AppArmor profile for Jellyfin running under Podman 5.4.0
# This is an AppArmor profile designed to limit a running Jellyfin server's
# access to only the resources it requires.
# Profile was tested using Jellyfin 10.11.8, Podman 5.4.2, AppArmor 4.1.0 on Debian 13.5 (trixie) host.
#
# Copyright (C) 2026 Chekhwastaken
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
abi <abi/4.0>,
include <tunables/global>
profile jellyfin flags=(enforce) {
include <abstractions/base>
include <abstractions/nameservice>
include <abstractions/fonts>
include <abstractions/dri-enumerate>
include <abstractions/dri-common>
include <abstractions/opencl-pocl>
include <abstractions/user-tmp>
include <abstractions/ssl_certs>
# allows jellyfin's rtmin signal.
# NOTE: THIS IS CRITICAL, OTHERWISE JELLYFIN INSTANCE WILL RANDOMLY CRASH.
signal (send, read, receive) peer=crun,
signal (send, read, receive) peer=**//&@{profile_name},
deny capability,
deny /dev/tty rwk,
owner @{PROC}/@{pid}/ r,
owner @{PROC}/@{pid}/** r,
/cache/ rw,
/cache/** rwk,
/config/ rw,
/config/** rwk,
/jellyfin/ r,
/jellyfin/** rmk,
# directory where the media archive is located.
# this grants read-only access to media folder.
# consider using rw if you want to let jellyfin to modify the media folder e.g. save metadata, delete files etc
/media/ rk,
/media/** rk,
owner @{PROC}/@{pid}/task/@{pid}/comm rw,
/proc/sys/net/ipv4/conf/*/forwarding r,
/sys/fs/cgroup/memory.max r,
/sys/fs/cgroup/memory.current r,
/sys/fs/cgroup/memory.stat r,
/sys/kernel/mm/transparent_hugepage/enabled r,
/sys/fs/cgroup/cpu.max r,
/sys/devices/pci*/*/* r,
/usr/lib{,64}/ r,
/usr/lib/jellyfin-ffmpeg/ffmpeg ix,
/usr/lib/jellyfin-ffmpeg/ffprobe ix,
/usr/share/zoneinfo{,-icu}/ r,
/usr/share/zoneinfo{,-icu}/** r,
/usr/lib/os-release r,
/{,usr/}bin/curl ix,
}
@mage603

mage603 commented May 19, 2026

Copy link
Copy Markdown

Hey! thanks for this! I know this is a bit old, sorry, but I thought that jellyfin needed execute permissions on directories in the media library in order to search them/view the contents of them, is that incorrect?

@ChekhWasTaken

Copy link
Copy Markdown
Author

Hey! thanks for this! I know this is a bit old, sorry, but I thought that jellyfin needed execute permissions on directories in the media library in order to search them/view the contents of them, is that incorrect?

@mage603
glad that it helped!

you are right that from linux permissions perspective one would need the "x" bit for searching in the directories, however for apparmor reading the directory's content falls under the "r" permission.

execute permission ("ix" and others) cover only actual, program execution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment