diff --git a/src/packages.md b/src/packages.md index da38dd5c..46c31564 100644 --- a/src/packages.md +++ b/src/packages.md @@ -1,7 +1,7 @@ ## Package Management Every non-trivial Flix project should have a `flix.toml` manifest. The manifest -contains information about the project and its dependencies. +contains information about the project and its dependencies. A minimal manifest is of the form: @@ -15,7 +15,7 @@ license = "Apache-2.0" authors = ["John Doe "] ``` -> **Note:** The `flix` field is not yet used, but it will be used in the future. +> **Note:** The `flix` field is not yet used, but it will be used in the future. ### Adding Flix Dependencies @@ -43,9 +43,9 @@ We can also add dependencies on Maven packages to the manifest: Flix dependency resolution works as follows: 1. Flix reads `flix.toml` and computes the transitive set of Flix package - dependencies. + dependencies. 2. Flix downloads all of these Flix packages. -3. Flix inspects each package for its Maven dependencies and downloads these. +3. Flix inspects each package for its Maven dependencies and downloads these. We illustrate with an example. Assume we have a Flix package with: @@ -87,3 +87,55 @@ This happens because `flix/museum` has the following dependency tree: - `flix/museum-clerk` - `flix/museum-restaurant` which depends on - `org.apache.commons:commons-lang3` + +### Security & Trust Levels +To reduce the risk of supply-chain attacks, every dependency +has a *trust* level--even if you don't set one explicitly. +Trust levels control which language features a dependency may use. +Higher trust levels enable more features but also increase +the risk of supply-chain attacks. + +The trust levels are as follows (from lowest to highest): +- `paranoid`: forbids Java interop, the `IO` effect, and unchecked casts. +- `plain` (default): permits the `IO` effect but forbids Java interop + and unchecked casts. +- `unrestricted`: allows Java interop, the `IO` effect, and unchecked casts. + +You can set the trust level of each dependency in the manifest like so: +```toml +[dependencies] +"github:flix/museum" = { "version" = "1.4.0", "trust" = "plain" } +"github:magnus-madsen/helloworld" = { "version" = "1.3.0", "trust" = "unrestricted" } +``` + +Trust levels are transitive: a dependency's trust level also applies +to its transitive dependencies, unless a dependency explicitly declares +a lower trust level. +If multiple dependencies require the same library, +the library inherits the lowest trust level requested. + +The recommended approach is to **not** specify a trust level, thus +defaulting to `plain`. +It provides the best balance between flexibility and safety. +You should avoid `unrestricted` when possible, as it permits +(transitive) dependencies to do *anything*. +Even building or compiling code that includes `unrestricted` dependencies +can by itself expose you to a supply-chain attack. +However, the package manager never downloads a package +that declares Java dependencies in its manifest if it has +trust level `plain` or lower. + +You should attempt to only depend on core library packages +and use your own handlers (or in some cases default handlers). +This allows you to limit what parts of the system a program +can access, e.g., such as only allowing certain directories +to be accessed or black/white-listing URLs. + +If you author a Flix library, e.g., `webserver`, that uses Java, +split it into two packages: a core library `webserver-lib` that +implements pure logic and custom effects, and a separate handler +package `webserver-lib-handlers` that performs Java interop. +Doing so also makes the core library easier to test and review. +Try to keep effects small and focues and document the expected +handler behavior so users can implement their own handlers if +they do no wish to use handler library.