Skip to content

Canvas sharing: grant read access to other users (snapshot + live modes) #6

Description

@Weegy

Summary

A canvas today is strictly private to the session that produced it: every DataRef token is HMAC-bound to tenantId ‖ userId ‖ canvasSessionId, and there is no concept of a second viewer. Users should be able to share a canvas with other users — at minimum within the same tenant — so that a composed view (report table, chart dashboard, triage list) has value beyond the one conversation that created it.

Motivation

  • Canvases are the product's unit of output. Right now the only way to "share" one is a screenshot, which throws away interactivity, freshness, and provenance.
  • Combined with deterministic refresh (see the refresh issue), a shared canvas becomes a lightweight live report without any extra authoring tool.

Proposed scope (v1)

  1. Share = grant, not copy. Sharing canvas X with user B creates a grant (canvasId, granteeUserId, mode), not a duplicated tree. The owner keeps one canonical canvas; revocation removes access.
  2. Two modes:
    • Snapshot (read-only): grantee sees the tree at the shared revision. No data re-resolution under the grantee's identity; safest default.
    • Live (read-only): grantee's client may trigger refresh; Tier 2 re-mints DataRef tokens under the grantee's identity, so row-level / record-level permissions of the underlying source apply to them. If the grantee lacks access to the underlying data, the affected primitives render an access-denied state rather than leaking the owner's view.
  3. No co-editing in v1. A shared canvas is not a collaborative session — the grantee cannot run chat turns against it. "Fork to my own session" (grantee gets an editable copy seeded from the snapshot) is the natural escape hatch and can be a fast follow.
  4. Tenant boundary is hard. Cross-tenant sharing is out of scope for v1.

Security considerations (must-haves, not nice-to-haves)

  • DataRef HMAC tokens are user-scoped by design — never hand the owner's tokens to a grantee. Live mode always re-mints per grantee; snapshot mode ships resolved data, not tokens.
  • Audit trail: who shared what with whom, when, and which mode.
  • Grants must survive the owner's session ending but die with the owner's account / tenant membership.

Open questions

  • Where do grants live — Tier 2 persistence is currently session-oriented; sharing forces a durable canvas store (canvas lifetime > session lifetime). That is the actual size of this feature.
  • Share UX: from the canvas chrome (share affordance next to refresh)? Link-based with in-app acceptance, or directory-picker of tenant users?
  • Does a snapshot share embed image/media payloads or re-sign asset references with grantee-scoped expiry?

Affected areas

  • Tier 2: durable canvas store, grant model, grantee-scoped token minting, refresh-under-grantee path
  • Protocol: a read-only attach flow for a grantee client (subset of the existing snapshot/stream phase)
  • Tier 1 host app: share affordance + grant management UI, read-only canvas rendering mode (no turn input, no Class-B local ops)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions