Skip to main content

Federated Learning

The Federated Learning API lets multiple Adjudon organisations collaborate on shared pattern detection (fraud signatures, AI incident archetypes, content-moderation drift) without sharing the underlying decision data. Each org's local trainer pushes a differentially-private model update; the aggregation service combines updates with calibrated noise; the resulting global model is published back to participants. Tested against API version v1. Mounted at /api/v1/federated. JWT auth; plan-gated by federatedLearning — Custom plans only.

Status

Federated Learning is on the published roadmap as Phase 3 (Q3-Q4 2027). The endpoints below are wired today on the Custom tier; the cross-org coordination, DP-noise calibration, and participant onboarding go through Adjudon Solutions Engineering as part of the Custom-plan negotiation. The schema ships AS BUILT; the production rollout drains in waves through participating consortia.

How it works

   ┌──────────────────────────────────────────────────────────┐
│ 1. Coordinator creates a PatternFamily (consortium) │
│ ──> sets domain ('financial-fraud', etc.) │
│ ──> sets DP defaults (epsilon, delta) │
├──────────────────────────────────────────────────────────┤
│ 2. Each member org POSTs /families/:id/join │
├──────────────────────────────────────────────────────────┤
│ 3. Coordinator POSTs /families/:id/rounds (kickoff) │
│ ──> Round status: pending → collecting │
├──────────────────────────────────────────────────────────┤
│ 4. Each participant POSTs /rounds/:id/updates │
│ with a DP-clipped local-model vector │
├──────────────────────────────────────────────────────────┤
│ 5. Coordinator POSTs /rounds/:id/aggregate │
│ ──> Status: aggregating → completed │
│ ──> globalModelRef + aggregateHash published │
├──────────────────────────────────────────────────────────┤
│ 6. Coordinator POSTs /rounds/:id/evidence │
│ ──> Sigstore-signed attestation bundle │
└──────────────────────────────────────────────────────────┘

Two MongoDB collections back the API: PatternFamily (the consortium) and FederatedRound (one row per coordination round). The Adjudon coordinator process is the trusted aggregator; the roadmap includes a Trusted-Execution-Environment (TEE) attestation path so the aggregation can run in a hardware-attested enclave that even the coordinator cannot inspect (gated by teeAttestation, also Custom-only).

Endpoints

GET    /api/v1/federated/families
GET /api/v1/federated/families/:id
POST /api/v1/federated/families/:id/join
POST /api/v1/federated/families/:id/leave
GET /api/v1/federated/families/:id/rounds
POST /api/v1/federated/families/:id/rounds ── kickoff
GET /api/v1/federated/rounds/:roundId
POST /api/v1/federated/rounds/:roundId/updates ── client update
POST /api/v1/federated/rounds/:roundId/aggregate
POST /api/v1/federated/rounds/:roundId/evidence

The PatternFamily object

FieldTypeDescription
namestringConsortium name (e.g. eu-fraud-2027-q1)
domainstringFree-text classification (financial-fraud, medical-triage, …)
members[]arrayEach entry { organizationId, joinedAt, status: 'active'/'paused'/'left' }
coordinatorOrgIdstring | nullAdjudon-internal by default; can be a member-org for self-coordinated families
currentRoundnumberRound counter; advances on aggregate completion
defaultEpsilonnumberDP epsilon default for rounds (1.0)
defaultDeltanumberDP delta default (1e-5)
statusenumactive, paused, archived

The FederatedRound object

FieldTypeDescription
familyIdstringOwning consortium
roundNumbernumberUnique within familyId; compound index
participantOrgIds[]string[]Orgs that submitted a client update
minParticipantsnumberDefault 3; aggregation refuses to run below this
statusenumpending, collecting, aggregating, completed, failed
epsilon, deltanumberDP parameters for the round
noiseMechanismenumlaplace, gaussian (default gaussian)
expectedLengthnumber | nullRequired client-update vector dimension
clipNormnumberL2 sensitivity bound; default 1.0
globalModelRefstring | nullS3-style reference or content hash post-aggregation
aggregateVectornumber[]Computed aggregate; omitted until completion
aggregateHashstringSHA-256 of canonicalised aggregate
participantCountnumberSuccessful contributions
rejectedCountnumberRejected contributions (clip-norm violation, malformed payload)
rejectionReasonsobjectorgId → reason; surfaces why each participant was excluded
contributionWeightsobjectorgId → weight; transparency on aggregation weighting
attestationRefstring | nullTEE attestation hash (when teeAttestation is on)
sigstoreBundleRefstring | nullSigstore-signed evidence bundle
chainHashstring | nullHash-chain anchor on round completion

Submit a client update

POST /api/v1/federated/rounds/:roundId/updates

Body: { vector: number[], orgId? }. The vector must match expectedLength and respect the round's clipNorm (L2 sensitivity bound). Updates that violate the bound are rejected synchronously with the violation reason landing in FederatedRound.rejectionReasons[orgId]. The reason vocabulary is curated — never raw error text, per Cardinal Rule #4 on the federated path.

curl — submit local-model vector
curl -X POST https://api.adjudon.com/api/v1/federated/rounds/65b1f2c4/updates \
-H "Authorization: Bearer $ADJUDON_JWT" \
-H "Content-Type: application/json" \
-d '{ "vector": [0.124, -0.087, ...], "orgId": "65a8b2c1..." }'

The endpoint never accepts raw training data — only the DP-clipped model-update vector. Adjudon does not see the participant's underlying decisions; that is the entire point of the federated architecture.

Run aggregation

POST /api/v1/federated/rounds/:roundId/aggregate

Coordinator-only. Combines submitted updates with the configured noise mechanism, computes the L2-clipped weighted average, serialises the result, hashes it, and writes globalModelRef + aggregateVector + aggregateHash. The round status transitions aggregating → completed (or failed if fewer than minParticipants valid updates were received).

The handler also computes per-participant contributionWeights and persists them — an auditor or a participant org can later read who contributed how much without trusting the coordinator's claim.

Sign aggregation evidence

POST /api/v1/federated/rounds/:roundId/evidence

Generates a Sigstore-signed attestation bundle anchoring the round's inputs, the noise parameters, the participant set, and the resulting aggregateHash. The sigstoreBundleRef is written back to the round so participants can fetch and verify the bundle independently. Plan-gated by sigstoreEvidence (Enterprise+).

Differential privacy parameters explained

The four DP-related fields on FederatedRound are the mathematical contract every participant inherits when they submit a client update. Understanding them is non-optional for operators in regulated sectors:

ParameterWhat it boundsDefault
epsilonPrivacy budget per round; lower means stronger privacy, more noise1.0 (moderate)
deltaProbability the privacy guarantee leaks; must be << 1/n for n participants1e-5
noiseMechanismgaussian (default; required for ε-δ DP); laplace (pure ε DP, larger noise)gaussian
clipNormL2 sensitivity bound; client updates exceeding this are scaled down to fit1.0

The defaults are intentionally conservative. A consortium that needs tighter privacy reduces epsilon to 0.5 or below at the cost of noisier global models; a consortium needing higher utility raises it with explicit member sign-off recorded in the PatternFamily.members[] consent fields. The coordinator cannot raise epsilon mid-round — the schema validates the round's parameters at kickoff and rejects mutations against the field thereafter.

The privacy-budget accounting itself lives on the Privacy Budget API; each participant tracks cumulative epsilon spent across all rounds they joined.

Architecture — split between Adjudon and the local trainer

The published Phase 3 architecture is deliberately split. Adjudon operates the coordinator (round kickoff, aggregation, evidence signing); the participant org operates the local trainer (loads the org's local trace data, computes a gradient or pattern statistic, applies clip-and-noise locally, emits the DP-clipped vector). The split exists because the local trainer needs read access to raw decisions that must never leave the org's tenancy. Adjudon ships a reference local-trainer in the Python SDK under the adjudon-federated adapter package; customers operating in their own infrastructure implement the local-trainer side once against the Adjudon documented round-protocol.

The reference adapter is built against Flower Labs open-source primitives where they fit; the protocol layer between local trainer and coordinator is an Adjudon contract, not Flower's, so customers running their own training stack do not inherit Flower's coupling.

How an auditor reads the federated record

A regulator auditing a federated-learning consortium typically asks for three artefacts per round:

  1. The aggregation receiptGET /rounds/:roundId returns participants, parameters, hashes, and Sigstore evidence reference. The receipt is publicly readable inside the consortium.
  2. The privacy-budget tally — per-participant epsilon spend over time, surfaced via the Privacy Budget API. The regulator confirms no participant exceeded their declared budget across the audit window.
  3. The Sigstore bundle — verifiable proof that the aggregation parameters published to participants match what actually ran. The bundle is the evidence-of-record; without it, the receipt is the coordinator's claim, not a verifiable artefact.

The combination is what closes the regulator's loop on "show me that this consortium runs DP and that the math actually applied."

Common gotchas

  • Custom-plan only. This is the most heavily plan-gated resource on the platform. Sandbox / Scale / Governance / Enterprise all return 403 UPGRADE_REQUIRED. Custom-plan contracts negotiate participation in specific consortia.
  • No raw data on the wire. The endpoints accept DP-clipped model updates only. Submitting raw training data or decision payloads is a category error the schema does not represent.
  • minParticipants is a floor, not a target. The default 3 is the minimum for differential-privacy guarantees to hold meaningfully; production consortia run with 10-20 participants.
  • Curated rejection reasons. Per Cardinal Rule #4, the reason vocabulary is bounded (clip-norm-violation, dimension-mismatch, late-submission, malformed-payload). Raw error messages never flow back to participants.
  • Idempotency. Idempotency-Key middleware is wired only on POST /traces; client-update submission is bounded by per-round (orgId) uniqueness server-side, so a double-submit with the same vector is no-op idempotent. Aggregation cannot run twice on the same round.

See also

  • Privacy Budget API — the DP-budget tracking surface for federated participants
  • Provenance API — the C2PA-anchored provenance surface that signs aggregation evidence
  • Plans & Features — the federatedLearning, teeAttestation, and sigstoreEvidence feature gates
  • Hash Chain — the tamper-evident anchor for round completion
  • Error Codes — the broader error taxonomy