It shouldn't need to have all of those rights though.The client code base is quite complicated since it use CEF which uses Chromium. I don't understand all of it. The current client actually doesn't detect properly if another instance is running (which is another bug).
It does query /proc/ a bit though. I see this with strace:
$ spotify --version
Spotify version 1.0.93.238.g2712e516, Copyright (c) 2018, Spotify Ltd
$ strace /usr/bin/spotify 2>&1 | grep '/proc/'
readlink("/proc/self/exe", "/usr/share/spotify/spotify", 4096) = 26
openat(AT_FDCWD, "/proc/filesystems", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/proc/self/cmdline", O_RDONLY) = 4
readlink("/proc/self/exe", "/usr/share/spotify/spotify", 64) = 26
readlink("/proc/self/exe", "/usr/share/spotify/spotify", 4096) = 26
readlink("/proc/self/exe", "/usr/share/spotify/spotify", 4096) = 26
readlink("/proc/self/exe", "/usr/share/spotify/spotify", 4096) = 26
readlink("/proc/self/exe", "/usr/share/spotify/spotify", 4096) = 26
readlink("/proc/self/exe", "/usr/share/spotify/spotify", 4096) = 26
readlink("/proc/self/exe", "/usr/share/spotify/spotify", 4096) = 26
openat(AT_FDCWD, "/proc/meminfo", O_RDONLY|O_CLOEXEC) = 37
stat("/proc/meminfo", {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
openat(AT_FDCWD, "/proc/vmstat", O_RDONLY|O_CLOEXEC) = 37
stat("/proc/vmstat", {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
readlink("/proc/self/exe", "/usr/share/spotify/spotify", 4095) = 26
readlink("/proc/self/exe", "/usr/share/spotify/spotify", 99) = 26
readlink("/proc/self/exe", "/usr/share/spotify/spotify", 64) = 26
readlink("/proc/self/exe", "/usr/share/spotify/spotify", 64) = 26
I wonder if it is following the symlink /proc/self that makes it need /proc/* access? I have never used apparmor, but would something like:
@{PROC}/@{pid}/** r,
work?