Collaborators and resource grants¶
A collaborator is a principal who belongs to an organization with role
collaborator and reaches individual resources, not the organization. A
resource grant gives a principal one of three roles on one resource. The
design is in Organizations and Membership
and Authorization.
The model¶
| Piece | Rule |
|---|---|
| Collaborator membership | Role collaborator: no view, edit or manage on the organization, only list so an application can show the organization in a switcher. No application roles |
| Resource roles | viewer (view), contributor (view, edit), maintainer (view, edit, manage); each includes the ones below. The names are reserved for every application |
| Resource | {app}_{type} (a collaborator-able definition of a registered application) plus the application's own identifier, 1 to 1024 characters of letters, digits and /_\|-=+ |
| Ownership | A resource belongs to one organization; grants naming another organization for an already-granted resource are refused |
An application declares which of its resource types accept collaborators by
giving the definition the three relations viewer, contributor and
maintainer in its vocabulary's schema fragment
(authz.ResourceRoleFragment renders it); a vocabulary with no fragment
accepts any type of its application.
Granting and revoking¶
There is no HTTP API for grants: the application checks that its caller may
manage the resource, then calls the service.
res, err := mode.New(ctx, cfg.Authz, mode.Deps{DB: db, Registry: registry})
ref := authz.ResourceRef{Type: "myapp_project", ID: projectID, OrganizationID: orgID}
err = res.Provider.GrantResourceRole(ctx, principalID, ref, authz.ResourceRoleContributor, callerID)
err = res.Provider.RevokeResourceRole(ctx, principalID, ref)
grants, err := res.Provider.ListResourceGrants(ctx, ref)
set, err := res.Provider.ListResources(ctx, principalID, "myapp_project", authz.PermResourceView)
// where org_id IN set.OrganizationIDs OR id IN set.IDs
Granting to a principal with no membership creates a collaborator membership in the same transaction; granting again replaces the role. Revoking the last grant of a collaborator removes the membership. An existing member keeps their role and gains the grant. The same grant can be made by accepting a resource-targeted invite.
Removing a member from the organization deletes their grants with the membership. Agents and managed principals are granted through the same operations, which confines them to the granted resources.
Checking access¶
Both modes answer Can(principal, view|edit|manage, resource) with the same
result. The role-based provider needs rbac.WithResourceGrants(svc), which
mode.New sets. Access that comes from an organization role (an admin's
manage through the organization) is unaffected by grants.
Permissions¶
The grant service does no authorization of its own. The application should
require manage on the resource for resource grants, and invite_member for
invites.
Errors¶
| Error | Meaning |
|---|---|
authz.ErrInvalidResourceRole |
The role is not viewer, contributor or maintainer |
authz.ErrInvalidResource |
The reference is malformed, or the type is not a collaborator-able type of a registered application |
authz.ErrGrantNotFound |
Revoking a grant the principal does not hold |
authz.ErrResourceOrganizationMismatch |
The resource already has grants in another organization |
resourcegrant.ErrInactiveMembership |
The principal has a deactivated membership that is not a collaborator's; reactivate or remove it first |
organization.ErrPersonalOrganization |
Collaborator invites without a target are refused for a personal organization |
Lowering or removing a grant records an access change (grant_reduced, plus
membership_removed when it was the last), so relying parties with a
revocation cache refuse earlier tokens; see
Access-change invalidation.