Capabilities are more general than that. They have been around for a long time; one academic design implemented them in hardware in 1970[1]. they can be used in as fine grained a way as 'you are allowed to access this array in memory and nothing else'- which is the sort of thing that needs to be built into languages to be maximally useful.
I disagree about your last point. I looked at a product design once which allowed one to associate a profile with each third party library. accesses across library boundaries were implementing using classic call gates from segmented architectures which could change memory visibility and syscall filtering.
so while I agree that language integration is really useful, I think you can get a lot out of appropriate support in the runtime, most notably the library loader.
[1] https://en.wikipedia.org/wiki/CAP_computer