Share resources
Workflows, plans, vaults. Grant access to specific users, teams, or share groups inside your org.
A resource in Viewport is any object that can be shared: a workflow definition, a plan, a context vault, a workflow run, an inbox item. Everything that can be shared goes through the same ACL system. A polymorphic registry of grants where the subject is a user, a team, or a share group.
The model
Every shareable resource has a row in resources and zero-or-more rows in resource_acl_entries:
resources
id ulid
workspace_id ← the tenant
resource_type workflow | plan | vault | run | inbox | ...
resource_ulid pointer to the underlying record
owner_user_id who created it
visibility private | workspace | restricted
resource_acl_entries
resource_id → resources.id
subject_type user | team | share_group
subject_id → users.id | teams.id | share_groups.id
role owner | admin | reviewer | viewerSharing creates resource_acl_entries. Unsharing deletes them. There's no separate "permissions" surface. The ACL table is the answer.
Visibility modes
| Mode | Who sees it |
|---|---|
| Private | Only the owner + people explicitly granted via ACL entries. |
| Workspace | Everyone in the workspace can view (read-only). ACL entries can grant higher roles. |
| Restricted | Specific principals only. Like Private, but the UI signals there's a non-obvious access list. Audited every time someone reads. |
Share a workflow
- Open the workflow detail page.
- Click Share.
- In the modal, search for a user, team, or share group inside this org.
- Pick a role for them.
- Save.
Behind the scenes:
- A
resource_acl_entriesrow is created. - The recipient sees the workflow in their list immediately.
- An audit event
workflow.sharedis written with the actor, the subject, and the role.
Share a plan or vault or context
Same modal. Same shape. Plans can be shared for review. Vaults can be shared so a team's agents can read its entries. The principal list is org-scoped. You can't share with a user outside the org.
Share groups (ad-hoc audiences)
Sometimes you want to share with "these 5 specific people" without making a team. That's a share group: a workspace-local list of principals that exists only to be the subject of an ACL entry.
Create one inline from the share modal: + New share group. Name it. Add people. Use it as a subject.
Share groups are also workspace-scoped. They cannot include users outside the org, and a share group from one org cannot grant access in another.
Unshare
Same modal. Remove the principal. The ACL entry is deleted; the resource is no longer visible to that principal (assuming they had no other grant path).
Unshares write an audit event.
What CAN'T be shared across orgs
Hard wall. The platform refuses with a 422 if you try to write an ACL entry where:
team.workspace_id != resource.workspace_idshare_group.workspace_id != resource.workspace_id- The subject user has no membership row in
resource.workspace_id
See Concepts: Trust and privacy for the invariants.
Resource roles
The role on an ACL entry maps to what the principal can do:
| Role | View | Comment | Edit | Approve | Share with others | Delete |
|---|---|---|---|---|---|---|
| viewer | ✓ | |||||
| reviewer | ✓ | ✓ | ✓ | |||
| editor | ✓ | ✓ | ✓ | ✓ | ||
| admin | ✓ | ✓ | ✓ | ✓ | ✓ | |
| owner | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
Each resource type has slight variations (a workflow's "approve" is "approve a plan generated by this workflow," etc.). Hover the role chips in the UI for resource-specific definitions.
Bulk share
To grant multiple principals at once, use the API:
POST /api/resources/{workspace}/workflows/{workflow_id}/share/bulk
Content-Type: application/json
{
"grants": [
{ "subject_type": "team", "subject_id": "t_platform", "role": "reviewer" },
{ "subject_type": "share_group", "subject_id": "sg_…", "role": "viewer" }
]
}See Reference: API.
Where to go next
- Approval policies. How shares affect inbox routing.
- Concepts: Inbox. The routing model.
- Audit log. What every share writes.