How are the apparmor profiles generated?

I was having some issues with running pulseaudio in the container. Mostly syslog on the host was saying the access to a /run/user/1000/pulse/native was denied by apparmor. Eventually after changing the profile from unix:/run/user ... to unix:/var/run/user ... and back again, and also rearranging the fields in the container attached profile, the apparmor denied message disappeared.

In addition i tried manually editing /var/snap/lxd/common/lxd/security/apparmor/profiles/lxd_forkproxy-PulseSocket. Though this didn’t seem to have any effect.

Is this profile generated automatically on every lxc profile edit <name>? And shouldn’t manually adjusting it and restarting the container get apparmor to reparse this?

New profiles are generated on every startup of the container as well as on relevant config changes.

AppArmor isn’t super smart about symlinks and effectively always dereferences them.
So if you have /var/run/... in your proxy device path and /var/run is a symlink to /run/, you really ought to just put /run/... in your device path to avoid weirdness.

I did explicitly change the apparmor profile to include a new line to encompass both cases, but apparmor was still complaining after i restarted the container.

I’ve just tried stopping lxd, manually editing the lxd/security/apparmor/profiles, starting lxd, starting the lxc container. It seems like the apparmor profiles are generated and stored in that directory, and don’t have any bearing on running containers as i had hoped.

So yes good to know