Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 56 additions & 4 deletions src/packages.md
Original file line number Diff line number Diff line change
@@ -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:

Expand All @@ -15,7 +15,7 @@ license = "Apache-2.0"
authors = ["John Doe <john@example.com>"]
```

> **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

Expand Down Expand Up @@ -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:

Expand Down Expand Up @@ -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.