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