PlatformXeDocs
Get API Key

Federation

Push fraud rules and tenant lists from a parent organisation to every member of a federation group.

Phase 6G builds on the Authorization Engine's federation infrastructure to let an Enterprise tenant push their fraud detection configuration across every organisation in a federation group — subsidiaries, partner brands, sandbox environments. Tune once at the parent, mirror everywhere.

Two assets are pushed:

  • Published fraud rules — every rule with status = 'published' (Phase 6B).
  • Tenant liststenant_blocklist and tenant_allowlist rows plus their entries (Phase 6C).

Sanctions / PEP / adverse_media lists are NOT pushed — those are global lists managed by the daily refresh cron (Phase 6C2) and already shared across every tenant.

Plan & scope

PropertyValue
Plan gateEnterprise + Detection Pack addon
Scope (push)permissions:manage
Scope (preview)permissions:check
IdempotentYes (Idempotency-Key honoured on push)
Rate limit500 / hr per API key on permissions:manage

Only the owner of a federation group may push (federation_groups.ownerOrgId). Non-owners get 403 FORBIDDEN. Members do NOT receive pushes from each other.

Preview

GET /api/v1/permissions/federation/groups/:id/fraud/preview

Dry-run the push without writing anything. Returns the same shape as the live push so the admin / portal UI can show "what would change" before the operator commits.

curl https://api.platformxe.com/api/v1/permissions/federation/groups/fed_abc123/fraud/preview \
  -H "x-api-key: pxk_live_your_api_key_here"
{
  "success": true,
  "data": {
    "groupId": "fed_abc123",
    "ownerOrgId": "org_parent",
    "rulesAvailable": 7,
    "listsAvailable": 2,
    "members": [
      {
        "organizationId": "org_subsidiary_a",
        "rulesPushed": 7,
        "listsPushed": 2,
        "entriesPushed": 84,
        "status": "success",
        "error": null,
        "durationMs": 12
      }
    ],
    "dryRun": true,
    "durationMs": 18
  }
}

Push

POST /api/v1/permissions/federation/groups/:id/fraud/push

Mirrors the owner's rules + lists into every other group member.

curl -X POST https://api.platformxe.com/api/v1/permissions/federation/groups/fed_abc123/fraud/push \
  -H "x-api-key: pxk_live_your_api_key_here" \
  -H "Idempotency-Key: $(uuidgen)"
const result = await px.fraud.federation.push('fed_abc123');
const failed = result.data.members.filter((m) => m.status === 'failed');
if (failed.length > 0) {
  // Surface to ops — partial failures are NOT auto-retried
}

Per-member result

FieldDescription
organizationIdThe target member.
rulesPushedNumber of rule rows inserted into the target.
listsPushedNumber of tenant lists upserted into the target.
entriesPushedNumber of list entries written across all upserted lists.
status'success' or 'failed'.
errorFailure message when status is 'failed'. null otherwise.
durationMsPer-member wall time.

Mirroring semantics

Rules

  • Each pushed rule is keyed by name against the target's existing rules.
  • A fresh row is inserted with status = 'published', the parent's content (weight, condition, windows, appliesTo, verdictOverride, description), and a version = max(existing) + 1.
  • createdBy = 'federation:<ownerOrgId>' — the audit trail makes the origin obvious.
  • Existing rule versions in the target stay in place — they're not deleted. Members can fall back to local versions by changing status if the federated rule misbehaves.

Lists

  • Tenant lists are matched by (targetOrgId, source).
  • Existing target lists are KEPT (id stable); their entries are replaced atomically.
  • Missing lists are created.
  • Sanctions / PEP / adverse_media lists are excluded — the schema's kind filter explicitly limits to tenant_blocklist and tenant_allowlist.

Audit

Each target member generates ONE federation_sync_logs row per push call:

ColumnValue
direction'push'
status'success' or 'failed'
modulesCountRules pushed
adminsCountLists pushed
durationMsPer-member duration
errorFailure message when status is 'failed'

The platform event FRAUD_FEDERATION_PUSHED fires once per push call with the rolled-up summary — subscribe via webhooks to wire up SOC alerting.

Partial-failure handling

A push to one member failing does NOT abort the rest. Each member is attempted, errors are logged + audit-trailed, and the response carries the full per-member breakdown so you can:

  1. Re-run the push (idempotent — succeeded members get a fresh version row but no semantic change).
  2. Investigate the specific failed members via federation_sync_logs.

There is no auto-retry; pushes are operator-initiated.

Error responses

HTTPCodeCause
400BAD_REQUESTMissing federation group id in path.
401UNAUTHORIZEDMissing or invalid API key.
402ENTERPRISE_REQUIREDTenant is not on Enterprise.
402DETECTION_PACK_REQUIREDDetection Pack addon not enabled.
403FORBIDDENCaller is not the federation group owner.
404NOT_FOUNDFederation group not found.
500INTERNAL_ERRORUnexpected service failure (very rare — push is purely DB I/O).

What's NOT included

  • Live decision-engine sync — pushes are configuration only. Each member still renders its own verdicts using its own rule engine + Redis counters.
  • Reverse pull — there is no "pull from member A into the parent." If you want to consolidate insights, query each member's fraud_decisions via your own pipeline.
  • Sanctions / PEP coverage — global lists already cover every tenant; no federation push needed.
  • KYC config — country plugins ship as code, not tenant configuration. Federation does not push identity provider preferences.