Earlier quoted context omitted.
Roughly put: in a capability based system, if you have a valid handle for a service, then you can use that service. But the only way you can get a valid handle is to ask your parent process for one --- handles are unforgeable. So your parent gets to check that you're legitimate. ...but your parent, in turn, has limited permissions, because the only way it can get a handle is to ask its parent. And when you ask your p…
That's actually really beautifully simple. Thanks for this explanation, it really helped the idea "click"
Most such languages only go too far by allowing "ambient authority", whereby any component in your program has the ability to turn a reference to a value that carries little authority, into one that carries significantly more authority. For instance, consider the file open API: you're essentially turning a string, which exposes no unsafe or security-critical methods, into an object that can literally destroy your computer. And literally any library or component you use can open files. It's madness!
To make a memory safe language capability secure, you simply remove all sources of ambient authority. This mainly consists of globals that permits transitive access to mutable state, like file system APIs, global static variables that can reference transitively mutable data, etc.
These insecure APIs are then replaced with equivalent object instances which you can pass around, eg. you can only receive the authority to open a file if you're given an instance to the directory object which contains that file. The entry point of your program would then change to accept various capabilities instead of just string parameters.