Skip to content

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.

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:

The evidence-release policyIllustrative data

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.

  1. Manufacturer proposes manufacturer-a proposes the release. Its role manufacturer is a proposer role, so the proposal opens PENDING. Proposing does not count as approving.
    Proposal: PENDING
    ClauseNeedsAccepted decisions
    auditors2 auditor, distinct organizationsnone
    regulator1 regulatornone
  2. Wrong role manufacturer-a also tries to approve in the auditors clause. It does not hold the auditor role.
    • 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
    ClauseNeedsAccepted decisions
    auditors2 auditor, distinct organizationsnone
    regulator1 regulatornone
  3. Wrong payload auditor-a1 signs 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
    ClauseNeedsAccepted decisions
    auditors2 auditor, distinct organizationsnone
    regulator1 regulatornone
  4. First auditor auditor-a1 from audit-org-a signs 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
    ClauseNeedsAccepted decisions
    auditors2 auditor, distinct organizationsauditor-a1 (audit-org-a)
    regulator1 regulatornone
  5. Same organization auditor-a2 also works for audit-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
    ClauseNeedsAccepted decisions
    auditors2 auditor, distinct organizationsauditor-a1 (audit-org-a)
    regulator1 regulatornone
  6. Second auditor auditor-b from audit-org-b approves. The auditors clause is satisfied, but the regulator clause 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
    ClauseNeedsAccepted decisions
    auditors2 auditor, distinct organizationsauditor-a1 (audit-org-a), auditor-b (audit-org-b)
    regulator1 regulatornone
  7. Regulator approves regulator-a approves in the regulator clause. 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
    ClauseNeedsAccepted 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.

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:

Terminal window
cd examples/evidence
./demo.sh up \
--instance tutorial-roles \
--machine role \
--continuation direct

up 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.

Terminal window
./demo.sh publish \
--instance tutorial-roles \
--machine role \
--continuation direct \
--evidence-id regulated-product-001 \
--sample-file samples/inspection-certificate.json

The 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 an APPROVED authorization with three decisions: auditor-a1 from audit-org-a, auditor-b from audit-org-b, and regulator-a.

Terminal window
./demo.sh verify \
--instance tutorial-roles \
--machine role \
--continuation direct \
--evidence-id regulated-product-001

Open 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”.

Terminal window
./demo.sh role-lifecycle \
--instance tutorial-roles \
--machine role \
--continuation direct

The exercise uses a dedicated recovery actor and checks, in order:

  1. governed onboarding with proof-of-possession;
  2. signing-key rotation;
  3. the old actor revision and key are refused;
  4. the new revision and key are accepted;
  5. revocation;
  6. refusal after revocation; and
  7. 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 a FAIL line 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.

Terminal window
./demo.sh stop \
--instance tutorial-roles \
--machine role \
--continuation direct

stop keeps the instance’s data and secrets.

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.

  • 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.
  • 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.