NODEDC_DESIGN_GUIDELINE/docs/FOUNDRY_DATA_PRODUCT_BINDIN...

4.1 KiB

Foundry Data Product bindings

NDC Foundry Binding is a deploy/control-plane operation. Realtime facts do not pass through the node: Foundry persists an approved page-slot binding and its server-owned consumer reads snapshot and durable patch from External Data Plane. The same-origin BFF serves the persisted projection and bounded history without exposing the reader grant.

Private workload API

GET  /internal/foundry/v1/data-products
POST /internal/foundry/v1/data-product-bindings
Authorization: Bearer ndc_fndbg_<opaque capability>

The POST body is nodedc.foundry.binding-upsert/v1. It contains only application, page, binding, Data Product projection and a stable idempotency key. Provider, tenant, connection, endpoint, URL, raw payload and credentials are rejected.

This credential is not a Foundry MCP fnd1.* capability. MCP capabilities are short-lived interactive grants for AI Workspace. It is also not NODEDC_INTERNAL_ACCESS_TOKEN, a browser session, or an EDP writer/reader grant.

Workload grant

The opaque value never enters a Foundry env file or application manifest. Foundry hashes it with SHA-256 and resolves a root-owned, non-writable record from NODEDC_FOUNDRY_BINDING_GRANTS_DIR on every request. Removing or replacing the record therefore revokes or rotates access immediately.

A nodedc.module-foundry.binding-grant.v1 record fixes:

  • expiry and actions (catalog.read, map-data-product.upsert);
  • actor and owner used by the existing replay-safe Foundry write path;
  • exact allowlisted tuples of application, page, binding, slot, Data Product, semantic types and field projection.

No authorization claim is accepted from request headers or workflow data.

Before persisting a binding, Foundry verifies that the target-specific EDP reader grant exists, is active, permits the selected product and exposes a snapshot+patch product. The workload API remains fail-closed: if the grant is not ready, POST fails with 409 data_product_reader_grant_not_ready; an unusable visual binding is never saved.

The Foundry MCP consumer lifecycle owns managed grant creation. Its safe plan asks EDP to resolve unique active writer coverage by Data Product id. The response contains no provider, tenant or connection. Exact apply generates an opaque target token inside the persistent Foundry runtime and sends only its SHA-256 digest in a request signed by a dedicated Foundry Ed25519 service identity. EDP persists a durable, explicitly revocable reader binding. The signing private key is runner-managed and distinct from Engine; EDP mounts only its public trust copy. Legacy root-owned deployment grants are read-only compatibility fallback, not the normal lifecycle.

The canonical Map entity-stream slot is points. Other templates may define their own typed slots, but the workload grant must name them explicitly.

Server-owned consumer lifecycle

An approved binding is the only addressable consumer target. Foundry persists consumer state under the runtime volume, keyed by application/page/binding; it stores the binding identity, Data Product version, policy version, cursor, snapshot generation, safe subjects, presentation status and reconnect metadata. It never stores the reader capability value or EDP endpoint.

Foundry MCP exposes exact plan/apply, safe status, bounded accept and non-destructive rollback for this target. A missing legacy consumer record is bootstrapped lazily from the already approved binding; a missing target grant appears as the explicit ensure-target-scoped-reader-grant plan effect. An existing Map Page therefore does not require a new provider workflow, native n8n credential or manual pin migration.

Snapshot replacement and patch application are atomic per target. Cursor is committed before browser fan-out. Patch replay is idempotent; a gap causes snapshot rebase. One active upstream stream is shared by every viewer of the same target and is closed after the final viewer releases it. Temporary source or network failure preserves subjects. Stale and removal use the versioned provider-neutral policy registry: removal is allowed only by authoritative snapshot absence or canonical tombstone/revocation.