SpaceRole

A SpaceRole is a bundle of permissions you grant to a member of a Space. It holds in one resource what a member can do (read, create, edit, delete, publish) to Content Types, Content, and Media, whether they can execute and manage Script, and whether they can reach the Space settings. Filters that narrow the scope of a permission (to only certain Content Types, only what the member created, and so on) are also defined inside the SpaceRole.

A SpaceRole you create applies to nobody on its own. You grant it to a member by putting a Refer to this SpaceRole into the roles of a Space Membership. One member can hold several SpaceRoles at once. A DeliveryAccessToken is also bound to a single least-privilege SpaceRole, which determines the scope that token can deliver.

Resource structure

The following is the single-read response for the SpaceRole "Product Read-only". Together with sys (system properties), it has the body properties that define permissions: contentType, content, media, settings, and script.

{
  "sys": {
    "id": "3trmXRM3RqbgSnifyg7PLzmhWFANg9",
    "type": "SpaceRole",
    "space": { "sys": { "id": "tcq4V2Xb", "type": "Refer", "targetType": "Space" } },
    "createdBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
    "createdAt": "2026-06-16T09:53:16.617Z",
    "updatedBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
    "updatedAt": "2026-06-16T09:53:16.617Z",
    "isLocked": false,
    "version": 1
  },
  "name": "Product Read-only",
  "contentType": { "All": { "Allow": [] } },
  "content": {
    "Read": {
      "Allow": [
        { "contentType": { "sys": { "id": "3trmXRM3RqbgSnifyg7PAmlxvX4fGY", "type": "Refer", "targetType": "ContentType" } } }
      ]
    }
  },
  "media": { "All": { "Allow": [] } },
  "settings": [],
  "script": {}
}

Key properties:

  • contentType: The permission map for Content Types themselves (the schema). It defines, per action, the permission to read, create, edit, delete, and publish a Content Type.
  • 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 that your frontend calls). Sets execution (Execute) and management (create/read/edit/delete) per action.
  • settings: A string array that defines access to Space settings. It is not a permission map: it lists action names directly. Full access is ["SETTING_ALL"], granting no settings access at all is [], and you can also pick only the settings you need (see settings below).
  • isLocked: When true, this is a role Weegloo provides by default (for example, Administrator), so it cannot be edited or deleted.

System properties (sys)

Every SpaceRole carries common system properties in the sys object. space, createdBy, and updatedBy are in the Refer shape ({ "sys": { "id", "type": "Refer", "targetType" } }).

PropertyTypeDescription
idstringUnique resource identifier.
typestringResource kind. For a SpaceRole this is always "SpaceRole".
spaceRefer<Space>The Space this SpaceRole belongs to.
createdByRefer<User>The user who created it.
createdAtstring (date-time)Creation time.
updatedByRefer<User>The user who last updated it.
updatedAtstring (date-time)Last update time.
isLockedbooleanWhen true, this is a default-provided role and cannot be edited or deleted. Roles you create yourself are false.
versioninteger (≥1)Resource version. It increases by 1 with every change.

A SpaceRole 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 SpaceRole.

Permission maps: contentType, content, media

contentType, content, and media are each a map keyed by action. The actions you can use are Create, Read, Edit, Delete, Publish, Unpublish, Archive, and Unarchive, plus All, which refers to every action at once. There is no action called Save. The permission to modify is Edit, and Save is the name of an event a Webhook subscribes to. The value of each action is an object holding Allow and Deny arrays of rules.

"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. You put in a Refer that points to that resource. In the contentType map it means one specific Content Type; in the script map, one specific Script.
  • contentType: Limits to the Content Type the Content belongs to. You put in a Refer that points to a Content Type.
  • createdBy: Limits to only resources created by a specific user. Put a specific user id in sys.id to limit to what that person created, or the reserved value :self to limit to "only what the user making the current call created".
  • tag: Limits to only resources carrying a specific Tag.

Which filter carries meaning in which permission map is fixed. If you put in a filter that does not fit, saving the role is rejected. Were it quietly ignored, a rule you believed you had narrowed would become a full allow.

Permission mapFilters you can useFilters that make the save fail
contentTypeself (that Content Type itself), createdBycontentType
contentcontentType (the kind the Content belongs to), createdBy, tagself
mediacreatedBy, tagself
scriptself (that Script itself), createdBycontentType, tag
  • In the contentType map you name the target with self, not with contentType. What you narrow there is the Content Type itself. The contentType filter means "the kind this resource refers to", so it fits the content map only.
  • A filter that narrows along an axis the resource does not have (tag on a Content Type, contentType on Media) is not blocked at save time, but the rule is not evaluated the way you intended. Do not use it.

To evaluate a createdBy filter (including :self) on CDA (delivery), the target Content Type's publishWithAuthor must be true. CDA evaluates this filter against the sys.createdBy of the publish snapshot, so if publishWithAuthor is left at its default false the snapshot has no author: an Allow rule matches nothing, and a Deny rule filters out no one. CMA (management) evaluates against the sys.createdBy of the draft and is therefore independent of this setting. Because publishWithAuthor is not retroactive, turn it on before publishing content, and republish any Content that has already been published. See the publishWithAuthor description 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.

An empty Deny array [] works the other way around. It does not mean "nothing is denied": it denies the entire kind and blocks that action completely. It stays blocked even if you write an Allow alongside it. Leaving [] to mean "there is nothing to deny" does the exact opposite, so when you want to deny nothing, leave the Deny key out entirely.

Example 1: Administrator (full permissions, provided by default)

The Administrator role gives an empty Allow to the All action of contentType, content, media, and script to allow everything, and gives ["SETTING_ALL"] to settings to reach all Space settings. Because Weegloo provides this role by default, its sys.isLocked is true and it cannot be edited or deleted.

{
  "sys": {
    "id": "3trmXRM3RqbgSnifyg7PAlm4FWTPQ8",
    "type": "SpaceRole",
    "space": { "sys": { "id": "tcq4V2Xb", "type": "Refer", "targetType": "Space" } },
    "createdBy": { "sys": { "id": "_", "type": "Refer", "targetType": "User" } },
    "createdAt": "2026-06-14T14:56:04.737Z",
    "updatedBy": { "sys": { "id": "_", "type": "Refer", "targetType": "User" } },
    "updatedAt": "2026-06-14T14:56:04.737Z",
    "isLocked": true,
    "version": 1
  },
  "name": "Administrator",
  "description": "Members of this role have full access to everything in this space.",
  "contentType": { "All": { "Allow": [] } },
  "content": { "All": { "Allow": [] } },
  "media": { "All": { "Allow": [] } },
  "settings": ["SETTING_ALL"],
  "script": { "All": { "Allow": [] } }
}

Example 2: Read-only (one specific Content Type)

This is an example of a least-privilege role you create yourself. It puts a rule only on the Read action of content, and limits that rule to one specific Content Type with the rule's contentType filter. The Content Type itself and Media are left open with All and an empty Allow, but for the content data only reading that one kind is possible. Because settings is [], it cannot reach Space settings. Bind this role to a DeliveryAccessToken and the delivery token will read only that scope. The JSON of this role is the same as "Product Read-only" in Resource structure above.

settings (Space settings access)

settings is not a permission map but a string array. It holds access to Space settings, and it has no Allow/Deny and no filters. The actions you put in the array are allowed, and the actions you leave out are not.

Full access is ["SETTING_ALL"], and you leave it [] to grant no access at all. When you need something in between, pick the actions below.

ActionWhat it gives access to
SETTING_GENERALThe Space itself (name, description, and so on)
SETTING_LOCALELocale
SETTING_WEBHOOKWebhook (including call history and status)
SETTING_APPMarket App installation
SETTING_TAGTag
SETTING_DELIVERY_ACCESS_TOKENDelivery Access Token
SETTING_SPACE_ACCESS_TOKENSpace Access Token
SETTING_USERSpace Membership (member assignment)
SETTING_ROLESpaceRole
SETTING_WEB_HOSTINGWeb Hosting and custom domains
SETTING_SERVICE_LOGINServiceLogin, ServiceUser, ServiceUserRole
SETTING_EMAIL_ACCOUNTThe mail sending account
SETTING_MONITORINGReading usage and metrics
SETTING_SCHEDULERScheduler and its execution records
SETTING_ALLAll of the above

The two kinds of token have separate actions. If you grant only SETTING_DELIVERY_ACCESS_TOKEN, the role can issue a read-only Delivery Access Token but cannot issue a Space Access Token, which can write as well.

The actions in settings are called only with a console login session or a Personal Access Token. A Space Access Token, a Delivery Access Token, or a ServiceUser token cannot call the APIs in this list, no matter which actions the role holds.

The action list of the permission maps (contentType, content, media, script), the filter keys (self, contentType, createdBy, tag), the meaning of :self, and which filter is valid in which map all follow the Permission maps: contentType, content, media section above.

script (Script permissions)

script is the permission map for Script (declarative backend endpoints that your frontend calls). Its structure is the same as content and media: actions as keys, with Allow/Deny rule arrays as values. The actions it uses are:

  • Create, Read, Edit, Delete: Create, read, update, and delete a Script resource.
  • Execute: Run a Script (call /execute). This action is unique to Script.
  • All: The umbrella action that includes all of the above.

Because a Script is not a resource you publish, publish actions such as Publish/Unpublish are not used. The rule filters you can use are self and createdBy.

  • self: Limits to a single specific Script. You put in a Refer that points to that Script (its targetType is Script).
  • createdBy: Limits by who created it (use :self for "only the Scripts the caller created").

contentType and tag are axes that do not attach to Script, so putting them in makes saving the role fail.

For example, to let someone execute any Script but read only the ones they created:

"script": {
  "Execute": { "Allow": [] },
  "Read": {
    "Allow": [
      { "createdBy": { "sys": { "id": ":self", "type": "Refer", "targetType": "User" } } }
    ]
  }
}

Narrowing with self produces the least privilege: the right to execute one Script and nothing else. When you give execute permission to an outside system such as a payment provider, this is how you open the one entry point that system will call and leave everything else closed.

"script": {
  "Execute": {
    "Allow": [
      { "self": { "sys": { "id": "3trmXRMZcTAjDnphewjj1AaxYcaxlK", "type": "Refer", "targetType": "Script" } } }
    ]
  }
}

Bind this role to a Space Access Token and that token executes only the one Script you named. Why you narrow it to a single execute permission, and the fact that running a Script borrows the author's permissions, are covered in Script execution semantics, limits, and security.

This script permission decides "can you execute and manage the Script resource." Separately, when you author a Script (create or edit it), at save time the author must actually hold the Content/Media action permissions that the Script's statements operate on; otherwise the save is rejected (see Script errors). See Script execution semantics, limits, and security for details.

Errors

These are the codes you meet when working with a SpaceRole. For codes that are common to every resource, see common errors.

CodeCondition
WGL400020The caller tried to save a SpaceRole whose rule carried a filter that has no meaning in that permission map.

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. Default-provided roles whose sys.isLocked is true cannot be edited or deleted.