Scope Catalog

UTMOS uses Casbin tenant-domain authorization. In this documentation, a “scope” maps to a Casbin object:action pair, not to the legacy string-scope model.

Open Platform Permissions

PermissionGrantsEndpoint
open:command:createAccept cloud-to-device commandsPOST /api/v1/open/downlink/commands
open:command:readQuery accepted commandsGET /api/v1/open/downlink/commands/{command_id}
open:object:createIssue upload or download presigned URLs for tenant-authorized objectsPOST /api/v1/open/objects/presign
open:object-config:createCreate tenant object credentials or resource policiesPOST /api/v1/open/objects/credentials, POST /api/v1/open/objects/resources
open:object-config:readRead tenant object storage configurationGET /api/v1/open/objects/credentials, GET /api/v1/open/objects/resources
open:object-config:updateUpdate or rotate tenant object storage configurationPUT /api/v1/open/objects/credentials/{credential_id}, PUT /api/v1/open/objects/resources/{resource_id}
open:callback:createCreate callback endpoints or subscriptionsPOST /api/v1/open/callbacks/endpoints, POST /api/v1/open/callbacks/endpoints/{endpoint_id}/subscriptions
open:callback:readRead callback endpoints or subscriptionsGET /api/v1/open/callbacks/endpoints
open:callback:updateUpdate or rotate callback endpointsPUT /api/v1/open/callbacks/endpoints/{endpoint_id}
open:callback:disableDelete callback subscriptionsDELETE /api/v1/open/callbacks/endpoints/{endpoint_id}/subscriptions/{subscription_id}
open:device-request:readRead device-to-cloud requestsGET /api/v1/open/device-requests, GET /api/v1/open/device-requests/{request_id}
open:device-request:createReply to device-to-cloud requestsPOST /api/v1/open/device-requests/{request_id}/reply

Suggested Roles

RoleUse caseCommon permissions
tenant_adminTenant administratorManage tenant credentials, ACL, object storage, callbacks, and NATS configuration
integration_operatorBusiness system integrationopen:command:create, open:command:read, open:object:create, open:device-request:read
integration_readerRead-only integrationQuery commands and device requests without creating commands

Authorization Model

Tenant, identity, scope, and business facts are connected as follows:
ConceptSourceResponsibility
Tenantauthenticated credential bindingdata isolation boundary
CredentialX-Api-Idcaller identity
Role BindingCasbin g policybinds client_id to a role inside a tenant domain
ScopeCasbin object:actiondescribes what the caller may do in the tenant
Business Ownershipcommand/object/callback factspersists business ownership
The Casbin request model is:
sub = client_id
dom = tenant_id
obj = object
act = action
Command acceptance checks:
Enforce(client_id, tenant_id, "open:command", "create")
Object presign checks:
Enforce(client_id, tenant_id, "open:object", "create")
Object storage configuration uses open:object-config; callback configuration uses open:callback. tenant_id must come from the authenticated credential binding. It cannot be declared or overridden by the request body. Later query, callback, adapter execution, and object access flows must use the tenant_id stored in business facts as the boundary; command_id, resource_id, or other global identifiers are not sufficient authorization context.

On Authorization Failures

Calling an endpoint without permission returns:
{
  "code": "FORBIDDEN",
  "message": "authorization denied",
  "request_id": "req_001"
}
To debug:
  • Confirm X-Api-Id is the expected client credential.
  • Confirm the credential is bound to the correct tenant_id.
  • Confirm the client_id has the required Casbin policy or role binding in the tenant domain.
For the full code list see Error Model.