Grant a principal access to an evidence asset
Adds one ownership row (migration 0122) for a user handle or an installed pack. Idempotent over the live (asset, ownerKind, ownerId) triple: a repeat returns the standing grant with created: false. ownerKind: "system" is REFUSED (400) — a system grant never dies with a user, so a client could pin content past GDPR erasure with it; system ownership stays a write-seam property of registration. The grantee handle is never checked for existence (a grant to an unknown handle is inert), so this is no user-enumeration oracle. There is no grant expiry: 0122 has no such column, an expiresAt field is rejected rather than silently ignored, and the asset’s own retainUntil — echoed here — is the horizon, since retention purges asset and grants together. Acting requires the caller to pass the raw-read gateway’s own fences over the asset: tenant (the lookup runs inside the authenticated tenant), liveness (not tombstoned, quarantine clean-or-absent, retention horizon not already past), OWNERSHIP (at least one live grant exists, and a user-bound key must hold the end user’s own live user grant), and the media-PII polarity (unclassified blocked, [] open, classified needs brain:read_media) — nobody shares what they cannot read. The byte-delivery steps are deliberately NOT applied (no bytes move here), so a metadata-only external asset is shareable; every serve still re-runs the full gateway ladder against the grantee. Any denial is the same bare 404 — unknown, foreign and forbidden are indistinguishable. 404 until EVIDENCE_GRANTS_API_ENABLED=1 AND EVIDENCE_SUBSTRATE_ENABLED=1 (raised in a guard, before body validation could reveal the route). Source: src/evidence/evidence-grants.controller.ts.
Required scope: brain:write.
Request
- Base URL: https://brain.inite.ai
- URL: https://brain.inite.ai/v1/evidence/{assetId}/grants
- Auth: HTTP bearer
Path parameters
evidence_asset record id.
Request body
Response
The live grant (created now, or the standing one).
Changes
No recorded changes to this operation across all 1 revision of this API.