Multi-Party Inference

Multi-Party Inference enables multiple parties to collaborate on AI analysis without exposing their private data. Data is aggregated securely in TEE environments, and each party only sees the final result, not each other's inputs.

Overview

┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│   Party A   │     │   Party B   │     │   Party C   │
│  (Bank A)   │     │  (Bank B)   │     │  (Regulator)│
└──────┬──────┘     └──────┬──────┘     └──────┬──────┘
       │                   │                   │
       │ Encrypted Data    │ Encrypted Data    │ Observer
       │                   │                   │
       ▼                   ▼                   ▼
┌──────────────────────────────────────────────────────┐
│                  TEE Secure Enclave                  │
│  ┌────────────────────────────────────────────────┐  │
│  │  Decryption → Aggregation → AI Inference       │  │
│  │                    ↓                           │  │
│  │              Result + Attestation              │  │
│  └────────────────────────────────────────────────┘  │
└──────────────────────────────────────────────────────┘
       │                   │                   │
       ▼                   ▼                   ▼
   Result Only         Result Only         Result Only
   (No raw data)       (No raw data)       (No raw data)

Use Cases

  • Cross-Institution Risk Analysis - Banks analyze combined transaction data without sharing customer details
  • Supply Chain Optimization - Multiple vendors optimize logistics without revealing proprietary data
  • Healthcare Research - Hospitals collaborate on research without exposing patient records
  • Regulatory Compliance - Regulators verify compliance without accessing raw business data

Creating a Session

import { TenzroPlatform } from '@tenzro/platform';

const platform = new TenzroPlatform({
  apiKey: process.env.TENZRO_API_KEY!,
  tenantId: process.env.TENZRO_TENANT_ID!,
});

// Create a multi-party session
const session = await platform.ai.createMultiPartySession({
  name: 'Q4 Risk Analysis',
  description: 'Cross-bank transaction risk assessment',
  modelId: 'risk-analyzer-v2',

  // Participants who will contribute data
  participants: [
    'party::bankA::treasury',
    'party::bankB::treasury',
    'party::bankC::treasury',
  ],

  // Observers who can see results but don't contribute data
  observers: [
    'party::regulator::compliance',
  ],

  // Data policy configuration
  dataPolicy: {
    // Minimum participants required to run inference
    minParticipants: 2,

    // How data is combined
    aggregationMethod: 'federated', // 'federated' | 'secure_aggregation' | 'mpc'

    // Security requirements
    encryptionRequired: true,
    attestationRequired: true,

    // Data retention
    retentionPolicy: 'delete_after_inference',
  },

  // Session expiry
  expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000), // 24 hours
});

console.log('Session ID:', session.id);
console.log('Status:', session.status);
console.log('Join Code:', session.joinCode);

Contributing Data

Each participant contributes their encrypted data to the session:

// Get session encryption key
const sessionKey = await platform.ai.getSessionKey(session.id);

// Encrypt your data locally (client-side)
const encryptedData = await encryptWithSessionKey(
  JSON.stringify(myTransactionData),
  sessionKey.publicKey
);

// Submit encrypted data
await platform.ai.submitSessionData({
  sessionId: session.id,
  data: encryptedData,
  dataSchema: 'transaction_records_v1',
  commitment: await hashCommitment(myTransactionData), // For verification
});

console.log('Data submitted successfully');

Consent Management

// Each participant must consent to the inference
await platform.ai.submitSessionConsent({
  sessionId: session.id,
  consent: {
    dataUsage: true,          // Allow data to be used
    resultSharing: true,       // Allow results to be shared with other participants
    attestationSharing: true,  // Allow TEE attestation to be shared
    retentionAcknowledged: true,
  },
  signature: await signConsent(session.id, myPrivateKey),
});

// Check consent status
const status = await platform.ai.getSessionStatus(session.id);
console.log('Consented participants:', status.consentedParticipants);
console.log('Pending consent:', status.pendingConsent);

Running Inference

// Once all participants have submitted data and consent, run inference
const result = await platform.ai.runMultiPartyInference({
  sessionId: session.id,
  prompt: 'Analyze combined transaction patterns for anomalies',
  parameters: {
    maxTokens: 2048,
    temperature: 0.3,
  },
});

console.log('Result:', result.content);
console.log('TEE Attestation:', result.teeAttestation);
console.log('Participant Count:', result.participantCount);
console.log('Data Hash:', result.aggregatedDataHash);

// Each participant receives the same result
// but cannot see each other's raw data

Session Lifecycle

// Session states
type SessionStatus =
  | 'created'           // Session created, awaiting participants
  | 'collecting'        // Collecting data from participants
  | 'awaiting_consent'  // Waiting for consent from all participants
  | 'ready'             // Ready to run inference
  | 'running'           // Inference in progress
  | 'completed'         // Inference complete, results available
  | 'expired'           // Session expired
  | 'cancelled';        // Session cancelled

// Monitor session status
const session = await platform.ai.getMultiPartySession(sessionId);
console.log('Status:', session.status);
console.log('Participants:', session.participants);
console.log('Data submitted:', session.dataSubmittedBy);
console.log('Consent from:', session.consentedBy);

React Integration

import {
  useMultiPartySessions,
  useMultiPartySession,
  useCreateMultiPartySession,
  MultiPartySessionManager,
  MultiPartySessionList,
  MultiPartySessionDetail,
  CreateMultiPartySession,
} from '@tenzro/platform-ui';

function MultiPartyPage() {
  // List all sessions
  const { sessions, loading, refresh } = useMultiPartySessions();

  // Create new session
  const { createSession, loading: creating } = useCreateMultiPartySession();

  const handleCreate = async () => {
    const session = await createSession({
      name: 'New Analysis',
      modelId: 'risk-analyzer-v2',
      participants: ['party::bankA::treasury', 'party::bankB::treasury'],
      dataPolicy: {
        minParticipants: 2,
        aggregationMethod: 'federated',
        encryptionRequired: true,
      },
    });
    refresh();
  };

  return (
    <div>
      {/* Option 1: Use individual components */}
      <CreateMultiPartySession
        onCreated={(session) => {
          console.log('Created:', session);
          refresh();
        }}
      />

      <MultiPartySessionList
        sessions={sessions}
        onSelect={(session) => console.log('Selected:', session)}
      />

      {/* Option 2: Use the all-in-one manager */}
      <MultiPartySessionManager
        onSessionCreated={(session) => console.log('Created:', session)}
        onSessionCompleted={(session, result) => console.log('Result:', result)}
        allowCreate={true}
        showParticipants={true}
      />
    </div>
  );
}

// Session detail view
function SessionDetail({ sessionId }: { sessionId: string }) {
  const { session, loading, error } = useMultiPartySession(sessionId);

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <MultiPartySessionDetail
      session={session}
      onSubmitData={async (data) => {
        // Handle data submission
      }}
      onConsent={async () => {
        // Handle consent
      }}
      onRunInference={async () => {
        // Handle running inference
      }}
    />
  );
}

Data Aggregation Methods

Federated Learning

Each participant trains a local model, and gradients are aggregated:

{
  aggregationMethod: 'federated',
  federatedConfig: {
    localEpochs: 5,
    aggregationRounds: 10,
    differentialPrivacy: {
      enabled: true,
      epsilon: 1.0,
      delta: 1e-5,
    },
  },
}

Secure Aggregation

Data is encrypted and aggregated without exposing individual values:

{
  aggregationMethod: 'secure_aggregation',
  secureAggConfig: {
    threshold: 2, // Min participants to decrypt
    noiseAddition: true,
  },
}

Multi-Party Computation (MPC)

Cryptographic protocols compute on encrypted data:

{
  aggregationMethod: 'mpc',
  mpcConfig: {
    protocol: 'shamir_secret_sharing',
    threshold: 3,
    totalParties: 5,
  },
}

Security Features

  • End-to-End Encryption - Data encrypted from client to TEE
  • Zero-Knowledge Aggregation - No party sees others' raw data
  • TEE Attestation - Hardware proof of secure execution
  • Consent Tracking - Cryptographic proof of participant consent
  • Audit Trail - All actions recorded on Canton ledger

Best Practices

  1. Set appropriate minParticipants - Balance privacy vs. data quality
  2. Use short session expiry - Minimize data exposure window
  3. Require attestation - Always verify TEE execution
  4. Add observers for compliance - Allow regulators to verify results
  5. Use differential privacy - Add noise for additional privacy guarantees

API Reference

MethodDescription
ai.createMultiPartySession()Create a new multi-party session
ai.getMultiPartySession()Get session details
ai.listMultiPartySessions()List all sessions
ai.getSessionKey()Get encryption key for session
ai.submitSessionData()Submit encrypted data
ai.submitSessionConsent()Submit consent for inference
ai.runMultiPartyInference()Execute inference on aggregated data
ai.cancelSession()Cancel a session