Skip to content
agstackPublic

About

Asset Registry's Hub and Spoke Model

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Asset Registry Node (ar2) - v0.9-review

The Asset Registry Node (ar2) acts as the Data Holder and Verifier in the AgStack Digital Public Infrastructure (DPI) architecture.

It stores high-resolution field boundary geometries and verifies field access credentials (ODRL Grants) before exposing sensitive data. It strictly adheres to two fundamental design rules:

  1. The Hub routes but never authorizes: The ar2-hub gateway forwards requests, but the Node is the ultimate authority that verifies the cryptographic grant.
  2. L1 requires a grant credential: High-resolution spatial data (Level 1 Masking) is never exposed without a valid ODRL JWT credential. The owner of the field is automatically the first grantee.

Key Features

  • Identity Resolution Engine: Prevents duplicated fields in the global registry. If a farm is registered twice (overlapping by a configurable threshold, defaulting to 95%), the node seamlessly aliases the new registration to the existing Geo Id. Furthermore, it supports hierarchical child_of relationship mapping for sub-plots completely contained within a larger farm boundary.
  • Trace-Back and Trace-Forward: Content-derived ListArtifacts (Merkle-root ListIDs over GeoIDs, nested lists, and regions) and RegionArtifacts (RegionIDs over an S2 cover, from WKT or member fields) turn the registry into a recall graph. Neither direction is open: the node verifies the caller's credential on every query. Trace-back (product to fields) requires a grant for the product being traced; trace-forward (a contaminated field to every downstream product) additionally requires a Hub-issued capability and seed authorization, and revealing downstream identities requires an accredited authority credential and is audited. See TRACEABILITY.md for the full reasoning, a worked cyclospora recall example, and a contrast with existing traceability platforms.

Architecture

Please see ARCHITECTURE.md for a detailed diagram of the Hub-Node-Pancake flow and a deeper dive into the DPI Trust architecture. For the recall/traceability model built on top of it, see TRACEABILITY.md.

Quickstart (10 Minutes to Run)

Follow these steps to run the Node locally alongside the ar2-hub and Pancake issuer.

  1. Create and activate a virtual environment:

    python3 -m venv ar-env
    source ar-env/bin/activate
  2. Install dependencies:

    pip install -r requirements.txt
  3. Configure Environment Variables: Copy the example environment file and update variables if necessary.

    cp .env.example .env
  4. Run the Uvicorn Server:

    uvicorn app.main:app --host 0.0.0.0 --port 8001 --reload

(Note: The ar2-hub gateway proxy should be run on a separate port, e.g., 8000, and this Node should typically be bound to an internal port like 8001 or shielded from public access).

Environment Variables Reference

Variable Description Default Demo-Only?
DATABASE_URL PostgreSQL connection string. Defaults to local postgres if omitted. postgresql://postgres:postgres@localhost:5432/postgres No
world_shp_file_PATH Path to the .shp file used for point-in-polygon country resolution. None No
JWKS_URL URL to fetch the ar2-hub JSON Web Key Set for L0 access token validation. http://127.0.0.1:8000/.well-known/jwks.json No

Endpoints Overview

Method Endpoint Description Auth Required
POST /register-field-boundary Registers a single WKT geometry. Yes (Hub JWT)
POST /register-field-boundaries-geojson Bulk registers from a GeoJSON feature collection. Point features take the point path below. Yes (Hub JWT)
POST /register-point Registers a plot declared by one coordinate, with the area it stands for (declared_area_ha, at most 4). Yes (Hub JWT)
POST /register-points-geojson Bulk registers points. Yes (Hub JWT)
GET /resolve/{geoid} Returns L0 masked data (S2 indices / Bounding Box) for a GeoID. No
GET /fetch-field-wkt/{geoid} Returns L1 high-resolution geometry. Yes (Grant)
GET /fetch-field-centroid/{geoid} Returns exact centroid of a field. Yes (Grant)
GET /geoid/{geoid}/eudr-export Exports an EUDR-compliant GeoJSON artifact. Yes (Grant)
POST /list-artifact Registers a content-derived list (a lot/case/pallet/retail item) over GeoIDs, nested lists (L:), or regions (R:). Append-only. Yes (Hub JWT)
POST /region-artifact Registers a content-derived region from a WKT boundary (no acreage cap) or from member GeoIDs/lists. Yes (Hub JWT)
GET /list-artifact/{list_id} Returns the members of a list artifact. Yes (Hub JWT)
GET /list-artifact/reverse/{geoid} Trace-forward: every list/region containing a GeoID, climbed recursively to terminal products. Yes (Hub JWT + trace-forward capability + seed authorization; accredited authority credential for the identity tier)

See TRACEABILITY.md for how these endpoints compose into trace-back and trace-forward.

Two kinds of plot

A plot reaches this registry as a boundary or as a coordinate, and the two are peers: same identifier shape, same resolution behaviour, same masking tiers, same consent flow, same EU filing route. Regulation (EU) 2023/1115 Art. 2(28) allows a plot of at most four hectares to be declared by a single coordinate, and in the Honduran cooperative survey the median plot is 0.30 ha, so most plots qualify. A registry that treated coordinates as a lesser case would work for the farms that had been surveyed and not for the rest.

boundary coordinate
named by SHA-256 over its sorted S2 cover (levels 1–20) SHA-256 over a one-cell cover of the leaf cell it lands in (level 30)
identifier 64 hex characters 64 hex characters, indistinguishable
re-submission resolves by cover overlap (IoU) against the threshold distance, within POINT_SAME_AS_METRES (10 m)
area computed from the boundary declared by the registrant, capped at 4 ha
L0 view level-10 cell, country, area, geometry_kind the same, with the declared area
L1 view the geometry, and GeometryKind / AreaHa the coordinate, and the same two
EU filing (/geoid/{id}/eudr-export) MultiPolygon Point with an Area property; refused if no area was declared
list membership any mix of the two in one ListID the same

Both kinds are named by the same digest over the same kind of cover, which is why a ListID may mix them and why nothing downstream can branch on shape.

GeometryKind and AreaHa are on the wire at both masking levels. A node entitled only to the masked view still has to know which kind of plot it is holding: screening a coordinate as though it were a boundary reads the single data cell containing the fix -- 36 m for the JRC deforestation layer -- and reports it as the plot. app/tests/test_point_polygon_peers.py runs one journey twice, once with each kind, and asserts the same answers everywhere except the two places they honestly differ.

Testing

A comprehensive API guide for interacting with the Node is provided in app/test_curls.txt. To run the automated test suite (which overrides the JWKS hub auth for isolation):

python -m pytest app/tests/test_api.py -v

Automated End-to-End Demos

There are two separate end-to-end demo scripts, each covering a different capability. Both require the Hub and Pancake servers to be running locally.

  1. Grant Lifecycle (./demo_e2e.sh) Covers the full lifecycle of a standard field grant (registration, issuance, retrieving L1 geometry, verification, and revocation).

  2. Trace-forward (./scripts/e2e_traceforward.sh) Covers the trace-forward recursive graph capability. It registers fields, builds a supply chain list structure, issues an authority credential, and then performs trace-forward queries to demonstrate Tier 1 vs Tier 3 identity disclosure rules, including negative assertions for missing or revoked authority.

About

Asset Registry's Hub and Spoke Model

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages