package conex

  1. Overview
  2. Docs

Module Conex_repository

Repository state and validation logic

The repository keeps track of valid resources, which are added after successful verification of an author. The only configuration element is the quorum: how many janitors have to sign off a change.

The only resource which is signed with an asymmetric cryptographic operation is the author, which contains a list of resources the author vouches for. To validate a resource, first the authorised authors have to be validated. Once they are approved, resource validation is a lookup of a computed hash in a map which is part of the repository.

This module contains the program logic to validate the different resources, which have different rules:

  • validate_author requires a self-signature with a validated key OR has an empty list of resources and approved by a quorum of janitors
  • validate_account is successful if the account is in the authors resource list, and approved by a quorum of janitors
  • validate_key is successful if the key is in the authors resource list, and approved by a quorum of janitors
  • validate_team is successful if approved by a quorum of janitors
  • validate_authorisation is successful if approved by a quorum of janitors
  • validate_package is successful if approved by an authorised author OR a quorum of janitors
  • validate_release is successful if approved by an authorised author OR a quorum of janitors

Monotonicity requirements are as follows:

  • monoton_author requires the counter to increase, deletion is not supported (they can have an empty resource list and no public key).
  • monoton_team requires the counter to increase, deletion is not supported (a team may have no members)
  • monoton_authorisation requires the counter to increase, deletion is not supported
  • monoton_package requires the counter to increase, deletion is not supported (the list of releases can be empty)
  • monoton_release requires the counter to increase

Repository type, constructor, predicates

type t

The repository type

val repository : ?quorum:int -> (Conex_resource.Wire.t -> Conex_resource.Digest.t) -> unit -> t

repository ~quorum ~strict digest () is a fresh empty repository.

val quorum : t -> int

quorum repo is the configured quorum.

val find_team : t -> Conex_resource.identifier -> Conex_utils.S.t option

find_team repo id returns the members of the team id or None if there is no such team.

val id_loaded : t -> Conex_resource.identifier -> bool

id_loaded repo id is true if id has been loaded.

authorised repo auth id is true if id is a member of auth or member of a team which is authorised.

val contains : ?queued:bool -> t -> Conex_resource.Author.t -> Conex_resource.name -> Conex_resource.typ -> Conex_resource.Wire.t -> bool

contains ~queued author name typ data is true if data named name of typ is a member in the list of resources of author. If queued is true, membership of the resource in the queued list of resources is sufficient.

Validation

type conflict = [
  1. | `NameConflict of Conex_resource.name * Conex_resource.Author.r
  2. | `TypConflict of Conex_resource.typ * Conex_resource.Author.r
]

The variant of a conflict in the digest map.

val pp_conflict : conflict Conex_utils.fmt

pp_conflict is a pretty printer for conflict.

pp_ok pretty prints validation success

Errors which can occur during any validation.

pp_error prints validation errors.

val validate_author : t -> Conex_resource.Author.t -> (t, [> base_error | conflict | `InsufficientQuorum of Conex_resource.name * Conex_resource.typ * Conex_utils.S.t * int | `AuthorWithoutKeys of Conex_resource.identifier ]) result

validate_author repo author validates author: at least one public key must be approved by a quorum of janitors or the resource list is empty and it is approved by a quorum of janitors. The valid resource list is added to the repository (using add_index).

validate_account repo author account validates account of author: a quorum of janitors have to approve an account.

validate_key repo id key validates key of id: a quorum of janitors have to approve a key.

val validate_team : t -> Conex_resource.Team.t -> (t * [ `Quorum of Conex_utils.S.t ], [> base_error | `InsufficientQuorum of Conex_resource.name * Conex_resource.typ * Conex_utils.S.t * int | `MemberNotPresent of Conex_resource.identifier * Conex_utils.S.t ]) result

validate_team repo team validates team: a quorum of janitors have to approve a team, and all team members must be in the repository. If valid, the team is added to repo (using add_team).

val validate_authorisation : t -> Conex_resource.Authorisation.t -> ([ `Quorum of Conex_utils.S.t ], [> base_error | `InsufficientQuorum of Conex_resource.name * Conex_resource.typ * Conex_utils.S.t * int | `IdNotPresent of Conex_resource.name * Conex_utils.S.t ]) result

validate_authorisation repo auth validates auth: a quorum of janitors have to approve an authorisation, and all authorised ids have to be present in repo.

validate_package repo ~on_disk auth package validates package: an authorised identity must approve the package in repo, all releases must be prefixed with the package name, and if on_disk is given, the list of releases have to be identical.

validate_release repo ~on_disk auth package release validates release: an authorised (using auth) identity must approve the release in repo, it must be part of the releases of package, and if on_disk is given, the files listed must be equal, as well as their checksums.

Monotonicity

type m_err = [
  1. | `NotIncreased of Conex_resource.typ * Conex_resource.name
  2. | `Deleted of Conex_resource.typ * Conex_resource.name
  3. | `Msg of Conex_resource.typ * string
]

The variant of monotonicity errors.

val pp_m_err : m_err Conex_utils.fmt

pp_m_err is a pretty printer for m_err.

val monoton_author : ?old:Conex_resource.Author.t -> ?now:Conex_resource.Author.t -> t -> (unit, m_err) result

monoton_author ~old ~now repo checks that the counter increased.

val monoton_team : ?old:Conex_resource.Team.t -> ?now:Conex_resource.Team.t -> t -> (unit, m_err) result

monoton_team ~old ~now repo checks that the counter increased.

val monoton_authorisation : ?old:Conex_resource.Authorisation.t -> ?now:Conex_resource.Authorisation.t -> t -> (unit, m_err) result

monoton_authorisation ~old ~now repo checks that the counter increased.

val monoton_package : ?old:Conex_resource.Package.t -> ?now:Conex_resource.Package.t -> t -> (unit, m_err) result

monoton_package ~old ~now repo checks that the counter increased.

val monoton_release : ?old:Conex_resource.Release.t -> ?now:Conex_resource.Release.t -> t -> (unit, m_err) result

monoton_release ~old ~now repo checks that the counter increased.

Unsafe operations

These operations extend which resources are trusted. Usually you should not need them, but use validate_author and validate_team instead.

add_valid_resource id repo r marks resource r valid under id in repo. If the digest of r is already present for a different resource, an error will be returned.

val add_index : t -> Conex_resource.Author.t -> (t, conflict) result

add_index repo author applies add_valid_resource to each member of the resource list from author.

val add_team : t -> Conex_resource.Team.t -> t

add_team repo team adds the team to the repo.

val add_id : t -> Conex_resource.identifier -> t

add_id repo id adds the id to the repo.

OCaml

Innovation. Community. Security.