From demonstration to production
Every product in this repository ships with a launcher, demo actors, and a local console, and every one of those is a demonstration convenience. This guide says what changes when a consortium runs one of these app ledgers for real: how the genesis is agreed, where keys live, what each service is allowed to reach, and which parts are still gated.
Yano is pre-release. Nothing here makes a preview or EXPERIMENTAL product production-ready on
its own; read each product’s status first. The DPP starter is a prototype and the attestation feed
is experimental, and both have gated stages listed at the end.
The short version
Section titled “The short version”| Demo | Production |
|---|---|
| Seeds derived from a public string | Keys generated by each actor, on their own machine, never transmitted |
| One gateway holding every seed | One signer per organization, holding only its own key, or a browser-held key |
| A fixed local API key | A per-caller key, rotated, never in a shell history or a repository |
| Loopback HTTP, no TLS | TLS on every reachable endpoint, with a reverse proxy in front |
| Members and threshold chosen by a script | Members agreed by the consortium, threshold a governance decision |
| Anchoring to a self-contained devnet | Anchoring to preprod or mainnet from a funded, protected key |
| One operator playing every role | Each organization operating its own node and signer |
1. Agree the genesis
Section titled “1. Agree the genesis”The genesis fixes the collections, the schemas, the roles, the policies, and the actors with their public keys. Its hash is the genesis id, and every authorization is signed against it, so agreeing it is the first governance act and changing it later means a different ledger.
Each actor generates its own key. On the actor’s own machine, never on the operator’s:
yano-trust actor-key --chain <chain-id> --actor <actor-id> --seed-file <seed>The command prints publicKeyHex and keyProofHex. Those two values travel to the operator. The
seed does not: it stays in a file readable only by its owner, or in a key store or HSM the
organization already trusts. The same command exists for the DPP and feed products.
The operator assembles the descriptor from the organizations, actors, public keys, key proofs, and policies the consortium agreed, then generates the node properties:
yano-trust genesis --descriptor registry.json --members <key,key,key> --threshold 2 \ --chain-index N --output registry.propertiesEvery participant regenerates it independently and compares the genesis id. The generator is deterministic: the same descriptor, members, and threshold always give the same id. A participant who cannot reproduce the id should not join the ledger. Publish the id where members can check it.
Note what cannot be changed afterwards without a new ledger: the collections, their policies, the actors declared at genesis, the block interval, and the message size bounds. Adding an actor later is a governance action on the role workflow, and the product CLIs do not expose it today.
2. Members, threshold, and nodes
Section titled “2. Members, threshold, and nodes”The member set is the list of node keys whose signatures certify a block, and the threshold is how many must sign. Both are consortium decisions, not defaults, and every verifier must pin the same set.
Size the threshold against two separate risks. Up to n − t members can be offline while the ledger
keeps finalizing blocks. Dishonest members are a separate assumption: the fault bound f, set as
consensus.max-byzantine-members, is 0 by default, and the node refuses to start unless
2t − n > f and t ≤ n − f. A threshold of two of three therefore tolerates one member being down,
but not one dishonest member: it cannot be configured with f = 1. Tolerating one dishonest member
takes, for example, four members with a threshold of three and f = 1.
Each organization runs its own node, with its own storage, and its own signing key. Do not run a “cluster” of nodes owned by one operator and call it a consortium: the threshold then proves only that one operator signed several times. The showcase launcher does exactly that, which is why it is a demonstration.
Node configuration is the product’s chain entry plus the four generated properties, applied to every node. The block interval and message size in the generated properties are part of the genesis identity: a node started with different values will not agree.
Give each node its own data directory, back up its authoritative stores, chainstate/ and
appchain-chainstate/ (see where data lives), and decide a
retention policy for proofs and history before you need one. Historical answers need proof retention: a verifier asking
about height H needs the node to still hold it.
3. Keys and signing
Section titled “3. Keys and signing”This is where a demonstration differs most from a deployment.
Do not run a shared gateway in production. A gateway signs for every actor whose seed it was started with, so whoever holds its token can write as any of them. In a demo that is the point; in a deployment it collapses the distinction the ledger is there to make. Each organization should either run a gateway holding only its own actors’ keys, on its own machine, reachable only by its own operators, or use a browser-held key so nothing but the tab ever has it.
Browser-held keys are implemented for the trust registry console today. The seed is imported through WebCrypto, held in a closure, zeroed immediately, never stored, and released when the tab closes. It is the honest default for a person acting for themselves. Hardware and wallet-held keys are not implemented yet.
API keys authenticate callers to the node, and are not identities. Issue one per caller, keep
them out of shell history and repositories, and rotate them. yano-trust, yano-dpp, yano-feed,
and yano-explorer accept --api-key-file; yano-attest and yano-cardano-history accept only
--api-key. The services read the node key on their side so a console never holds it.
Authorization lifetimes are bounded in blocks and one-use. A signer that is offline long enough for its authorization to expire simply retries; do not raise the lifetime to avoid that.
4. Network and services
Section titled “4. Network and services”Everything binds to loopback by default. That default is correct, and exposing a service is a deliberate act:
| Service | Exposure | Notes |
|---|---|---|
| Node REST API | private to the operators and services that need it | never public; put TLS and a reverse proxy in front |
| Product portal (DPP, feed) | public, read only | serves proofs and views; no secret, no write route |
| Registry read service | public, read only | serves status lists and TRQP answers |
| Operator gateway | private to one organization’s operators | holds keys; never public, and never without TLS if it leaves the host |
| Explorer service | as private as the ledger data it indexes | holds the node API key on its side |
| Consoles | static files | can be public; they hold no secret beyond what the operator types |
A console served over HTTPS cannot call a service over plain HTTP. Either serve both over HTTPS, or host the console behind the same reverse proxy as the service so they share an origin, which is what the demo does with a local proxy.
5. Anchoring to Cardano
Section titled “5. Anchoring to Cardano”The demo anchors to a devnet the cluster runs itself. In production, anchoring is what turns “the consortium says so” into “a public chain carries it”.
- Choose the network deliberately, and confirm public anchoring explicitly. Preprod for testing; mainnet only when the operator accepts the cost and the permanence.
- Anchoring needs a funded wallet key. Keep it in a file the launcher reads, owner-only, outside the data directory, and treat it as a production secret. Never pass a seed on a command line.
- Only some ledgers need anchoring. Anchor the ones whose evidence must be independently checkable later, and leave the rest.
- Verifiers reach the top trust level by reading the anchor datum from a Cardano source they trust
and passing it to
verify --anchor-datum-hex. Plan how your verifiers get that datum: a public resolver, a block explorer, or their own node. - Nothing public should carry personal data. On-chain metadata and datums are permanent.
6. What the demo does that production must not
Section titled “6. What the demo does that production must not”- Derive seeds from a public string. Every demo actor’s key is computable by anyone.
- Use the known local API key, or leave one in an environment printed by a launcher.
- Run one gateway holding every organization’s key.
- Run all members from one operator, one host, and one directory.
- Bind services to a public interface without TLS.
- Treat a
previeworEXPERIMENTALproduct as a supported one.
7. Per-product notes
Section titled “7. Per-product notes”- Attest needs a ledger running the stock
doc-trailstate machine and nothing else. Its certificate is portable and verifies offline; distribute the members file through a channel your verifiers trust, never alongside the certificate alone. - Trust and Status Registry publishes status lists that verifiers fetch by URL. Publish again after later status writes, or a served list will not match the ledger. Onboarding an issuer after genesis goes through the approval route and has no CLI yet.
- Verifiable Explorer is a convenience index. It never adds trust: every row keeps its evidence and can be verified against the node. Give it read access only.
- DPP Starter is a prototype. Any manufacturer can rewrite any product, and the ledger exposes that as a flag rather than preventing it. The full provider that enforces the rules on the ledger waits on qualification of the governed map and acceptance of the DPP design.
- Data Attestation Feed is experimental. Aggregates are recomputed by verifiers, nothing is published to Cardano, and the hardened publication executor and the reviewed aggregation component are core work that has not landed.
8. Before you go live
Section titled “8. Before you go live”- The genesis id is reproduced independently by every member.
- Each organization holds its own signing key, and no key is on a machine that did not generate it.
- The member set and threshold are recorded where verifiers can obtain them.
- TLS terminates in front of every reachable endpoint, and the node API is not among them.
- Anchoring, if used, has a funded key that is backed up and access-controlled.
- Retention is decided, backups are tested, and a member can be restored.
- Every verifier knows which trust level they require, and treats only exit 0 and 5 as verified.
- The product’s classification and its deferred stages are written down where the operator’s stakeholders can read them.