One of my scripts dynamically creates a symlink like so:
ln -s /home/hosting/projects/images /home/hosting/projects/demo/images
How can I make it so that the access through link is read-only?
You can create a read-only bind-mount.
This completely lives in the Virtual Filesystem layer (VFS), so this it's not specific to any filesystem, nor do you really 'mount' anything. So, basically, this is creating a sort of symbolic link for you, but this doesn't show up as such.
Yes, this must be done in two steps in kernels after Linux kernels 2.6.25 (see the link above for why).