The DB label is used for access control. Specifically it is used to enforce who can read/write from/to the database. For instance, the label L_DB = imposes the following restrictions:
The collection label is similar to DB label, but restricts the principals that can access a collection within a DB. For instance, the label L_Coll = imposes the restrictions:
In other words, the collection label can be used to impose restrictions in addition to the DB label.
The collection clearance is used to impose a restriction on the data within the collection. Specifically, the sensitivity of any data in the collection is limited by the collection clearance. For instance, the clearance C_Coll = imposes the restrictions:
Each DB+collection has two forms of policies:
Each policy is a function from a document to a label. In other words, data from the document (e.g., user-name) can be used to label documents/fields.
A document is a set of fields, each field being a key-value pair. A value is a LabeledBSON, meaning that it can be any of the following:
The labeled BSON value is serialized as a BSON document whose key has a prefix that is internal to HAILS (__hails_internal) that no code may use when creating a document. Similarly, a policy-labeled BSON value is serialized as a BSON document with a key whose prefix is __hails_internal. We serialized labeled and policy-labeled values in this manner as to provide some guaranteed in the case of model-changes. Specifically, if version 0 of an application has the password field as a labeled string, and a later version removes (either by accident or malice) the label restriction -- it should not be the case that existing passwords be simply read as unlabeled strings.
A document policy must specify how the document should be labeled. This label protects all the values in the document. In the case of labeled or policy-labeled fields, the document label protects the label of the values.
MongoDB supports standard operations on collections.
Inserting a unlabeled document into a collection requires several steps:
Note that when applying the policies (i.e., performing a label operation) it is required that the label of fields/document be below the current clearance.
Inserting already-labeled documents (with labels possibly above the current clearance) is done as follows:
Note that if any checks in step 3-4 fail, an exception with the document label is thrown (which may be above the current clearance and thus cannot be handled).
Fetching all documents within a collection (i.e., no predicate/WHERE clause) is done as follows:
Getting the next document of a query (find) result for a no-predicate query is done as follows:
Fetching documents within a collection given a non-vacuous predicate on unlabeled fields:
Getting the next document of a complex query (find) result is done as follows:
Note that if in the last step the document label is above the current clearance, the thread will not be able to catch the thrown exception. Note that this leaks a bit of information through termination: there exists a document that matches the given predicate.
An alternative approach can do:
This approach, though more permissive, can be used to leak information though timing. The simple find/next can be used to retrieve all labeled documents, while the complex find/next can be used to perform a query on sensitive data. The duration of the latter query can be used to infer whether there was a match (usually longer, since a next will be performed until we can read something) and the former can be used to infer which document might have matched (the label of the document will likely have some useful information e.g. username).