The EULA gate
Included from Basic tier
Every OpsChain binary embeds the LimePoint End User Licence Agreement
(the faithful single-column rendition of the
canonical copy published at https://opschain.io/eula/). A fresh
installation must accept it once before opschain server start will
compose anything user-visible — the gate runs before even the identity
bootstrap writes its first row. The opschain agent dev ephemeral sandbox
is exempt, like its licence gate.
Read the agreement with opschain eula; opschain eula --sha prints the
embedded text's sha256: digest, its Updated date and the canonical URL
— useful for recording exactly which revision an installation accepted
(see opschain docs cli/eula).
Accepting
On a fresh installation (no acceptance record in the store), the gate accepts through the first of these that applies, in order:
- Explicit confirmation —
opschain server start --confirm-eula, or its config twineula.accepted: trueinconfig.yaml(deploy-authoritative; seeopschain docs config). Either is inert once the acceptance is recorded. - Grandfathering — a store that predates the gate (any
usersrow on PostgreSQL, anyrunsrow on SQLite) means an existing installation, which is admitted rather than bricked; the record is written with methodgrandfathered. - The interactive prompt — when stdin is a terminal, the agreement is
displayed and the operator types
accept.
The acceptance record
Acceptance is recorded durably in the installation's store (the
eula_acceptances table, on either scheduler database — PostgreSQL,
HA-wide, or SQLite). The record is append-only; no API can delete it. It
captures:
| Field | Meaning |
|---|---|
sha256 | The accepted text's hex digest, so a later revision is detectable. |
version | The agreement's own date line (currently 3 April 2024) — captured automatically, operators never handle it. |
accepted_at | When (UTC). |
acceptor | Who: the OS identity of the first boot, as <username>@<hostname>. |
method | How: interactive, flag, config or grandfathered. |
A concurrent replica's identical insert is a no-op: the first writer wins
and both boots proceed. When this boot created the record, the start log
notes it and the api:eula:accepted event is emitted (carrying sha256,
version, acceptor and method).
When unaccepted
A fresh headless installation — no acceptance record, no
--confirm-eula, no eula.accepted config, no terminal to ask on (or the
operator declined at the prompt) — is refused with:
the LimePoint End User Licence Agreement has not been accepted on this installation — read it with
opschain eula(canonical copy: https://opschain.io/eula/), then accept it one of three ways: runopschain server startfrom an interactive terminal and type 'accept' at the prompt; start once withopschain server start --confirm-eula; or seteula: {accepted: true}in config.yaml
The server does not start; nothing is served.
A later revision never re-gates
Once an installation holds an acceptance record, it always boots — the
agreement's own continued-use clause governs. When the embedded text's
sha differs from the recorded acceptance, the boot proceeds loudly: a
start-log notice, plus a warn:eula:updated event emitted once per
revision (throttled durably against the events table, keyed on the new
revision's sha, so a restart never re-emits it). The event names both
texts (sha256/version of the build, accepted_sha256/
accepted_version of the record) and points at opschain eula and the
canonical URL.
Related pages
opschain docs cli/eula— read or digest the embedded agreement.opschain docs cli/server-start— the--confirm-eulaflag.opschain docs config— theeula.acceptedkey.