AIGQLUnify • Architecture patent pending
Your REST · Our Graph
High-level architecture

How AIGQLUnify sits in your estate

REST and OpenAPI services stay where they are. AIGQLUnify becomes the federated fabric in the middle, speaking GraphQL to consumers while enforcing policy, DSAR, and observability on every hop.

This page zooms out: where the control plane (CP) lives, where the data plane (DP) runs, how PDP / PEP decisions flow, and how DSAR and OpenTelemetry hang off the same path. For API-specific behavior, see the Build, Secure, Govern, and Observe pages.

Architecture diagram showing REST services, AIGQLUnify control/data plane, and consuming clients
Policy-aware AI

Ask AI, stay inside PDP + DSAR policy.

Diagram showing Ask AI requests flowing through AIGQLUnify policy, PDP, and GraphQL before reaching the model

The askAI path is just another action on the same PDP: the model only sees what the graph returns after masking, and only when obligations say features.ai = true. That means no side-channel around DSAR, no AI prompt that bypasses Zero-Trust, and a trace for every invocation. For inline modeling helpers and more detailed flows, see the AI helpers page → and the Secure page →.

PDP / PEP at runtime

How AIGQLUnify turns policy into per-field behavior.

Inside the AIGQLUnify runtime

A. Policy decision logic (PDP)

The control plane acts as your Policy Decision Point via a decidePdp function that evaluates: subject (who is calling), action (read, create, delete, invoke for AI), resource (GraphQuery, DSAR, orders, etc.), and rich context such as the exact GraphQL selections requested.

  • Deny-by-default: unmatched calls fall through to allow: false — a Zero-Trust baseline.
  • Role-based gating: analysts are blocked from create, delete, and introspection; DSAR actions are limited to admin / privacy roles.
  • AI-aware policy: AI invocations are explicitly gated so, for example, isAnalyst && isAI can be refused up front.
  • PII masking obligations: for an analyst’s read, the PDP returns obligations.mask = ["userEmail", …] instead of just allow: true.

B. Policy enforcement (PEP)

The same decision is enforced at two layers:

  • At the control plane gateway: handlers call enforcePdp first. If the decision is not allowed, the request ends with 403 Forbidden before any business logic runs. A global onRequest hook verifies JWTs when enabled.
  • At the data plane: the obligations are sent alongside the request. The federated GraphQL engine uses obligations.mask to redact or drop fields as it resolves data — field-level PEP at the gateway / subgraph layer.

C. Observability & auditability

Helpers like tagPdpDecision and tagDsarSpan attach the decision (allow flag, reason, resource, obligations) as attributes on every OpenTelemetry span. That gives you an immutable, queryable audit trail that ties every API call to the policy that governed it.

How others solve (or don’t)

Most stacks have to bolt this together across gateways, microservices, and ad-hoc filters. AIGQLUnify ships it as one runtime.

A. Non-federated API gateways

  • Typical pattern: JWT / scope checks in a Lambda authorizer, field-level PII handling buried inside each backend service.
  • AI risk: LLMs see raw data and rely on prompt-level “please don’t leak PII”.
  • AIGQLUnify difference: centralized PDP, obligations-driven masking at the GraphQL layer, and policy checks before AI is even invoked.

B. Traditional GraphQL federation

  • Typical pattern: each subgraph owns its own auth; security is scattered across dozens of services.
  • Failure mode: one service forgets to scrub a PII field and the composed graph happily returns it.
  • AIGQLUnify difference: a single PDP decision for the whole federated query, enforced consistently via obligations across all backing services.

The result: Zero-Trust by construction — GraphQL, DSAR, and AI all share the same PDP/PEP path, the same obligations, and the same OpenTelemetry evidence.

Tame the legacy zoo

Modernize legacy / obsolete APIs without touching them.

The AIGQLUnify Data Plane is built to quarantine old or risky APIs. It turns them into a modern, unified, secure GraphQL surface — while the original SOAP / REST / monolith stays where it is.

Legacy API problem AIGQLUnify DP behavior Advantage for legacy APIs
Obsolete protocols (SOAP, old REST versions) Subgraph resolvers (dpResolvers) act as the translation layer. They consume the legacy API, but clients only ever see a clean GraphQL interface. Decoupling: you can migrate or deprecate the original endpoints without breaking any client that speaks GraphQL to AIGQLUnify.
Inconsistent names / shapes / pagination AIGQLUnify uses an explicit mapping layer to normalize field names, nested shapes, and pagination into a consistent GraphQL contract. Clean contract, messy source: legacy REST can stay weird, while your graph stays predictable. Curious how the mapping works? See “How do you handle inconsistent REST APIs?” in the FAQ.
Lack of unification / stitching The DP uses the Apollo subgraph schema (mkSchema) and the /plan endpoint to execute the stitched SDL from the control plane. The CP plans the joins; the DP runs them. Unified data access: join data from a monolith, a newer REST API, and even a warehouse into a single GraphQL response.
Poor observability The DP wires in Apollo tracing plugins and Fastify logging hooks, and exports spans and metrics via OpenTelemetry. Modern telemetry: legacy APIs gain traces, logs, and metrics the moment they sit behind AIGQLUnify — no changes needed to the old code.
Insecure / no security policy Security is enforced upstream by the control plane calling the PDP. The DP only resolves fields that the PDP obligations allow, including PII masks. Zero-Trust wrapper: AIGQLUnify becomes the enforcement shell. Even if the legacy backend has no concept of fine-grained policy, outbound data is filtered and masked before it leaves the DP.

For teams staring at decades of technical debt, this is the upgrade path: keep the systems of record, wrap them with AIGQLUnify, and gradually retire the old endpoints while clients stay stable on the GraphQL fabric.