API access denied for data-stream after user role change in Composer

We’re experiencing API access issues after updating user roles in Composer for our ThingWorx 9.7 deployment. Users who previously had API access to data-stream endpoints are now getting 403 Forbidden errors after their roles were changed to align with our new security model.

The role changes were made in Composer’s Organizations & Users section, and the new roles should have inherited permissions from the previous roles. However, API requests that worked before are now failing:


GET /Thingworx/Things/SensorDataStream/Properties/temperature
Response: 403 Forbidden
{"error": "User does not have permission to execute service"}

Web-based access through mashups works fine for these same users, so they clearly have some level of access. The issue seems specific to REST API calls. I suspect there’s a disconnect between role-based API permissions and the role inheritance model in Composer, but I’m not sure how to diagnose or fix this. Has anyone dealt with API permission issues after role changes?

Role inheritance doesn’t always work as expected with API permissions. If you changed from a role that had explicit API permissions to a role that inherits those permissions, there can be edge cases where the inheritance chain doesn’t properly grant service execution rights. You may need to explicitly grant API permissions to the new role.

Thanks for the insights. I checked and the new role does have PropertyRead permission on the data-stream thing. Where exactly do I configure ServiceInvoke permissions? Is this in the thing’s permission settings or in the role configuration?

ServiceInvoke permissions are set on the thing itself, not in the role configuration. Go to the data-stream thing in Composer, open Permissions tab, and you’ll see ServiceInvoke as a separate permission category. Make sure the new role is listed there with appropriate service execution rights. Also check if there are any visibility restrictions that might be blocking API access.

I’ve troubleshot this exact scenario multiple times across different ThingWorx deployments. The issue is more complex than it initially appears and involves understanding ThingWorx’s multi-layered permission model:

Understanding Role-Based API Permissions: ThingWorx has separate permission layers that all must align for API access:

  1. Thing-level permissions (PropertyRead, ServiceInvoke)
  2. Role-based visibility permissions
  3. Runtime permissions for service execution
  4. Composer access permissions (affects API authentication)

Role Inheritance Issues: When you change user roles, inherited permissions don’t always propagate correctly for API access:

  • Web mashups use cached permission evaluations
  • API calls perform real-time permission checks
  • This creates the situation where mashups work but API calls fail

Diagnostic Steps: First, verify the actual permission state:


GET /Thingworx/Resources/CurrentSessionInfo
// Returns current user's roles and permissions
// Compare with expected permissions

Composer Permission Settings: Navigate to the data-stream thing in Composer:

  1. Open the thing (e.g., SensorDataStream)
  2. Go to Permissions tab
  3. Verify the new role is listed with these permissions:
    • PropertyRead: Checked (for reading temperature property)
    • ServiceInvoke: Checked (for API service calls)
    • Visibility: Checked (for thing discovery)

Role Inheritance Configuration: Check role inheritance chain:

  1. Go to Organizations & Users > Roles
  2. Find the new role assigned to users
  3. Verify inheritance from parent roles
  4. Look for permission conflicts or overrides
  5. Ensure ServiceInvoke is explicitly granted, not just inherited

Critical: Explicit vs Inherited Permissions: API permission evaluation prioritizes explicit permissions over inherited ones:

  • If parent role has ServiceInvoke but child role doesn’t explicitly grant it
  • API calls may fail even though inheritance suggests permission exists
  • Solution: Explicitly grant ServiceInvoke to the new role at the thing level

Implementation Fix:


// Pseudocode - Grant explicit API permissions:
1. Open data-stream thing (SensorDataStream) in Composer
2. Navigate to Permissions tab
3. Click Add Permission button
4. Select the new role (e.g., DataAnalyst)
5. Check ServiceInvoke and PropertyRead
6. Apply changes and save thing
// Reference: Security Guide Section 6.3

Session and Cache Clearing: After permission changes:

  1. Have all affected users logout completely
  2. Clear browser cache and cookies
  3. If using API keys, regenerate them
  4. Clear ThingWorx session cache (restart Session Manager subsystem)
  5. Test API access with fresh authentication

Verification Testing: Test API permissions systematically:


// Test property read
GET /Thingworx/Things/SensorDataStream/Properties/temperature

// Test service invoke
POST /Thingworx/Things/SensorDataStream/Services/GetDataStream

Both should return 200 OK if permissions are correct.

Common Permission Gotchas:

  1. Runtime Permissions: Even with thing permissions, users need Runtime > ServiceInvoke permission
  2. Organization Scope: If thing is in a specific organization, role must have access to that org
  3. Visibility Restrictions: Thing must be visible to the role (check Visibility permission)
  4. Instance-Level Permissions: Permissions set on thing templates don’t automatically apply to instances

Best Practice Implementation: For role-based API access:

  1. Create explicit permission grants (don’t rely solely on inheritance)
  2. Grant permissions at thing level, not just role level
  3. Test API access immediately after role changes
  4. Document permission requirements for each role
  5. Implement permission validation in CI/CD pipeline

Audit and Monitoring: Enable detailed permission logging:

  • Set log level to DEBUG for Security subsystem
  • Monitor ApplicationLog for permission denial messages
  • Look for specific error codes indicating permission type (403.1 vs 403.2)
  • Use audit logs to track permission changes

After implementing these changes, your API access should be restored. The key issue is that role inheritance doesn’t reliably grant ServiceInvoke permissions for API calls - you need explicit permission grants at the thing level for the new role.

Don’t forget about the Composer permission settings themselves. If the role doesn’t have adequate Composer access, it might affect how permissions are evaluated for API calls. Also, role changes sometimes require a session refresh - have your users logged out and back in after the role change? Cached permissions can cause these kinds of issues.

API permissions in ThingWorx are separate from UI permissions. Just because a user can view data in a mashup doesn’t mean they have API service execution rights. Check the ServiceInvoke permissions for the specific data-stream thing - the role might have PropertyRead but not ServiceInvoke.