#Shares & Grants
When you build an app or workflow another tenant installs, controlling what those consumers can see and do is part of authoring it. Helm separates two independent levers, and you usually reason about them separately:
| Tier | Lever | Scope | Actions | Where you set it |
|---|---|---|---|---|
| 1 | Share | cross-tenant | read only | owner-side, next to the resource: /definition/*/{id}/shares, /entity/.../shares |
| 2 | Grant | intra-tenant principal | any of CRUD (intra) / read (cross) | /access/grants |
A manifest bundles many shares into one two-party offer (concept below); the walkthroughs live in the persona guides.
Authenticate with a Personal Access Token (HTTP Basic auth) — enter it once in the Authorize bar above and every Try it below uses it.
#Tier 1 — Shares (cross-tenant, read-only)
A share is how a tenant that owns a resource (an entity type, a workflow
definition, an app spec, …) declares that a specific grantee tenant may
read it. That's the whole contract — shares are read-only by design:
- ✅ Makes a resource's existence + shape visible to another tenant.
- ✅ Lets the grantee use a shared definition (e.g. activate a shared app spec in their own tenant — the activation is theirs).
- ❌ Never lets the grantee write to the owner's data.
- ❌ Never materializes the owner's data inside the grantee tenant.
- ❌ Never lets the grantee re-share onward.
Wanting
create/updateon a share is a sign you need a different lever: cross-tenant writes are the consumer acting on its own rows of a shared type, or a workflow that runs in the owner's tenant under an owner-controlled policy.
#Entity type shares vs entity (data) shares
For entities, two share kinds are distinct and independent:
- An entity-type share conveys catalog + schema visibility — "this type exists, here's its shape". It never reveals the owner's rows.
- An entity (data) share conveys row visibility — "see my rows". It requires a parent entity-type share.
This is what lets you share a type (so a partner can store their own rows of it) without exposing your rows.
POST/entity/entity-types/{id}/sharesShare a type's definition (cross-tenant, read-only)API docs ↗Try it
POST/entity/entity-types/{id}/data-sharesShare a type's rows (requires the definition share)API docs ↗Try it
The same primitive mounts next to every shareable resource — standalone JSON
schemas at /schema/schemas/{id}/shares, relationship rules at
/entity/relationship-rules/{id}/shares, and definitions at
/definition/{workflows,jobs,specs}/{id}/shares.
#Tier 2 — Grants (intra-tenant authorization)
A grant authorizes a specific principal — a user, a team, or a
policy — to act on a resource, optionally narrowed by an ABAC
attribute_filter.
- Intra-tenant grant (you own the resource):
actionsmay be any subset ofcreate/read/update/delete. - Cross-tenant grant (the resource is another tenant's):
actionsis constrained to["read"], and a matching active share must also exist.
Jobs are the exception. A job read follows the binding that pins it, not a grant — an app spec's
policiesblock may not grantjob_definitionat all, because a hand-written grant would only widen access beyond the jobs the app actually runs.
POST/access/grantsGrant a principal actions on a resourceAPI docs ↗Try it
#Combining the tiers
Within one tenant, a grant is all you need. For a cross-tenant data read you need both — a tier-1 share (owner → consumer) and a tier-2 grant (consumer → their principal):
tier-1 share (owner → consumer) tier-2 grant (consumer → principal)
A ──(rows of type X visible to tenant B)──► B ──(user u may read type X)──► user u
Remove the share and the cross-tenant read stops on the next request; remove the grant and the principal loses access while the share remains.
#Manifests — the bundle concept
Sharing one resource at a time doesn't scale to provisioning a whole app or workflow package. A manifest is a named bundle of shares offered with two-party consent:
- The owner publishes the manifest to a specific grantee tenant — an offer; nothing materialises yet.
- The grantee subscribes (accepts). Only now does each item in the bundle become a read-only share inside their tenant.
Either side can pull out unilaterally — the owner rescinds the publication, or the grantee unsubscribes — and the shares disappear immediately. Every share a manifest produces is read-only, like any share.
App specs and workflow definitions derive their manifest automatically from the
shares block the author declares, and the consumer's activation is the
subscription. The walkthroughs live in the persona guides:
Share Workflows & Apps (authoring side, including
standalone manifests) and
Activate Shared Workflows & Apps (consumer side).
#See also
Share Workflows & Apps and Activate Shared Workflows & Apps walk the two personas end to end; Provisioning covers the tenant-admin surface (users, tokens, policies); the Canonical Example shows a tier-1 share + tier-2 grant end to end.