#include <tunables/global>

# To audit denials after deploying, SSH into HA, then:
# journalctl _TRANSPORT="audit" | grep 'apparmor="DENIED"' | grep trmnl-ha
profile trmnl-ha flags=(attach_disconnected,mediate_deleted) {
  #include <abstractions/base>
  #include <abstractions/nameservice>

  # Container working directory and filesystem root
  / r,
  /app/ r,

  # =============================================================================
  # CAPABILITIES (minimal set for container operation)
  # =============================================================================

  capability chown,
  capability dac_override,
  capability dac_read_search,
  capability fowner,
  capability fsetid,
  capability kill,
  capability setgid,
  capability setuid,
  capability net_bind_service,
  capability sys_chroot,

  # =============================================================================
  # SIGNALS
  # =============================================================================

  signal (send) set=(kill,term,int,hup,cont),
  signal (receive),

  # =============================================================================
  # CONTAINER INIT & ENTRYPOINT
  # =============================================================================

  /usr/local/bin/docker-entrypoint.sh rix,
  /bin/** rix,
  /usr/bin/** rix,
  /lib/** rm,
  /lib64/** rm,
  /usr/lib/** rm,

  # Binaries and libraries the image installs under /usr/local: the Bun
  # runtime, the ImageMagick 7 binary, and the convert wrapper all live here
  /usr/local/bin/** rix,
  /usr/local/lib/** rm,

  # =============================================================================
  # BUN RUNTIME
  # =============================================================================

  /root/.bun/ rw,
  /root/.bun/** rwkix,

  # =============================================================================
  # APPLICATION (/app)
  # =============================================================================

  /app/ r,
  /app/** r,
  /app/*.js rix,
  /app/*.ts r,
  /app/node_modules/** rm,
  /app/node_modules/.bin/** rix,
  # esbuild ships a native binary tsx spawns on the Node fallback path (#24)
  /app/node_modules/@esbuild/*/bin/* rix,

  # Logs and output directories (read/write/create)
  /app/logs/ rw,
  /app/logs/** rwk,
  /app/output/ rw,
  /app/output/** rwk,

  # =============================================================================
  # DATA PERSISTENCE (/data - mounted by HA Supervisor)
  # =============================================================================

  /data/ rw,
  /data/** rwk,

  # =============================================================================
  # TEMPORARY FILES
  # =============================================================================

  /tmp/ rw,
  /tmp/** rwk,
  /var/tmp/ rw,
  /var/tmp/** rwk,
  /run/ rw,
  /run/** rwk,
  /dev/shm/ rw,
  /dev/shm/** rwk,

  # =============================================================================
  # CHROMIUM BROWSER
  # =============================================================================

  # Chromium binaries and launch wrapper config. The helper executables
  # (chrome-sandbox, chrome_crashpad_handler) need exec, so the tree is rix.
  /usr/bin/chromium rix,
  /usr/lib/chromium/ r,
  /usr/lib/chromium/** rmix,
  /etc/chromium.d/ r,
  /etc/chromium.d/** r,
  /etc/chromium/ r,
  /etc/chromium/** r,

  # Chromium needs to read /proc for sandboxing, and to tune its own
  # processes (out-of-memory score, reference clearing)
  @{PROC}/ r,
  @{PROC}/** r,
  @{PROC}/sys/kernel/random/uuid r,
  owner @{PROC}/*/oom_score_adj rw,
  owner @{PROC}/*/clear_refs w,

  # Device access
  /dev/null rw,
  /dev/urandom r,
  /dev/tty rw,
  /dev/dri/ r,
  /dev/dri/** rw,
  /sys/** r,

  # Chromium user data and cache
  owner /root/.config/ rw,
  owner /root/.config/** rwk,
  owner /root/.cache/ rw,
  owner /root/.cache/** rwk,
  owner /root/.local/ rw,
  owner /root/.local/** rwk,
  owner /root/.pki/ rw,
  owner /root/.pki/** rwk,

  # Fonts for rendering. fontconfig enumerates the font directories, so the
  # directory entries are read on top of their contents, and it takes file
  # locks on its cache.
  /usr/share/fonts/ r,
  /usr/share/fonts/** r,
  /usr/local/share/fonts/ r,
  /usr/local/share/fonts/** r,
  /usr/share/fontconfig/ r,
  /usr/share/fontconfig/** r,
  /etc/fonts/** r,
  /var/cache/fontconfig/ r,
  /var/cache/fontconfig/** rwkl,

  # =============================================================================
  # IMAGEMAGICK
  # =============================================================================

  /usr/bin/convert rix,
  /usr/bin/identify rix,
  /usr/bin/mogrify rix,
  /usr/lib/*/ImageMagick*/ r,
  /usr/lib/*/ImageMagick*/** rm,
  /usr/local/lib/ImageMagick*/ r,
  /usr/local/lib/ImageMagick*/** rm,
  /etc/ImageMagick*/ r,
  /etc/ImageMagick*/** r,
  /usr/local/etc/ImageMagick*/ r,
  /usr/local/etc/ImageMagick*/** r,
  /usr/share/ImageMagick*/ r,
  /usr/share/ImageMagick*/** r,

  # =============================================================================
  # NETWORK (allow TCP/UDP for HTTP server & webhooks)
  # =============================================================================

  network inet stream,
  network inet6 stream,
  network inet dgram,
  network inet6 dgram,
  network unix stream,
  network unix dgram,

  # =============================================================================
  # SYSTEM FILES (read-only)
  # =============================================================================

  /etc/hosts r,
  /etc/resolv.conf r,
  /etc/nsswitch.conf r,
  /etc/ssl/ r,
  /etc/ssl/** r,
  /etc/ca-certificates/ r,
  /etc/ca-certificates/** r,
  /usr/share/ca-certificates/ r,
  /usr/share/ca-certificates/** r,
  /etc/passwd r,
  /etc/group r,
  /etc/localtime r,
  /etc/timezone r,
  /etc/mime.types r,
  /etc/machine-id r,
  /etc/ld.so.cache r,
  /etc/ld.so.preload r,

  # Chromium probes these on startup; it falls back cleanly when absent, but
  # reading them keeps the audit log quiet
  /etc/pulse/** r,
  /usr/share/glib-2.0/** r,

  # =============================================================================
  # EXPLICIT DENIALS (defense in depth)
  # =============================================================================

  # Deny raw/packet sockets (prevent packet sniffing)
  deny network raw,
  deny network packet,

  # Deny mount operations
  deny mount,
  deny umount,
  deny pivot_root,

  # Deny ptrace (debugging other processes)
  deny ptrace,

  # Deny kernel parameter modification
  deny @{PROC}/sys/kernel/** w,
  deny @{PROC}/sys/net/** w,

  # Deny access to Home Assistant directories
  deny /homeassistant/** rwx,
  deny /config/** rwx,
  deny /ssl/** rwx,
  deny /addons/** rwx,
  deny /backup/** rwx,
  deny /media/** rwx,
  deny /share/** rwx,
}
