The Jeeves research mission doge.
Image created using NoodlyTime.com.
Jeeves allows the programmer to separately implement information flow policies from other program functionality while relying on the language runtime to produce the correct outputs.
The way Jeeves allows this is by having the programmer specify multiple views, called facets, of sensitive values. For instance, for my GPS location the programmer can define a high-confidentiality facet that is my actual GPS location and a low-confidentiality facet that is what country I'm in. Such a faceted value is guarded by a label that determines which facet should be used. The programmer associates policies with labels that the runtime uses to determine label values. The programmer can then write policy-agnostic programs: the programs can use faceted sensitive values as normal program values and rely on the runtime to produce the correct output.
Nuts and Bolts
In Jeeves, policies are associated with labels and are functions that take an output channel as the argument and return a predicate saying whether the output channel can allow the given label to be high. For instance, the policy restrict a: λ oc.isFriends(oc, alice) associates with label a the policy that the output channel needs to be friends with user alice in order to see the high-confidentiality facets associated with the label. The Jeeves runtime uses the policies to determine the label values. Policies can depend on sensitive values, potentially causing mutual dependencies between labels.
The Jeeves runtime performs faceted execution to simultaneously execute on the multiple values, producing faceted results from operations on faceted values while performing the bookkeeping on the labels. For instance, evaluation of the expression <a ? 42 : 0> = 42 yields the faceted expression <a ? true : false>. The runtime can handle implicit flows, leakage of information through conditionals on sensitive values; the runtime evaluates conditionals on sensitive values by evaluating both branches and producing a faceted result.
When the program interacts with the outside world, it needs to produce a concrete value. Effectful computations such as print now require an additional output channel argument. The Jeeves runtime uses the output channel argument to produce a system of constraints from the policies in order to assign values to the labels. The runtime can then project out the appropriate result for the output channel.
Information Flow vs. Access Control
Jeeves enforces information flow and not access control. When you only have access control, you're trusting the programmer to tell you correctly at one point where a piece of data is going. Even if a sensitive location value is used in a bunch of search queries, the result of which is shared as a status (that becomes visible to many people with different levels of access), the programmer is responsible for asking for the right level of access when accessing that location. With the complex policies we're starting to see in modern applications, managing this is becoming increasingly burdensome for developers. That's why were looking at how to automatically handle information flow: the system tracks how sensitive values are used in order to make sure the values--and resulting computations--are flowing only to those with appropriate permissions. While it's relatively simple to hook access control into existing programming models, automatically handling information flow requires enhancing the language semantics (especially for conditions and function calls) to track additional information.