Skip to content

Latest commit

 

History

History
129 lines (102 loc) · 6.79 KB

README.md

File metadata and controls

129 lines (102 loc) · 6.79 KB

FORA — Reference Implementation

A working implementation of the FORA protocol for licensed AI content access.

FORA lets software agents find, pay for, and download licensed content from publishers. This repository implements the whole path, end to end:

Agent ── MCP ──► Identity ──► Broker ──► Exchange ──► (signed URL) ──► Edge ──► Origin
  1. Ask. An agent asks for content. It can call the Identity service's MCP tools (fora_register, fora_discover, fora_execute, fora_report, fora_status), which sign each call with the agent's stored key, or it can use the protocol SDK directly and sign its own requests.
  2. Discover. The Broker finds the exchange that licenses the content. It reads the publisher's /.well-known/fora.json, which names the exchanges that sell the site. Every publisher serves that file from its own site; there is no fallback to the plain URL.
  3. Buy. The agent accepts an offer. The Exchange verifies the signatures, charges the agent's prepaid balance, records the transaction, and returns a signed URL.
  4. Download. The agent fetches the signed URL. The Edge verifies the signature, and that the request comes from the agent the offer was sold to, then passes the request to the publisher's own origin.
  5. Report. The agent reports its usage back to the Exchange that sold it.

The agent never sees the underlying delivery URL, and no secret is shared between tenants: every signature is asymmetric.

Publishers join through the publisher console. They name their business once, then set up each site: its domain, its terms, and the two things that connect it — the discovery file they serve from their own site, and the edge package they install on their CDN.

Components

Path Language Role
src/identity/ Go (Connect-Go, Postgres, Vault) Agent registry and Web Bot Auth directory. Developer sign-up, per-agent signing keys, and the MCP endpoint that turns each tool call into a key-signed FORA request.
src/broker/ Go (Connect-Go, Postgres + Redis) Discovery and routing. Resolves a URL to the exchange that licenses it, applies per-agent spending limits, and relays the signed request.
src/exchange/ Go (Connect-Go, Postgres, TigerBeetle) Catalog, offer signing, transaction execution, signed-URL minting (Ed25519, or CloudFront RSA for a site set up that way by hand; chosen per publisher site), and usage reporting.
src/console/ Go (html/template, Postgres) Publisher console. Publishers sign in, register their business and their sites through the Exchange's signed registration routes, and download the discovery file and the edge package made for each site.
src/edge/ TypeScript (Hono, multi-runtime) Signed-URL verification at the CDN. One runtime-agnostic core with adapters for Cloudflare Workers, Fastly Compute, and AWS Lambda@Edge. It passes the publisher's own /.well-known/fora.json and /rsl.txt through to the origin.
internal/ Go Shared packages: database setup, HTTP server harness, HTTP message signatures, cost arithmetic, structural guards.
tests/e2e/ Python (pytest, uv) End-to-end suite driving the full docker-compose stack.

The wire format is not defined here. It comes from the protocol module github.com/FORA-Protocol/protocol, pinned in go.mod and in the Python and TypeScript manifests, so every language in this tree speaks one revision.

Underneath, the services need PostgreSQL (one database each), Redis (replay protection and spending counters), TigerBeetle (the financial ledger), Vault (agent signing keys), and an OIDC provider.

Quick start

Requires Docker, Go 1.26, Node 22 (the version every image in this tree builds with), and uv with Python 3.12 for the end-to-end harness.

make test-fast          # fast tests across Go, TypeScript, and Python
make test-integration   # Go integration tests against testcontainers Postgres and Redis
make test-e2e           # the full docker-compose stack, end to end
make quality            # format, lint, typecheck, fast tests, and the structural gates

make help lists the rest. make install-tools fetches the linters and code generators the gates expect.

Reconciling a transaction

Every successful purchase leaves evidence at three independent parties. To check one transaction across all of them:

make ledger TX=<transaction-id>

The tool reads the Exchange's admin API, the Broker's database, and the Edge's delivery log, then reports whether the bytes each party stored agree with each other. It re-derives nothing — an agreement is a comparison of what was actually recorded, so tampering at any single party shows up as a mismatch.

Container images

Each release publishes four images to the GitHub Container Registry:

ghcr.io/fora-protocol/exchange
ghcr.io/fora-protocol/broker
ghcr.io/fora-protocol/identity
ghcr.io/fora-protocol/console

Every build gets exactly one immutable tag — the version, with no leading v. There is no latest and no moving major or minor pointer, so a pull with no tag fails on purpose rather than quietly running whatever was pushed last. Each service's DEPLOYMENT.md names the version to pull. In production, deploy the @sha256: digest instead. Our tags are written once and never moved, but that is a policy of ours; a digest is content-addressed and nobody can move it. The reasoning is in ADR-024.

The Edge worker is not a container. It deploys to the CDN — see src/edge/DEPLOYMENT.md.

Documentation

  • docs/HANDOFF-operator.md — start here to run this yourself: what the platform is made of, what to prepare, how the network must be laid out, and where each component's own guide lives.
  • docs/architecture/ — the architecture decision records: request signing and key rotation, the licensing vocabulary, publisher registration, the transaction journal, and the testing rules. A record that was replaced stays in place, marked superseded.
  • Per service, under src/<service>/: CONFIGURATION.md (every setting), DEPLOYMENT.md (how to run it), and RUNBOOK.md (what to do when it breaks).
  • Backing services are documented the same way under deploy/storage/ and deploy/zitadel/.
  • deploy/terraform/ — modules and stacks for a staging or demo deployment on AWS, and for a publisher's edge on Cloudflare or AWS CloudFront.

License

Apache License 2.0. See LICENSE.