Skip to main content

Operator Role

The Operator is a first-class party on every IRSForge deployment, distinct from the trader counterparties. It models the platform operator — the entity running the IRSForge service that two trading firms have both onboarded with.

In TradFi terms, this is the role a clearing venue, a tri-party agent, or a DLT platform operator plays: a third party that doesn't take economic risk on the trade but mediates issuance, lifecycle, and reference data on behalf of the bilateral counterparties.

If you're looking for the operator UI reference (queue, disputes, health), see ui/operator. This page covers why the operator exists and what authority it carries on-chain.

Why a third party at all

Two firms can do bilateral Daml between themselves with no operator involved. IRSForge needs an operator because:

  1. Daml Finance factories require operator authority. The Factory.Create choice that mints an Instrument is signed by a provider party — not by the two trade counterparties. Without a stable third-party signer, every trade would need its own ad-hoc factory deployment.
  2. Reference data is platform-wide. Currencies, rate indices (SOFR, ESTR, …), holiday calendars, oracle observations, and curve snapshots are shared across every counterparty pair. A single operator-owned authority publishes them and every trader observes.
  3. Compliance gating wants a non-trader actor. Optional manual co-sign on trade acceptance (Stage 2) requires an authority that's structurally separate from both economic counterparties.
  4. Regulator hand-off has a defined source. The operator includes configured regulator parties as observers on every contract it provisions, so audit visibility flows from one place.

The org.role: operator field is required and schema-enforced as exactly one per deployment (shared-config/src/schema-orgs.ts). Regulator orgs are also role-declared; the schema requires at least one and supports more than one.

On-chain footprint

The operator appears on-chain as either a signatory (its authority is required for the contract to exist) or an observer (it can read the contract). The shape:

ContractOperator roleWhy
Setup.RoleSetupsignatoryBootstrap marker — proves the deployment was provisioned
IRS / CDS / CCY / FX / Asset / FpML Factorysignatory (provider)Required by Daml Finance for Factory.Create
LifecycleRule, EventFactorysignatoryAuthority chain for Lifecycle.Evolve
HolidayCalendar, Currency, FloatingRateIndexsignatoryShared reference data
Observation, Curve, CurveSnapshotsignatory (or co-signed with scheduler)Oracle authority — see Canton Oracle Model
<Family>Proposal (IRS, OIS, Basis, Xccy, CDS, Ccy, Fx, Asset, FpML)signatory with proposerPre-co-signs so Accept body inherits factory auth
<Family>AcceptAcksignatory with proposer + counterpartyManual-policy co-sign holding pen
Csasignatory with partyA + partyBOperator co-owns the bilateral CSA (Bloomberg MARS convention)
CsaProposalsignatory with proposerSame proposal pattern as swaps
MarginCallOutstanding, MarkDisputedobserverOperator monitors and adjudicates disputes
SwapWorkflow (the live trade)observerOnce minted, the bilateral trade has signatory partyA, partyB only
Cash holdingsnot presentOperator never holds positions

The headline: operator authority is everywhere at provision-time, but the operator is not on the bilateral instrument body once the trade is live. It mints the trade and gates its lifecycle, but doesn't own the trade.

What the operator does

1. Co-sign trade proposals

Every <Family>Proposal template declares signatory proposer, operator. Creating a proposal therefore requires submitMulti [proposer, operator] [] — the operator's authority is consumed inline so that the eventual <Family>Accept choice has enough authority to invoke Factory.Create.

template CcySwapProposal
with operator : Party; proposer : Party; counterparty : Party; ...
where
signatory proposer, operator
observer counterparty

2. Optionally gate acceptance (auto vs manual)

operator.policy.<FAMILY>: auto | manual in irsforge.yaml selects the acceptance flow:

  • auto — counterparty exercises <Family>Accept directly. The operator's standing co-signature on the proposal carries through; the live SwapWorkflow lands in one transaction. Operator queue stays empty.
  • manual — counterparty exercises <Family>ProposeAccept → creates <Family>AcceptAck → operator reviews on /org/<id>/operator → exercises <Family>ConfirmAcceptSwapWorkflow lands. Either side can cancel before the operator acts.

This is a compliance choice, not a technical one. Same on-chain end state; the manual path inserts a human review gate. See Operator UI — compliance policy for the per-family configuration.

3. Resolve CSA disputes

The operator is signatory on every Csa contract alongside the two traders. When a counterparty exercises MarkDispute, the CSA enters MarkDisputed and is pinned out of the margin-call cycle until the operator exercises AcknowledgeDispute. See CSA Model — lifecycle states.

4. Maintain platform reference data

Currencies, rate indices, holiday calendars, oracle observations, curve snapshots — all submit operator (or co-signed with the scheduler service account, see Scheduler Authority). Traders observe; only the operator can publish.

5. Run scheduler-fallback lifecycle

When the autonomous scheduler is stalled, the operator can manually drive TriggerLifecycle on CCY / FX / FpML swaps via the operator UI. The dual LifecycleRule accepts either signer — operator authority works as a break-glass without redeploying anything.

What the operator structurally cannot do

CannotReason
Be partyA or partyB on a swapSwapWorkflow declares signatory partyA, partyB — operator isn't in that set
Propose a tradeProposal controllers are trader parties; operator UI hides the "New Swap" button (ui/operator.md:108)
Accept / Reject / Withdraw a tradeChoice controllers are trader parties
Unwind a live swapterminateProposal controller is trader-side
Hold cash or instrumentsOperator never appears as owner on Daml Finance holdings
Unilaterally cancel a live SwapWorkflowWorkflow body has only the two traders as signatories

The full bidirectional gating audit is in ui/operator — what the operator can't do.

Demo vs production

Same on-chain shape, different participant topology and trust model.

DemoProduction
Hosted onThe single Canton sandbox alongside every other partyThe platform-operator's own Canton participant node, under separate org
Authauth.provider: demo — party-selector mints a JWT for Operator on clickauth.provider: oidc — the IdP proves operator identity; IRSForge auth service mints the operator-scoped Canton ledger JWT
Operator service credentialBrowser-minted, ephemeralmark-publisher service-account secret in a secrets manager; auth service exchanges it for short-lived ledger JWTs
operator.policy.<FAMILY>All 9 families on auto (zero-friction demo)Mixed auto / manual per compliance regime; manual queue is staffed and paged
Compliance reviewerWhoever is clicking the demoA human at the platform operator (with PagerDuty / Slack hook on new queue items — roadmap)
Trust modelOperator is just another persona on a single ledgerOperator is the platform's commitment to the two firms — they trust the platform-operator the way they'd trust a CCP or tri-party agent

In demo the operator looks invisible because everything is on one sandbox and auto policy short-circuits the queue. In production the operator is what makes a bilateral trade a platform trade rather than two firms doing arbitrary Daml on their own ledgers — same code, different operating model.

For the production cutover checklist (OIDC wiring, secrets, manual buttons off) see Deploying to Production.

Mental model

┌────────────────────┐
│ Operator │ ← platform authority
│ (provision + │ (factory provider, lifecycle,
│ gate + publish) │ reference data, dispute resolver)
└─────────┬──────────┘
│ co-signs
┌─────────┴──────────┐
▼ ▼
┌──────────┐ ┌──────────┐
│ PartyA │ ◀────▶ │ PartyB │ ← the live bilateral trade
└──────────┘ └──────────┘ (signatory partyA, partyB)
▲ ▲
└────────┬───────────┘
│ observes
┌────────▼─────────┐
│ Regulator │ ← read-only audit
└──────────────────┘

PartyA ↔ PartyB own the economic relationship. The operator sits above them as the platform / factory / oracle authority. The regulator sits below with read-only audit visibility. None of these can swap roles — cardinality and signatory shape enforce it on-chain.