AppID: Separate checking credentials from assigning identifiers
Currently, the trait the kernel uses to check credentials and assign IDs is kernel::process_checker::CredentialsCheckingPolicy, which looks like the following:
pub trait CredentialsCheckingPolicy<'a>: AppCredentialsChecker<'a> + Compress + AppUniqueness {}
That is, the kernel holds a single reference to an object which checks credentials (AppCredentialsChecker), checks if multiple process binaries are unique (AppUniqueness), and assigns short IDs (Compress).
Proposal
I propose we remove CredentialsCheckingPolicy to effectively split these operations. Further, I propose we change the app checking logic to only check credentials, and execute the Compress (aka assigning ShortID) as a separate stage of loading a process.
Issues with the current design
-
Credentials make for bad AppIDs. Credentials are by design intended to be a summary of the integrity region of the installed process, and any changes to the process binary or TBF headers necessarily changes the credential. Also, credentials themselves cannot be verified, so they cannot contain any trusted content. On the other hand, AppIDs are persistent across versions of an app. Changes to the process binary, for example, should not change the AppID.
Using credentials to assign AppIDs can be done correctly, but can also easily be done improperly. For example, including an AppID within the credential might seem reasonable (i.e. "if this credential is accepted then use this id"), but the kernel cannot verify the integrity of the id appended to the credential. That ID also cannot be included within the integrity region the credential covers. Another mistake would be assigning the ID based on the credential itself. For example, using the first four bytes of a hash. This will change every time the app changes, violating the goal of AppID.
-
AppIDs are only assigned if the installed process has credentials. This makes it difficult to realize some of the use cases from the AppID TRD, for example, a research use case where resources want to be mapped to specific apps, but security isn't required.
There is perhaps an argument that IDs should only be assigned if the app can be verified. I think many systems might want to preserve that, but it shouldn't be required. Also, as a side-effect of the current implementation, any credential is sufficient today, even padding.
-
It is helpful to be able to mix-and-match credential checkers and ID assigners. Different kernels might want to use different credentials, but might derive IDs in the same way (e.g. from the process name, or from a specific TBF header). Or vice-versa. Right now it would require some boilerplate to enable this, and it isn't clear that new app checkers should enable this level of flexibility.
Open questions
- Do we need to closely tie app identifiers to credentials? Now that we have an implementation we can look at, and reading over the AppID TRD, the various mechanisms and structure (i.e. the integrity region, putting credentials at the end, requiring unique app ids) were carefully designed and address specific use cases. But I don't think that the design and use cases require that AppID assignments have to be intertwined with credential checking at the implementation level.
- Do apps need to have credentials to have an AppID? Certainly the example of using the private key used to sign an app as the identifier would require that credential. But the examples of using the process name or the write_id do not.
One concern: in some cases it is critical that the AppID is not assigned unless the process has a valid credential. The traits should make this requirement obvious, and not just leave the to_short_id() implementation (or other functions) to implement this correctly.