Production-ready workflow demonstrations from the Sorcha project
Multi-step approval workflows with cryptographic signing at each stage. Automated routing based on loan amount, applicant criteria, and risk assessment.
Financial institutions process loan applications through multiple stages:
Automated loan application workflow with:
var loanWorkflow = Blueprint.Create("LoanApplicationWorkflow")
// Receive loan application
.AddSource<LoanApplication>(config => config
.FromQueue("loan-applications")
.WithDeduplication())
// Validate application data
.Validate<LoanApplication>(validation => validation
.AgainstSchema("loan-application-schema-v1")
.CheckRequiredDocuments()
.ValidateApplicantInfo())
// Sign initial submission
.Sign(signature => signature
.WithAlgorithm(CryptoAlgorithm.ED25519)
.UsingKey("loan-processor-key")
.IncludeTimestamp())
// Credit check and risk assessment
.Transform<LoanApplication, AssessedLoan>(loan =>
loan
.PerformCreditCheck()
.CalculateRiskScore()
.DetermineEligibility())
// Dynamic routing based on loan amount using JSON Logic
.Route(routing => routing
.When(loan => loan.Amount < 10000)
.ToDestination("auto-approval-queue")
.When(loan => loan.Amount >= 10000 && loan.Amount < 50000)
.ToDestination("manager-approval-queue")
.When(loan => loan.Amount >= 50000)
.ToDestination("director-approval-queue")
.Otherwise()
.ToDestination("manual-review-queue"))
// Record in distributed ledger
.Audit(audit => audit
.CreateLedgerEntry()
.WithDIDReference()
.StoreInRegisterService()
.EnableODataQuery())
// Notify stakeholders via SignalR
.Publish(notification => notification
.ToApplicant("application-status-update")
.ToProcessor("new-application-assigned")
.ToCompliance("application-submitted"))
.Build();
Dynamic routing with JSON Logic evaluation based on expense amounts. Automatic escalation and multi-level approval workflows with real-time notifications.
Organizations need efficient expense approval processes that:
Intelligent expense approval with:
var expenseWorkflow = Blueprint.Create("ExpenseApprovalWorkflow")
// Receive expense submission
.AddSource<ExpenseReport>(config => config
.FromAPI("expense-submission-endpoint")
.WithRealTimeProcessing())
// Validate against expense policy
.Validate<ExpenseReport>(validation => validation
.AgainstSchema("expense-policy-schema")
.CheckReceiptsAttached()
.ValidateCategoryRules())
// JSON Logic routing based on amount and department
.Route(routing => routing
// Small expenses: auto-approve
.When(expense =>
expense.Amount < 100)
.ToDestination("auto-approve")
// Medium expenses: manager approval
.When(expense =>
expense.Amount >= 100 && expense.Amount < 1000)
.ToDestination("manager-approval")
// Large expenses: director approval
.When(expense =>
expense.Amount >= 1000 && expense.Amount < 5000)
.ToDestination("director-approval")
// Very large: CFO approval required
.When(expense =>
expense.Amount >= 5000)
.ToDestination("cfo-approval")
// Policy violations: manual review
.When(expense =>
expense.HasPolicyViolation)
.ToDestination("compliance-review"))
// Sign approval decision
.Sign(signature => signature
.WithAlgorithm(CryptoAlgorithm.ED25519)
.UsingApproverKey()
.IncludeApprovalReason())
// Store in distributed ledger
.Audit(audit => audit
.RecordApprovalChain()
.WithTimestamp()
.StoreInRegisterService())
// Real-time notifications
.Publish(notification => notification
.ToSubmitter("expense-status-change")
.ToApprover("new-expense-pending")
.ToFinance("expense-approved"))
.Build();
End-to-end procurement workflows with vendor validation, approval chains, and cryptographic transaction records in a distributed ledger.
Purchase order processing involves complex workflows:
Comprehensive purchase order workflow with:
var purchaseOrderWorkflow = Blueprint.Create("PurchaseOrderProcessing")
// Receive PO request
.AddSource<PurchaseOrder>(config => config
.FromProcurementSystem("po-requests")
.WithValidation())
// Validate vendor and budget
.Validate<PurchaseOrder>(validation => validation
.CheckApprovedVendor()
.VerifyBudgetAvailability()
.ValidateLineItems())
// Multi-party signing
.Sign(signature => signature
.WithAlgorithm(CryptoAlgorithm.NISTP256)
.RequireSignatures()
.FromRequester()
.FromManager()
.FromProcurement())
// Route based on value and category
.Route(routing => routing
.When(po => po.TotalValue < 5000)
.ToDestination("auto-process")
.When(po => po.TotalValue >= 5000 && po.TotalValue < 50000)
.ToDestination("director-approval")
.When(po => po.TotalValue >= 50000)
.ToDestination("executive-approval")
.When(po => po.IsInternational)
.ToDestination("international-review"))
// Store in distributed ledger with DID
.Audit(audit => audit
.CreatePORecord()
.WithDIDURI()
.EnableODataQueries()
.ChainToPreviousTransaction())
// Notify all stakeholders
.Publish(notification => notification
.ToRequester("po-status-update")
.ToVendor("po-issued")
.ToReceiving("po-goods-pending")
.ToAccounts("po-payment-pending"))
// Handle goods receipt
.OnEvent("goods-received", receipt =>
receipt
.ValidateAgainstPO()
.RecordInLedger()
.TriggerInvoiceMatching())
.Build();
Control exactly which data participants can access using JSON Pointers (RFC 6901). Enable secure collaboration with cryptographic guarantees and fine-grained access control.
Sharing sensitive data requires precise control over:
Selective data disclosure using:
var dataDisclosureWorkflow = Blueprint.Create("SelectiveDataDisclosure")
// Receive data disclosure request
.AddSource<DisclosureRequest>(config => config
.FromAPI("disclosure-requests")
.WithAuthentication())
// Validate requester permissions
.Validate<DisclosureRequest>(validation => validation
.CheckRequesterAuthorization()
.ValidateAccessPolicy()
.VerifyDataOwnerConsent())
// Apply JSON Pointers for selective disclosure
.Transform<DisclosureRequest, FilteredData>(request =>
request
// Allow researcher to see aggregate data only
.When(role => role == "Researcher")
.DiscloseFields("/surveyId", "/aggregateResults")
// Allow data steward to see identifiers but not PII
.When(role => role == "DataSteward")
.DiscloseFields("/surveyId", "/submissionDate", "/statusCode")
// Allow principal investigator to see all non-PII fields
.When(role => role == "PrincipalInvestigator")
.DiscloseFields("/surveyId", "/responses", "/demographics")
.ExcludeFields("/personalInfo/name", "/personalInfo/email")
// Data owner sees everything
.When(role => role == "DataOwner")
.DiscloseAll())
// Sign disclosed data
.Sign(signature => signature
.WithAlgorithm(CryptoAlgorithm.ED25519)
.IncludeDisclosurePolicy()
.IncludeAccessTimestamp())
// Record disclosure in ledger
.Audit(audit => audit
.RecordDataAccess()
.WithDIDReference()
.LogDisclosedFields()
.LogRequesterIdentity()
.EnableComplianceQuery())
// Notify data custodian
.Publish(notification => notification
.ToDataOwner("data-accessed")
.ToRequester("data-disclosure-granted")
.ToCompliance("disclosure-logged"))
// Validate disclosed data integrity
.Validate<FilteredData>(validation => validation
.AgainstSchema("filtered-data-schema")
.EnsureNoPIILeakage()
.VerifySignature())
.Build();
Complex survey workflows with conditional logic, data validation, and cryptographic protection of respondent data.
Research and customer feedback surveys require:
Intelligent survey workflows with:
var surveyWorkflow = Blueprint.Create("MultiStepSurveyCollection")
// Receive survey response
.AddSource<SurveyResponse>(config => config
.FromWebForm("survey-endpoint")
.WithSessionManagement())
// Validate current step
.Validate<SurveyResponse>(validation => validation
.AgainstSchema("survey-step-schema")
.CheckRequiredFields()
.ValidateResponseTypes())
// Conditional routing based on responses
.Route(routing => routing
// Basic demographic questions for everyone
.When(response => response.Step == 1)
.ToDestination("demographic-processing")
// Conditional follow-up based on age
.When(response =>
response.Step == 2 && response.Age < 25)
.ToDestination("youth-specific-questions")
.When(response =>
response.Step == 2 && response.Age >= 25)
.ToDestination("adult-specific-questions")
// Income-based routing
.When(response =>
response.Step == 3 && response.Income > 100000)
.ToDestination("high-income-questions")
// Final step: thank you
.When(response => response.IsComplete)
.ToDestination("completion-processing"))
// Encrypt sensitive fields
.Transform<SurveyResponse, ProtectedResponse>(response =>
response
.EncryptField("/personalInfo/email")
.EncryptField("/personalInfo/phone")
.HashField("/personalInfo/postalCode"))
// Sign and store
.Sign(signature => signature
.WithAlgorithm(CryptoAlgorithm.ED25519)
.IncludeSessionId())
.Audit(audit => audit
.RecordSubmission()
.WithAnonymizedIdentifier()
.EnableAggregateAnalysis())
// Notify researcher of completion
.Publish(notification => notification
.ToRespondent("survey-progress-saved")
.ToResearcher("new-response-received"))
.Build();
These production-ready examples are running in the Sorcha project today