Feature Specification: Deployment of the api Service
Created: 2026-09-23
Status: Implemented
Input: Reconstructed from the code of api/ at 0bf4ecd36, api/README.md, pull requests #1184, #1249, #1901 and #1903, and the design notes of the maintainers.
User Scenarios & Testing (mandatory)
User Story 1 - Run api on a NixOS host (Priority: P1)
A provider runs api with its NixOS module. The module makes each service that api depends on a setting: the state store, the job runner, the events service, the allowed origins, the authorization callback and the service token. Optionally, the module also runs the events server and its virtual host. Secrets come from files at run time.
Why this priority: this is how a provider runs api.
Independent Test: a NixOS VM test starts the service and calls its procedures.
Acceptance Scenarios:
- Given the module with a database, When the host starts, Then
apikeeps its state in PostgreSQL. - Given a service token file, When the host starts, Then
apireads the token at run time, and the token is not in the Nix store.
User Story 2 - Develop api locally (Priority: P1)
A developer runs api from the development shell of api/. The shell has the tools, a local state backend, a job runner and an events server for the full setup.
Independent Test: a developer starts the local stack from the development shell.
Acceptance Scenarios:
- Given the development shell, When the developer starts the simple setup, Then
apiruns builds as local subprocesses, without a job runner.
User Story 3 - Publish the wire contract (Priority: P2)
api publishes its OpenAPI 3.1 and AsyncAPI 3.0 documents and their documentation sites, made from the models in the code.
Independent Test: validation checks of the two documents.
Acceptance Scenarios:
- Given a change of a model, When the documents are built, Then they show the change, and the validation passes.
- Given a node that runs the events server on a public name, When the node serves its AsyncAPI documentation site, Then the site names that events server. The documents that
api/builds without a deployment keep a placeholder for the name.
User Story 4 - Deploy api with a group of machines (Priority: P3)
api/ adds its component to a group of core, and gives deploy attributes that provision the machines with api. When the front-end gives an events domain, the component also runs the events server on that domain, with a generated key and a certificate from the SSL resource.
Independent Test: a VM test of a full deployment.
Edge Cases
- A flake build of
api/cannot pin the whole repository:apithen takes the default source from the self-pin.
Requirements (mandatory)
Functional Requirements
- FR-001: The plain Nix entry point of
api/MUST be the single source of all outputs. The flake MUST only add the system layer. - FR-002: The NixOS module MUST make each dependency on a service of the provider (database, job runner, events, callback, service token) a setting.
- FR-003: The module MUST read secrets from files at run time.
- FR-004:
apiMUST publish OpenAPI and AsyncAPI documents that validate. - FR-005: The development shell MUST contain the tools to run
apilocally.
Key Entities
- NixOS module: the service definition of
apifor a NixOS host. - Component: the registration of
apiin a group ofcore.
Success Criteria (mandatory)
Measurable Outcomes
- SC-001: The format check, the NixOS VM test and the validation of the two documents pass.
- SC-002: A provider can run
apiwith the NixOS module and its own services, without the component of the fediversity provider.
Assumptions
- The component under
api/is the wiring for the fediversity hosting provider. It moves to the tree of the provider at the repository root, so thatapi/gives only the service and its NixOS module.
Known Deviations
- The component of
apiadds it to thehosting-providergroup ofcore, withspire, NetBox IPAM, the Openprovider registrar,openbaoand its ownpostgresqlresource, and uses the deploy credentials, the operator curation and the contract modules of the provider. This is the business case of one provider insideapi(principle IV). The service itself only reads a generic database URL, so it is agnostic (#1940).