Classifications
A classification is an attribute that a reader must hold to see a document, following the attribute-based access control (ABAC) model. This page describes how a pipeline defines classifications and inheritance, how a search request selects classifications, how classifications are added and removed, and how classifications relate to encryption. Integrators and administrators need this page to design the classification scheme of a pipeline and to scope search results to an end user.
Classification model
Every document carries exactly one classification, chosen from the classifications that the pipeline defines. Every search request names the classifications that the reader holds, and search returns only fragments whose classification is among those classifications or inherited by those classifications.
Foundation4 assigns no meaning to a classification name. The organization defines what each classification represents: a clearance level, a team, a tenant, a customer account, or a combination of these. The client application maps each end user to the classifications that the end user holds, because the client application holds the identity and entitlements of that user.
Classifications apply to coarse, stable divisions of content. Scoping that changes per request, such as the rooms or projects to which an end user belongs, uses metadata filters. The Metadata, filters and taxonomies page describes metadata filters. Both mechanisms apply to every search mode.
Inheritance
A classification can inherit one or more other classifications. A reader who holds a classification also sees documents that carry any classification inherited by that classification. Inheritance is transitive: when confidential inherits internal and internal inherits public, a reader holding confidential sees all three.
Each arrow points from a classification to the classification that the classification inherits. In this example, a reader holding finance sees documents classified finance, internal and public, but not documents classified confidential.
Defining classifications
The classifications field of POST /pipelines lists the classifications of a new pipeline. Each entry takes one of the following forms:
- Name.
"public"defines a classification with no inheritance. - Pair.
["internal", "public"]defines both classifications, if not already defined, and records thatinternalinheritspublic. - Pair with null.
["public", null]is equivalent to the name alone.
The following list defines the hierarchy shown in the diagram:
"classifications": [
"public",
["internal", "public"],
["confidential", "internal"],
["finance", "internal"]
]
A classification that inherits more than one classification is listed in one pair for each inherited classification.
Classification scope in search
Every search request carries a classification field that names the classifications the reader holds. The field accepts three forms:
| Form | Example | Matching |
|---|---|---|
| String | "classification": "finance" | Hierarchical |
| Array | "classification": ["finance", "public"] | Hierarchical |
| Object | "classification": {"classifications": ["finance"], "search_type": 1} | As set by search_type |
The search_type value selects the matching mode:
- Hierarchical (
2, the default). Search includes the named classifications and every classification that the named classifications inherit, transitively. Names that the pipeline does not define are ignored. - Exact (
1). Search includes only the named classifications. The request fails if any named classification is not defined in the pipeline. - Hierarchical with validation (
3). Search includes inherited classifications, as in hierarchical matching, and fails if any named classification is not defined in the pipeline.
Foundation4 applies the classifications that the request names. The client application is responsible for naming only the classifications that the end user holds. For content with strict access rules, the client application also confirms the end user's access to each result before displaying the result.
Changing classifications
GET /pipelines/{id}/classifications returns the pipeline's classifications in classifications and the inheritance relationships as pairs in hierarchy. The classifications array is in no defined order. POST /pipelines/{id}/classifications changes both and returns status 200 with an empty body. The request body contains an add list and a remove list, each using the entry forms described in Defining classifications. Foundation4 processes additions before removals, in one transaction. Removing a name that the pipeline does not define changes nothing.
Reading the classifications requires read permission on the pipeline, and changing them requires write permission. Both also require the allow-list * on the pipeline, because the response and the changes cover every classification and the inheritance relationships. Classification allow-lists describes the allow-list.
| Change | Entry | Effect |
|---|---|---|
| Add a classification | "restricted" in add | Creates the classification and a new encryption key. An existing classification is left unchanged. |
| Add inheritance | ["restricted", "confidential"] in add | Creates any missing classification and records the inheritance |
| Remove inheritance | ["finance", "internal"] in remove | Removes the inheritance relationship. Both classifications and their documents remain. |
| Remove a classification | "finance" in remove | Removes the classification, the classification's inheritance relationships and encryption key, and every document and fragment that carries the classification |
Removing a classification permanently deletes the content that carries the classification. Content that must be retained under a different classification is submitted again with the new classification before the old classification is removed.
A document keeps the classification assigned at first submission. Every later version of the document must carry the same classification, as described in Documents, versions and fragments.
Classifications and encryption
Each classification has a dedicated encryption key, generated when the classification is created. Foundation4 encrypts the text of every fragment with the key of the fragment's classification, using ChaCha20-Poly1305. The keys are stored in the pipeline's classifications table in PostgreSQL. Removing a classification removes the classification's key together with the content encrypted under that key. Data protection describes the scope and limits of this encryption.