Skip to content

Accept new-style SACD grants: ODRL Agreements under DIMO profile v1#17

Open
elffjs wants to merge 1 commit into
mainfrom
odrl-sacd-v1
Open

Accept new-style SACD grants: ODRL Agreements under DIMO profile v1#17
elffjs wants to merge 1 commit into
mainfrom
odrl-sacd-v1

Conversation

@elffjs

@elffjs elffjs commented Jul 9, 2026

Copy link
Copy Markdown
Member

What

Alongside legacy SACDData documents, the exchange now accepts CloudEvents of type dimo.sacd.odrl whose data is a W3C ODRL 2.2 Agreement restricted to DIMO profile v1 (https://ns.dimo.co/odrl/v1). Dispatch is on the CloudEvent envelope type; legacy documents flow through the existing path untouched.

ODRL: W3C spec · Wikipedia

Profile v1 deliberately covers exactly the capabilities of legacy permission grants, no more:

Concept ODRL term
Asset / subject target (ERC721/Ethr DID)
Grantor assigner (did:ethr:...)
Grantee assignee (did:ethr:...)
Valid period constraint (dateTime comparisons, conjunctive; absent = unbounded)
Named permissions permission[].action (existing privilege:* names)

The minted claims are identical to those from an equivalent legacy document, so downstream consumers (dq) need no changes. Parties are DIDs rather than legacy {address} objects. CloudEvent-scoped access is not in profile v1; token requests carrying event filters are refused when backed by an ODRL grant.

Fail-closed by construction

  • Unknown fields anywhere (prohibition, duty, refinements, per-permission constraints) reject the document in full.
  • No JSON-LD processing, ever. @context must be byte-identical to a canonical form and is never dereferenced — a hostile context cannot remap term meanings under the grantor's signature.
  • Actions come from a closed vocabulary (the existing permission names); an unknown action rejects the whole document so authoring typos fail loudly at exchange time.
  • Operators limited to gteq/gt/lteq/lt over dateTime with plain RFC 3339 operands.

Later profile versions widen the vocabulary (CloudEvent scoping via refinements, Set templates, isAnyOf, purpose constraints); they never change the meaning of v1-valid documents.

Files

  • internal/exchange/models/odrl.go — strict profile parser and structural validation
  • internal/exchange/autheval/odrl.go — grant-map evaluation (target, validity window, actions)
  • internal/exchange/services/access/access.go — envelope-type dispatch + evaluateODRLDoc (reuses the legacy path's assignee and signature checks)
  • internal/exchange/services/ipfs_service.go — accept the new envelope type
  • docs/odrl-profile-v1.md, docs/odrl-profile-v1.schema.json — profile spec, example document, JSON Schema

Testing

14 table-driven cases in odrl_test.go against ValidateAccessViaSourceDoc: happy path, subset grants, expired / not-yet-effective / unbounded agreements, assignee/target/signature mismatches, and strictness rejections (unknown action, prohibition present, wrong @type, tampered @context, unsupported operator, event-filter refusal). Full build and test suite pass.

🤖 Generated with Claude Code

https://claude.ai/code/session_01DNqJMcyn2p3oKosj3KFdQR

Alongside legacy SACDData documents, the exchange now accepts CloudEvents
of type dimo.sacd.odrl whose data is a W3C ODRL 2.2 Agreement restricted
to DIMO profile v1 (https://ns.dimo.co/odrl/v1). Dispatch is on the
CloudEvent envelope type; legacy documents are untouched.

Profile v1 covers exactly the capabilities of legacy permission grants:
assigner (grantor), assignee (grantee), target (asset DID), a validity
period as conjunctive dateTime constraints, and named permissions using
the existing privilege:* vocabulary. The minted claims are identical to
those from an equivalent legacy document, so downstream consumers (dq)
need no changes. CloudEvent-scoped access is not in profile v1 and such
requests are refused when backed by an ODRL grant.

The evaluator is fail-closed: unknown fields (prohibitions, duties,
refinements), unknown actions, unsupported operators, and any @context
other than the fixed canonical forms reject the document in full. No
JSON-LD processing is ever performed, so a hostile @context cannot remap
term meanings under the grantor's signature.

See docs/odrl-profile-v1.md and docs/odrl-profile-v1.schema.json.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DNqJMcyn2p3oKosj3KFdQR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant