I think we're just talking past each other- by "leak" I was talking about something like accidentally sharing an fd number, not actually communicating the capability itself. This is how Dropbox's approach is a "fuzzy emulation"- you can in principle forge a URL in a way that you could never forge a file handle.
Obviously if you communicate the actual capability itself to someone you didn't intend to, that would be bad. But that's more of a question of API design- even fork is, in this sense, asking for the capability to be transferred. This is a very different problem than the one Dropbox has- no amount of random guessing, or side channel information leaks, or anything else like that, is going to land a capability in another process's kernel table.
Yes, accidentally sharing a capability is a leak. If I accidentally printed out a capability it would be 'leaked' and anyone who reads that capability now has obtained it an dcan use it.
> you can in principle forge a URL in a way that you could never forge a file handle.
Maybe it would be better to not talk about fs apis, because they're not really capability based, so I suspect that's the confusion.
The point is that if someone has a capability, they have that capability. There is no additional access control or checking in a capability based system. You absolutely have to consider things like rotation and revocation.
I'm specifically talking about Fuchsia and other kernel-based capabilities here. You fundamentally cannot print out that kind of capability in any way that matters- the only thing that determines whether a process has it is the table in the kernel, not whether it can produce a particular bit pattern.
In this sense, fs APIs are a fine example, as long as you keep the ls/.. caveats in mind. If you have a file descriptor for something inaccessible through the global file system namespace, then the only way to grant that to another process is via specifically-designed APIs like domain sockets or fork.
As I said in my first comment, there are of course other reasons you might want to revoke a capability. But unlike Dropbox URLs, true capabilities are unforgeable, so you don't need to rotate them out simply to make them harder to guess- they're already unguessable.
How so? The line you quoted from Wikipedia calls them unforgeable. If you can forge it (by printing it out and reading it back in from somewhere else, or by guessing a bit pattern) then surely it's not a capability?
So to recap, a capability is a value that represents authorization. The value must not be forgeable, the value must be communicable.
If I'm unable to convey authorization by giving you the token, it is not a capability. If I am able to guess the token, it is not a capability.
Delegation is not forgery. Forgery would be an entity creating a token without the token being delegated to that entity. Guessing is forgery, but you can "guess" a uuid in the same way that you can "break AES" with a bruteforce, which is to say, you can't.
> If I'm unable to convey authorization by giving you the token, it is not a capability. If I am able to guess the token, it is not a capability.
You're taking "communicable" too literally. It doesn't mean "literally giving someone else this bytestring and now they can do it, too". It means "there is a way to give someone else the capability". SCM_RIGHTS is such a way to communicate capabilities between processes. Further up above you're also conflating files and file descriptors, which are very different things.
No, it does not mean there is "a way", it means that the name is the permission. Period. That is what a capability is. If the name is not the permission, it is not a capability.
It can mean what the parent is talking about, and does in this case. It's an older morph of capability based security than the newer crypto enforced name concept, but equally valid.
You can read more about it in Capability Based Computer Systems by Henry M Levy. The Hydra MMP, GE-645, and iAPX 432 are older implementions of this concept in hardware.
In both cases (TCB table enforced and crypto one way function enforced) the name is the capability, but in a kernel (or hardware) table enforced method that's interpreted to mean that you have permission to access the object by having a simply having reference to it in your descriptor table.
You can see this also in KeyKOS, EROS, Coyotos, XOK, and SeL4 among many other capability based kernels. They don't give you a capability just because you got access to a global name to the backing object; the whole shtick for them is there is no global names for objects, only descriptor tables.
What you're referring to is how operating systems maintain the integrity of capabilities. This is addressed directly in 'Capability Based Computer Systems'. I would direct you to chapter 1 section 1.1.
> A capability thus provides addressing and access rights to an
object.
> a program cannot access an object unless its capability list contains a
suitably privileged capability for the object.
> Capability system integrity is usually maintained by prohibiting direct program modification of the capability list. The
capability list is modified only by the operating system or the
hardware.
> Thus, a program can execute direct control over the movement
of capabilities and can share capabilities, and therefore, objects, with other programs and users.
You can think of capabilities lists as kernel managed namespaces if you'd like. Maybe that would help clear things up.
In these non crypto enforced capability systems, you don't have any control over other processes' names for resources addressed through capabilities is the point I'm attempting to get across.
Crypto backed capabilities that merge the token with the capability itself are one morph of capability based systems, but that's not the scheme being described here. Leaking the name of a capability (the offset in the cap table) does not leak the capability itself in these TCB schemes. Capabilities are still communicable in these TCB schemes because they're explicitly supported in the IPC mechanisms like SCM_RIGHTS or seL4_Send along side normal data. The token naming a capability then is a per process concept and you can clone an identical capability into several tokens in the same cap table, unlike the crypto enforced scheme which are basically content addressed storage for a secret representing a capability.
Semantics aside, is it accurate to say that schemes where the capability is represented as a signed token require care and diligence to mitigate leaks, and schemes where the capability is represented as a table entry (mapping a user/process to a permission) don't require any meaningful care/diligence?
Though, it is still worth thinking about how someone might accidentally leak a table-based capability via API misuse. For example, if table entries are reused over time you might get a sort of use-after-free situation where you mean to share an old capability but accidentally share the new one that replaced it.
Yes- the thing you didn't mention is the distinction I'm making between Dropbox URLs/UUIDs/etc and fds/Fuchsia capabilities, which is that the former are bit patterns and the latter are pieces of state in a trusted kernel.
The attack surface of "bit pattern" capabilities is much larger than that of "trusted state" capabilities- even if you can't practically guess one, all you need to break it is to discover its bit pattern somehow. Trick someone into printing it out, read it out of their memory space, leak it via a side channel, attack their UUID generator, etc. For this kind of capability, sure- periodic revocation might be a worthwhile mitigation technique.
But for "trusted state" capabilities, which is where this thread started, and what file descriptors exemplify, this all goes away. The attack surface is reduced to the kernel and the component's own API (nothing new here) and its use of a finite set of capability delegation APIs. Leaking an fd number does not leak the corresponding capability the way leaking a Dropbox URL does, so there is relatively little purpose in rotating those out.
I wouldn't call it attack surface, I would call it a threat model. And yes, the threat model of capabilities includes the fact that knowledge of the capability connotes the capability. If it didn't, it wouldn't be a capability.
Then you've spent this entire thread arguing over clearly-explained terms of art, what a colossal waste of effort. I'm sorry to inform you: this is not how Fuchsia uses the word "capability."
Using your version of the word, since you appear incapable of operating in any other frame, Fuchsia does not use capabilities, and thus does not have the problem of leaking permissions via bit patterns. The original question of whether they need to be rotated periodically does not apply here.
There's really no debate here. I'm right. A capability is defined as I have defined it. You can say "well Fuschia says otherwise", that's fine, people are wrong about things all the time. Such is life.
Of course I've spent this entire thread explaining a clearly defined term, was that not obvious?
And yes, rotation is relevant to capabilities because leaking capabilities is a critical failure. It's not the only way to protect capabilities though, you can add ACLs or namespaces, which is what Fuschia seems to do.
Obviously if you communicate the actual capability itself to someone you didn't intend to, that would be bad. But that's more of a question of API design- even fork is, in this sense, asking for the capability to be transferred. This is a very different problem than the one Dropbox has- no amount of random guessing, or side channel information leaks, or anything else like that, is going to land a capability in another process's kernel table.