Tutorial 5 — Generic Domain Actors and Role-Aware Approval
Open generic role approval in App-Chain Studio
- Level: application developer; advanced for identity governance
- Time: about 30 minutes, plus the first image build
- Outcome: run a release that business actors from different organizations approve under a governed policy, confirm that deliberate mistakes are final but count for nothing, and rotate and revoke an actor key.
Role-aware approval separates two identities:
- member identity: which member node relayed an envelope; and
- actor identity: which business actor signed the exact statement inside it.
This tutorial runs the evidence demo’s role-evidence profile, which builds on
the same actor registry and approval rules as the generic
role-approvals machine.
How the policy decides
Section titled “How the policy decides”The demo’s policy, evidence-release, needs a manufacturer to propose, two
auditor actors from distinct organizations, and one regulator. The demo
sends these statements for one release, in this order:
What you're seeing: the statements the demo submits for one release, in order. A manufacturer proposes; two auditors from different organizations and one regulator must approve. Three statements are deliberate mistakes: each is final but changes nothing.
- Manufacturer proposes
manufacturer-aproposes the release. Its rolemanufactureris a proposer role, so the proposal opens PENDING. Proposing does not count as approving.Proposal: PENDING Clause Needs Accepted decisions auditors2 auditor, distinct organizationsnone regulator1 regulatornone - Wrong role
manufacturer-aalso tries to approve in theauditorsclause. It does not hold theauditorrole.- passes: The proposal exists and is PENDING
- passes: Policy, payload and deadline match the proposal
- passes: This actor has not decided on it yet
- fails: The actor has the clause’s role
ROLE_MISMATCH - not reached: No accepted decision in this clause from the same organization
Proposal: PENDING Clause Needs Accepted decisions auditors2 auditor, distinct organizationsnone regulator1 regulatornone - Wrong payload
auditor-a1signs an approval over a hash with one bit flipped. It does not match the proposal’s hash.- passes: The proposal exists and is PENDING
- fails: Policy, payload and deadline match the proposal
CONFLICT - not reached: This actor has not decided on it yet
- not reached: The actor has the clause’s role
- not reached: No accepted decision in this clause from the same organization
Proposal: PENDING Clause Needs Accepted decisions auditors2 auditor, distinct organizationsnone regulator1 regulatornone - First auditor
auditor-a1fromaudit-org-asigns the correct hash. The decision is accepted.- passes: The proposal exists and is PENDING
- passes: Policy, payload and deadline match the proposal
- passes: This actor has not decided on it yet
- passes: The actor has the clause’s role
- passes: No accepted decision in this clause from the same organization
Proposal: PENDING Clause Needs Accepted decisions auditors2 auditor, distinct organizationsauditor-a1(audit-org-a)regulator1 regulatornone - Same organization
auditor-a2also works foraudit-org-a. The clause counts organizations, not people, so this approval does not count.- passes: The proposal exists and is PENDING
- passes: Policy, payload and deadline match the proposal
- passes: This actor has not decided on it yet
- passes: The actor has the clause’s role
- fails: No accepted decision in this clause from the same organization
DISTINCTNESS_DUPLICATE
Proposal: PENDING Clause Needs Accepted decisions auditors2 auditor, distinct organizationsauditor-a1(audit-org-a)regulator1 regulatornone - Second auditor
auditor-bfromaudit-org-bapproves. Theauditorsclause is satisfied, but theregulatorclause is not, so the proposal stays PENDING.- passes: The proposal exists and is PENDING
- passes: Policy, payload and deadline match the proposal
- passes: This actor has not decided on it yet
- passes: The actor has the clause’s role
- passes: No accepted decision in this clause from the same organization
Proposal: PENDING Clause Needs Accepted decisions auditors2 auditor, distinct organizationsauditor-a1(audit-org-a),auditor-b(audit-org-b)regulator1 regulatornone - Regulator approves
regulator-aapproves in theregulatorclause. Every clause is satisfied, so the proposal becomes APPROVED with exactly three accepted decisions, the ones the demo then verifies.- passes: The proposal exists and is PENDING
- passes: Policy, payload and deadline match the proposal
- passes: This actor has not decided on it yet
- passes: The actor has the clause’s role
- passes: No accepted decision in this clause from the same organization
Proposal: APPROVED Clause Needs Accepted decisions auditors2 auditor, distinct organizationsauditor-a1(audit-org-a),auditor-b(audit-org-b)regulator1 regulatorregulator-a
- business actor
- deterministic state machine
- approved
- no-op
The three mistakes are final, like every other message, but they change nothing. Only eligible, signed decisions count toward the policy.
The codes above are the decisions the machine makes, but it does not store a
code for each command, so the demo cannot print them. You see their result
instead: the approved proposal keeps only the three accepted decisions, and
publish fails unless they are exactly auditor-a1, auditor-b and
regulator-a. The role-approvals reference
lists every code and the order of the checks.
1. Start the role profile
Section titled “1. Start the role profile”You need JDK 25, Docker with Compose v2, curl, jq, openssl and Python 3.
The stack uses the same ports as Tutorial 4: 7070–7072 for the members, 7080
for the Explorer, and 9092, 9000 and 5001. If any is busy, export the same
DEMO_HTTP_BASE or other DEMO_*_PORT overrides that
Tutorial 4 describes before the first command,
and keep them set for the whole tutorial.
From the top-level directory of the extracted release:
cd examples/evidence
./demo.sh up \ --instance tutorial-roles \ --machine role \ --continuation directup prepares the instance first: it generates its secrets and builds the Yano
and runner images, which takes a while the first time. ./demo.sh prepare runs
only that preparation, if you want to do it ahead of time. Then up starts
three members and the publication services, funds and bootstraps a devnet
anchor, and runs a read-only readiness probe.
The profile commits its organization and actor registry, policy, component
order, routes, effect workflow, administrator threshold and limits at genesis.
It is not a setting you can switch on for an existing chain. Pass the same
--machine role --continuation direct to every command for this instance.
2. Publish actor-authorized evidence
Section titled “2. Publish actor-authorized evidence”./demo.sh publish \ --instance tutorial-roles \ --machine role \ --continuation direct \ --evidence-id regulated-product-001 \ --sample-file samples/inspection-certificate.jsonThe runner submits the statements shown above, including the three negative controls, then releases the evidence once the proposal is APPROVED.
✓ You should see
PASS command=publish scenario=regulated-product-001-.... The run’s report, which the Explorer in the next step shows, has anAPPROVEDauthorization with three decisions:auditor-a1fromaudit-org-a,auditor-bfromaudit-org-b, andregulator-a.
3. Inspect and verify
Section titled “3. Inspect and verify”./demo.sh verify \ --instance tutorial-roles \ --machine role \ --continuation direct \ --evidence-id regulated-product-001Open http://127.0.0.1:7080/. The report separates the relay member, actor, organization, role, policy revision, clause and signed decision. Current actor and policy projections include both the revision proof and the same-root current-pointer proof, so “this revision exists” is never confused with “this is the current revision”.
4. Rotate and revoke an actor
Section titled “4. Rotate and revoke an actor”./demo.sh role-lifecycle \ --instance tutorial-roles \ --machine role \ --continuation directThe exercise uses a dedicated recovery actor and checks, in order:
- governed onboarding with proof-of-possession;
- signing-key rotation;
- the old actor revision and key are refused;
- the new revision and key are accepted;
- revocation;
- refusal after revocation; and
- proofs of the historical revisions and decisions.
✓ You should see one line,
PASS command=role-lifecycle actor=recovery-probe revision=3 rotation=verified revocation=verified .... The command checks every step above against proven state and stops with aFAILline at the first one that does not hold; it does not print the steps one by one.
This is not member rotation. Business credentials and member nodes are governed separately.
5. Stop and retain
Section titled “5. Stop and retain”./demo.sh stop \ --instance tutorial-roles \ --machine role \ --continuation directstop keeps the instance’s data and secrets.
Use the generic machine
Section titled “Use the generic machine”The generic role-approvals machine
approves any payload hash and emits nothing. Its reference page shows how to
create a project with the role-approval recipe, sign statements with
./yano.sh appchain role sign, submit them on role-approvals.command.v1,
and query and prove the result. It also lists the lifecycle, the order of
checks and every outcome code.
Its organizations, actors and policies are created through member governance.
./yano.sh appchain role bootstrap encodes them from the project’s generated
bootstrap/role-approvals-plan.yaml; the reference page walks through the
bootstrap, from actor keys to a read-back of every record.
Reuse levels
Section titled “Reuse levels”- Configuration only. Use a stock profile when its action and terminal transition already match. Governed data defines actors, organizations, roles, policies, counts, organization distinctness, deadlines and connector targets.
- Small composite plugin. Use the existing registry, approval, evidence or payment components in a new order, or connect approval to a different terminal action. Order and cross-component transitions affect consensus, so they stay reviewed Java composition.
- Custom state-machine plugin. Only for new state or business rules.
Production boundaries
Section titled “Production boundaries”- The demo uses deterministic actor seeds held locally. Production signing belongs in a KMS, HSM, vault or an actor-owned signing service.
- Yano proves that registered keys authorized exact bytes under a governed policy. Legal identity and real-world truth remain onboarding and audit duties.
- An actor record keeps at most 16 key epochs. Plan a successor identity before you reach that limit.
- Administrator authority is part of the profile; changing it is governed profile evolution, not an ordinary actor change.
Go deeper
Section titled “Go deeper”- The
role-approvalsreference, with an interactive walkthrough of every outcome code. - The complete domain-role guide.
- The evidence demo README, for other profiles, ports and cleanup.