Skip to main content

Model Grant kinds

Building a connector, step 4 of 10. Previous: Model entities.

A Grant kind is one kind of access the system has: group membership, a role assignment, a permission on a project. For each one you declare who can hold it, what it is on, which details distinguish one assignment from another, how Sync finds it, how access flows through it, and whether Owlie may add and remove it. The concepts are explained in the unified access model; this page is the procedure.

1. List every kind of access​

List every access relationship the API exposes, whether or not you expect to model it: group, team, role, licence, permission set, application, workspace, project, organization and channel membership or assignment, admin roles, and roles scoped to a project, workspace or organization. Include operations that are Grant writes in disguise, such as "add collaborator" or "promote to admin". You will reject some of these in the next step; keep them on the list with the reason.

2. Map each one​

For each kind of access you keep, decide:

  • Principal and target. source is the entity that normally holds the Grant (usually the account); principal_types lists every entity that can hold it, when a group can hold it too, and must include source. target is the entity the access is on.
  • Qualifiers: the details the system records with the assignment, such as a role or a permission level. Give each one a name, a schema (string, enum, boolean, number, entity_ref and others), whether it is required, and whether it is a slot_key: does this value distinguish assignments that can exist side by side? An entity_ref qualifier names the entity its value points to. An enum lists its values. A string can have a pattern and examples; anchor a pattern that guards a URL path segment with ^ and $.
  • Discovery: discovered_via is the entity whose listing returns the relationship, and fetch_mode says how. per-entity means Sync calls a relationship listing once per record of that entity (list the members of each group). embedded means the relationship arrives on the entity's own records (each user record carries its department).
  • Inheritance: membership, hierarchy, propagates and via_membership, decided with the table below. derived marks a read-only Grant kind your connector computes itself.

Deciding slots: if a user can have one permission per folder and changing it replaces the old one, the permission is a qualifier but not a slot key. If a user can hold several roles in the same application, each removable on its own, the role is a slot key.

Membership or hierarchy​

Both mean "A is inside B". They differ in which direction access flows. With membership, A holds every Grant that B holds as a principal. With hierarchy, every propagating Grant on B also covers A. Decide from your own model, not from the word the system uses. The rows below are Grant kinds of Owlie's Google Workspace, Microsoft Entra ID and Workday connectors:

RelationshipDoes A inherit Grants that B holds?Do propagating Grants on B cover A?Flag
user in a Google Workspace groupyes, the admin roles assigned to the groupnomembership
user holding a Microsoft Entra ID directory roleyes, the permissions the role holdsnomembership
child organizational unit in its parent (Google)noyes, an admin role scoped to the parent unit, which propagates, covers ithierarchy
worker in a Workday organizationno, the organization holds no Grantnoneither

If neither column is "yes", the Grant kind has neither flag. A hierarchy kind must form a tree: one parent per entity. via_membership sets how far membership reaches: transitive (through nested groups, the default), direct, or none.

3. Decide what Owlie may write​

A Grant kind can be writable: true only when all of these hold:

  • the API has both an add call and a remove call that your connector's credentials can use;
  • Sync can list the Grants, so Owlie can see the result (a write Owlie cannot observe is a custom operation, not a Grant kind);
  • you know whether an add replaces an existing assignment or sits beside it;
  • the vendor documents what it answers for "already there" on add and "not there" on remove. Your connector reports those answers to Owlie, as Grant writes explains.

Owlie also refuses a writable Grant kind in a connector whose provides does not include provision, and a Grant kind that is both derived and writable.

Owlie's policies assign Grants to accounts. A Grant kind whose principal is a group is still worth syncing and reviewing, but rarely worth making writable.

4. Record the design​

Keep one table in your connector's README.md, one row per kind of access, rejected ones included:

Kind of accessAPI calls (list / add / remove, with links)Grant kindPrincipal → targetQualifiersDiscoveryFlagsWritable"Already there" and "not there" answersScopes or roles neededStatus and reason

A worked example​

Take a fictional product, Fieldnote, that lets a user hold a role inside a specific organization, and the same user can hold the same role in another organization. The Grant kind puts the organization in a qualifier that is a slot key, so the two assignments are separate Grants:

{
"key": "organization_role",
"source": "user",
"principal_types": ["user"],
"target": "role",
"discovered_via": "organization",
"fetch_mode": "per-entity",
"writable": true,
"qualifiers": [
{
"name": "organization",
"schema": "entity_ref",
"entity": "organization",
"required": true,
"slot_key": true,
"source": "attrs.organization"
}
]
}

Sync lists each organization's members with their roles and emits one relationship per member role. For member usr_alice holding role_viewer in org_A, the relationship names user usr_alice, role role_viewer, and carries { "organization": "org_A" }, which becomes the qualifier.

Every Grant kind and qualifier field is in Connector manifest.

Rules that keep the model honest​

  • Keep state out of qualifiers. Expiry dates, justifications and who made a change are not part of the assignment. An expiry the system itself holds is observed state, not a qualifier.
  • Never change what a published name means. A qualifier whose meaning changes gets a new name. Changing a Grant kind's principals, target or flags in a published version is a breaking change.
  • Every writable Grant kind needs both its add and its remove, and a read-only one has neither. Owlie refuses a connector that breaks this rule.

Next: Decide what not to govern