ServiceUserRole
A ServiceUserRole is a bundle of permissions you grant to an end-user who signed up for your product, that is, a ServiceUser. It holds in one resource what they can do (read, create, edit, delete) to Content Types, Content, and Media, whether they can execute a Script, along with filters that narrow the scope, such as only certain Content Types or only what they created. The actions you can use differ from map to map (see the Permission maps table below). These permissions apply to the ACMA/ACDA that the ServiceUser calls.
It sits in a different place from a SpaceRole. A SpaceRole is a bundle of permissions for a Weegloo User (a content studio user) and applies to CMA/CDA, while a ServiceUserRole is a bundle of permissions for a ServiceUser who signed up for your product and applies to ACMA/ACDA. A ServiceUserRole you create applies to nobody on its own. You grant it by setting it as the default role (defaultRole) on a ServiceLogin, or by binding it to the roleOverride of a ServiceUser.
Resource structure
The following is the single-read response for the ServiceUserRole "Buyer". Together with sys (system properties), it has the body properties that define permissions: contentType, content, media, and script.
{
"sys": {
"id": "3trmXRLXeZN2RTHvVj3hFDN5546vbp",
"type": "ServiceUserRole",
"space": { "sys": { "id": "tcq4V2Xb", "type": "Refer", "targetType": "Space" } },
"createdBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
"createdAt": "2026-06-18T12:40:36.944Z",
"updatedBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
"updatedAt": "2026-06-18T12:40:36.944Z",
"version": 1
},
"name": "Buyer",
"description": "Member who can read published products",
"contentType": { "All": { "Allow": [] } },
"content": {
"Read": {
"Allow": [
{ "contentType": { "sys": { "id": "3trmXRM3RqbgSnifyg7PAmlxvX4fGY", "type": "Refer", "targetType": "ContentType" } } }
]
}
},
"media": { "All": { "Allow": [] } },
"script": {}
}Key properties:
contentType: The permission map for Content Types themselves (the schema). A ServiceUser only reads the form, so you setReadalone.content: The permission map for Content (the content data). The example above limits the role to reading only the Content of one specific Content Type.media: The permission map for Media (files and images).script: The permission map for Script (declarative backend endpoints). A ServiceUser only executes (Execute) a Script.
Unlike a SpaceRole, a ServiceUserRole has no settings to hold access to Space settings, because a ServiceUser does not work with Space settings. It also has no sys.isLocked to mark whether the role is provided by default.
System properties (sys)
Every ServiceUserRole carries common system properties in the sys object. space, createdBy, and updatedBy are in the Refer shape ({ "sys": { "id", "type": "Refer", "targetType" } }).
| Property | Type | Description |
|---|---|---|
id | string | Unique resource identifier. |
type | string | Resource kind. For a ServiceUserRole this is always "ServiceUserRole". |
space | Refer<Space> | The Space this ServiceUserRole belongs to. |
createdBy | Refer<User> | The user who created it. |
createdAt | string (date-time) | Creation time. |
updatedBy | Refer<User> | The user who last updated it. |
updatedAt | string (date-time) | Last update time. |
version | integer (≥1) | Resource version. It increases by 1 with every change. |
A ServiceUserRole is a settings resource with no publishing concept. So unlike Content and Media, its sys has no publish, archive, or status, only version. The version increases each time you update the ServiceUserRole. Unlike a SpaceRole, it also has no sys.isLocked.
Permission maps: contentType, content, media
contentType, content, media, and script are each a map keyed by action. The value of each action is an object holding Allow and Deny arrays of rules. The structure of the maps is the same as a SpaceRole, but the actions you can use differ from map to map and are narrower than on a SpaceRole.
| Permission map | Actions you can use |
|---|---|
contentType | All, Read |
content | All, Create, Read, Edit, Delete |
media | All, Create, Read, Delete |
script | All, Execute |
All refers at once to every action you can use in that map. If you put in an action the table does not list, saving the role is rejected. None of the maps carry the publishing actions (Publish, Unpublish, Archive, Unarchive) because Content and Media a member creates are published the moment they are created (see ACMA).
There is no action called Save. The permission to modify is Edit, and Save is the name of an event a Webhook subscribes to.
"content": {
"Read": { "Allow": [ /* rule */ ], "Deny": [ /* rule */ ] },
"Edit": { "Allow": [ /* rule */ ] }
}Each rule object has optional filters that narrow the permission's scope.
self: Limits the target the rule applies to the resource itself, one single resource. In thecontentTypemap it means one specific Content Type; in thescriptmap, one specific Script.contentType: Limits to the Content Type the Content belongs to. You put in aReferthat points to a Content Type.createdBy: Limits to only resources created by a specific user. Put a specific user id insys.idto limit to what that person created, or the reserved value:selfto limit to "only what the ServiceUser making the current call created".tag: Limits to only resources carrying a specific Tag.
Which filter is valid in which permission map is the same as for a SpaceRole (the contentType map names its target with self, and the content map with contentType), and putting in a filter that does not fit makes saving the role fail. The per-map table is in Permission maps on SpaceRole.
To apply a
createdByfilter (including:self) on ACDA, the target Content Type'spublishWithAuthormust betrue. ACDA evaluates this filter against thesys.createdByof the publish snapshot, so ifpublishWithAuthoris left at its defaultfalsethe snapshot has no author: anAllowrule matches nothing (a member receives their own resources as an empty result), and aDenyrule filters out no one. ACMA (management), on the other hand, evaluates against thesys.createdByof the draft and is therefore independent of this setting, so the same rule may work on ACMA yet break on ACDA.publishWithAuthormust be turned on before members start posting, and it is not retroactive. See thepublishWithAuthordescription in Content Type.
An empty Allow array [] means the action is allowed across the entire kind. Because the filter is empty there is nothing to filter out, so the action is open to all resources.
Unlike a SpaceRole, a ServiceUserRole has no settings. The permission maps are the four: contentType, content, media, and script. For how to write the permission maps, including the filter keys and the meaning of :self, see also the explanation in SpaceRole, which uses the same structure. Note, however, that the actions you can use are the ones in the table above, and they differ from a SpaceRole. Regular member roles and administrator roles, just below, shows an example that uses :self to narrow editing to only the Content the caller created.
The filter keys (
self,contentType,createdBy,tag) and the meaning of:selffollow the permission-rule definition in SpaceRole. For a ServiceUserRole,:selfresolves to only what the current ServiceUser created. The action list does not follow SpaceRole; it follows the table above.
Regular member roles and administrator roles
Whether a member can handle other members' resources is decided by the rule's createdBy filter. For one and the same action, putting :self in createdBy makes that action target only what the calling member created, while leaving createdBy out makes it target what other members created as well.
The role you give to regular members limits Edit and Delete with :self.
"content": {
"Edit": {
"Allow": [
{
"contentType": { "sys": { "id": "3trmXRM3RqbgSnifyg7PAmlxvX4fGY", "type": "Refer", "targetType": "ContentType" } },
"createdBy": { "sys": { "id": ":self", "type": "Refer", "targetType": "User" } }
}
]
},
"Delete": {
"Allow": [
{
"contentType": { "sys": { "id": "3trmXRM3RqbgSnifyg7PAmlxvX4fGY", "type": "Refer", "targetType": "ContentType" } },
"createdBy": { "sys": { "id": ":self", "type": "Refer", "targetType": "User" } }
}
]
}
}For a member who is to act as an administrator, build a separate role that drops createdBy from the same action. The role below opens only deleting to other members' items and leaves editing limited to the member's own.
"content": {
"Edit": {
"Allow": [
{
"contentType": { "sys": { "id": "3trmXRM3RqbgSnifyg7PAmlxvX4fGY", "type": "Refer", "targetType": "ContentType" } },
"createdBy": { "sys": { "id": ":self", "type": "Refer", "targetType": "User" } }
}
]
},
"Delete": {
"Allow": [
{ "contentType": { "sys": { "id": "3trmXRM3RqbgSnifyg7PAmlxvX4fGY", "type": "Refer", "targetType": "ContentType" } } }
]
}
}You apply a role built this way to one member alone by setting it on that ServiceUser's roleOverride. If you leave ServiceLogin's defaultRole as the regular member role, a member who newly signs up does not receive the administrator role.
Media works the same way. Dropping createdBy from an action in the media map makes it target files other members uploaded as well. Note that the contentType filter is used only in the content map, so do not put it in the media map.
script (Script permissions)
script is the permission map for Script; its structure is the same as content and media. However, the only thing a ServiceUser can do to a Script is execute it (authoring, that is create/edit/delete, is CMA / Weegloo-User only). So the only actions you can use in a ServiceUserRole's script are the two All and Execute.
To let a signed-up member execute a Script:
"script": {
"Execute": { "Allow": [] }
}The rule filters you can use are two: self (one specific Script) and createdBy. contentType and tag are axes that do not attach to Script, so putting them in makes saving the role fail. To let a member execute one specific Script and nothing else, put a self rule pointing at that Script in the Allow of Execute.
"script": {
"Execute": {
"Allow": [
{ "self": { "sys": { "id": "3trmXRMZcTAjDnphewjj1AaxYcaxlK", "type": "Refer", "targetType": "Script" } } }
]
}
}The structure of Script itself and its execute endpoint are covered in Script resource and endpoints; the full action list is covered in the script permission on SpaceRole.
Errors
These are the codes you meet when working with a ServiceUserRole. For codes that are common to every resource, see common errors.
| Code | Condition |
|---|---|
WGL400020 | A rule put a filter into a permission map that cannot use that filter, so saving the ServiceUserRole was rejected. Putting contentType or tag into the script map is one such case. |
API
The base URL for all endpoints below is https://cma.weegloo.com/v1, and a Bearer token that authenticates against CMA is required in the Authorization header. Role updates (PUT, PATCH) must also send the X-Weegloo-Version header (the current resource's sys.version) for optimistic concurrency control. Create and delete do not have this header.
Related documents
- ServiceUser: The signed-up member who receives this role (
roleOverride). - ServiceLogin: Set a ServiceUserRole as the default role (
defaultRole). - SpaceRole: The permission bundle for Weegloo Users (same permission-map structure).
