Contracts (RFC 189)
This page tells how the contracts of RFC 189 connect the software that needs
a service to the software that gives it. A contract is the interface
between a consumer module and a provider module of a service, for example
smtp, postgresql, ssl or oidc.
A contract is not a part of the Fediversity data model. The data model has resources, the interface between a component and a hosting provider. A resource usually uses one or more contracts to give what a request asks for. The configuration data flow page tells how a configuration becomes a deployment through the resources.
For example, Forgejo asks the smtp contract for outbound mail with a sender
address. The mail relay that provides the contract answers with a host, a port,
a user name and a password file:
A contract has these parts, under config.contracts.<type>:
want.<consumer>.<instance>.request-- what a consumer asks for.providers.<name>-- the providers that can answer the request.defaultProvider-- the provider that answers when the consumer selects none. A want that no provider answers fails the evaluation.providerRequests.<provider>-- the requests that a provider reads.results.<consumer>.<instance>-- what the consumer reads back, for example a host, a port and a password file.
Each contract type defines the shape of its request and its result. The consumer and the provider agree only on these shapes, so a hosting provider can replace a provider without a change to the consumer. The contract reference lists the request and the result of each contract type, with its providers and an example.
Contracts across nodes
Each node of a deployment is a separate NixOS evaluation, so the nodes do not
share config.contracts. When the consumer and the provider are on different
nodes, crossNodeContract and crossNodeWant in core/lib/lib.nix evaluate
the contract once, and give the result to each node. A contract that only gives
coordinates, such as the address of a DNS server, does not need this.
What a cross-node contract costs tells when to use one.
Where the code is
| Part | Location |
|---|---|
| The contracts machinery | nix/contracts/lib/contracts/module.nix |
| The contract types | nix/contracts/lib/contracts/definitions/ |
| The cross-node helpers | core/lib/lib.nix |
The contracts guide of the vendored contracts tree tells how to write a consumer, a provider and a new contract type.
Further reading
- RFC 189, the contracts RFC, and its implementation in Self Host Blocks.
- nixpkgs pull request 506343, which adds default providers, providers outside NixOS, contracts across nodes, and introspection to make a form.
- Talks on contracts: NixCon NA 2024 and NixCon 2024.