Kaltura API: Use of appToken gives "access to service [schedule_scheduleevent->list] is forbidden"

Hello. We’ve been using Kaltura API (Python) successfully for about a year, authenticating with:

   config = KalturaConfiguration()
   self.client = KalturaClient(config)
   ks = self.client.session.start(
       app.config['KALTURA_ADMIN_SECRET'],
       app.config['KALTURA_UNIQUE_USER_ID'],
       KalturaSessionType.ADMIN,
       app.config['KALTURA_PARTNER_ID'],
       app.config['KALTURA_EXPIRY'],
       'appId:appName-appDomain',
   )
   self.client.setKs(ks)

I now want to use an appToken to authenticate. The code above was replaced with:

   config = KalturaConfiguration()
   self.client = KalturaClient(config)
   result = self.client.session.startWidgetSession(
       expiry=app.config['KALTURA_EXPIRY'],
       widgetId=f"_{app.config['KALTURA_PARTNER_ID']}",
   )
   self.client.setKs(result.ks)
   token_hash = hashlib.sha256((result.ks + app.config['KALTURA_APP_TOKEN']).encode('ascii')).hexdigest()
   result = self.client.appToken.startSession(
       id=app.config['KALTURA_APP_TOKEN_ID'],
       tokenHash=token_hash,
       userId=app.config['KALTURA_APP_TOKEN_USER_ID'],
       type=KalturaSessionType.ADMIN,
       expiry=app.config['KALTURA_EXPIRY'],
       sessionPrivileges='list:*',
   )

The session starts successfully but, when making an API call, I get:

The access to service [schedule_scheduleevent->list] is forbidden (SERVICE_FORBIDDEN)

I verified the “sessionPrivileges” and “type” of the appToken and all looks right. What am I missing?

Thank you!

Figure this out yet? I am having the exact same problem

Hi @eberfinn ,

Below is a full example. This code will:

  • Create an appToken of type 2 (ADMIN)
  • Generate a session using said appToken and set the returned KS on the client
  • Call schedule.scheduleEvent.list()

See inline comment about restricting the API actions allowed with the token.

from KalturaClient import *
from KalturaClient.Plugins.Core import *
from KalturaClient.Plugins.Schedule import *
import hashlib

partner_id=000000
admin_secret=""
userId = "user@example.com"
config = KalturaConfiguration(partner_id)
config.serviceUrl = "https://www.kaltura.com/"
client = KalturaClient(config)
ks = client.session.start(
            admin_secret,
            userId,
            KalturaSessionType.ADMIN,
            partner_id)
client.setKs(ks)

# create the app token
appToken = KalturaAppToken()
appToken.hashType = KalturaAppTokenHashType.SHA256

# if you wish to restrict privileges such that only the `scheduleEvent` service actions could be used with this token, you can create a role by calling userRole.add() with
# userRole:permissionNames=SCHEDULE_EVENT_BASE,SCHEDULE_EVENT_MANAGE,SCHEDULE_RESOURCE_MANAGE,SCHEDULE_RESOURCE_BASE
# userRole:name=NAME, e.g: MY_SCHEDULE_ROLE
# userRole:systemName=NAME, e.g: MY_SCHEDULE_ROLE
# This would allow all event scheduling operations, naturally, you could refine this further to only allow read only operations.
# see https://developer.kaltura.com/api-docs/VPaaS-API-Getting-Started/application-tokens.html#set-a-user-role for more details.


# appToken.sessionPrivileges = 'setrole:MY_SCHEDULE_ROLE'

result = client.appToken.add(appToken);
id=result.id;
token=result.token;

# generate a widget session in order to use the app token
widgetId = "_"+str(partner_id)
expiry = 86400

result = client.session.startWidgetSession(widgetId, expiry);
client.setKs(result.ks)
tokenHash = hashlib.sha256(result.ks.encode('ascii')+token.encode('ascii')).hexdigest()
type = KalturaSessionType.ADMIN

# start an app token session
result = client.appToken.startSession(id, tokenHash, userId, type, expiry);
# set the resulting KS on the client
client.setKs(result.ks)

filter = KalturaScheduleEventFilter()
pager = KalturaFilterPager()

result = client.schedule.scheduleEvent.list(filter, pager)
# if you set sessionPrivileges as described above when calling appToken.add(), the below call will fail
#result = client.media.list(filter, pager)

print(result)

Cheers,

@jess Sorry to revive this old topic, but I’m in the process of diagnosing an appToken permission issue and this was one of the few posts I could find with any information. In your response to @eberfinn, you set the session type to KalturaSessionType.ADMIN. It was my understanding that this would override any sessionPrivileges set in the appToken and create a KS with full admin permission. How would someone create an appToken with only the permissions necessary to perform the functions needed in an app? In my case, I need access to the following endpoints.

category.Add
categoryUser.Add
group.Add
group.List
groupUser.Add
media.Add
media.List
metadata.Add
scheduleEvent.Add
scheduleEvent.List
scheduleResource.List
scheduleEventResource.Add
user.List

So here is what I’ve tried. I retrieved the full list of permissionItems using the API console to see which Ids I need in order to create a new role with those permissions. In my instance, and I’m assuming these permissions with partnerId:0 are the same across all Kaltura SaaS instances, I located the following.

{
  "service": "category",
  "action": "add",
  "id": 7832,
  "type": "KalturaApiActionPermissionItem",
  "partnerId": 0,
  "createdAt": 1299481438,
  "updatedAt": 1299481438,
  "objectType": "KalturaApiActionPermissionItem"
},
{
  "service": "categoryuser",
  "action": "add",
  "id": 13812,
  "type": "KalturaApiActionPermissionItem",
  "partnerId": 0,
  "createdAt": 1342353291,
  "updatedAt": 1342353291,
  "objectType": "KalturaApiActionPermissionItem"
},
{
  "service": "group_group",
  "action": "add",
  "id": 18112,
  "type": "KalturaApiActionPermissionItem",
  "partnerId": 0,
  "createdAt": 1552551196,
  "updatedAt": 1552551196,
  "objectType": "KalturaApiActionPermissionItem"
},
{
  "service": "group_group",
  "action": "list",
  "id": 18122,
  "type": "KalturaApiActionPermissionItem",
  "partnerId": 0,
  "createdAt": 1552551197,
  "updatedAt": 1552551197,
  "objectType": "KalturaApiActionPermissionItem"
},
{
  "service": "groupuser",
  "action": "add",
  "id": 15762,
  "type": "KalturaApiActionPermissionItem",
  "partnerId": 0,
  "tags": "",
  "createdAt": 1424351732,
  "updatedAt": 1424351732,
  "objectType": "KalturaApiActionPermissionItem"
},
{
  "service": "media",
  "action": "add",
  "id": 11302,
  "type": "KalturaApiActionPermissionItem",
  "partnerId": 0,
  "createdAt": 1310288233,
  "updatedAt": 1310288233,
  "objectType": "KalturaApiActionPermissionItem"
},
{
  "service": "media",
  "action": "list",
  "id": 6632,
  "type": "KalturaApiActionPermissionItem",
  "partnerId": 0,
  "createdAt": 1299481420,
  "updatedAt": 1299481420,
  "objectType": "KalturaApiActionPermissionItem"
},
{
  "service": "metadata_metadata",
  "action": "list",
  "id": 5442,
  "type": "KalturaApiActionPermissionItem",
  "partnerId": 0,
  "createdAt": 1299481412,
  "updatedAt": 1299481412,
  "objectType": "KalturaApiActionPermissionItem"
},
{
  "service": "schedule_scheduleevent",
  "action": "add",
  "id": 16792,
  "type": "KalturaApiActionPermissionItem",
  "partnerId": 0,
  "createdAt": 1463655388,
  "updatedAt": 1463655388,
  "objectType": "KalturaApiActionPermissionItem"
},
{
  "service": "schedule_scheduleevent",
  "action": "list",
  "id": 16832,
  "type": "KalturaApiActionPermissionItem",
  "partnerId": 0,
  "createdAt": 1463655390,
  "updatedAt": 1463655390,
  "objectType": "KalturaApiActionPermissionItem"
},
{
  "service": "schedule_scheduleresource",
  "action": "list",
  "id": 16782,
  "type": "KalturaApiActionPermissionItem",
  "partnerId": 0,
  "createdAt": 1463655387,
  "updatedAt": 1463655387,
  "objectType": "KalturaApiActionPermissionItem"
},
{
  "service": "schedule_scheduleeventresource",
  "action": "add",
  "id": 16852,
  "type": "KalturaApiActionPermissionItem",
  "partnerId": 0,
  "createdAt": 1463655392,
  "updatedAt": 1463655392,
  "objectType": "KalturaApiActionPermissionItem"
},
{
  "service": "user",
  "action": "list",
  "id": 6142,
  "type": "KalturaApiActionPermissionItem",
  "partnerId": 0,
  "createdAt": 1299481414,
  "updatedAt": 1299481414,
  "objectType": "KalturaApiActionPermissionItem"
}

Now with these permissionItem Ids, I created the following permission.

{
“id”: 520643282,
“type”: 1,
“name”: “COURSE_CAPTURE_BUILDER”,
“friendlyName”: “Course Capture Builder permissions”,
“description”: “Limited permissions for Course Capture Builder application”,
“status”: 1,
“partnerId”: {partnerId},
“permissionItemsIds”: “5442,6142,6632,7832,11302,13812,15762,16782,16792,16832,16852,18112,18122”,
“createdAt”: 1685123854,
“updatedAt”: 1685123854,
“objectType”: “KalturaPermission”
}

And then I created a userRole with that new permission.

{
“id”: 28982642,
“name”: “Course Capture Builder”,
“systemName”: “Course Capture Builder”,
“description”: “Custom user role for the Course Capture Builder application”,
“status”: 1,
“partnerId”: {partnerId},
“permissionNames”: “COURSE_CAPTURE_BUILDER”,
“createdAt”: 1685127627,
“updatedAt”: 1685127627,
“objectType”: “KalturaUserRole”
}

Then I created the user-type appToken with that role, leaving sessionUserId blank so we can apply that at runtime for each different department that may use this app.

{
“id”: “{tokenId}”,
“token”: “{token}”,
“partnerId”: {partnerId},
“createdAt”: 1685127870,
“updatedAt”: 1685127870,
“status”: 2,
“sessionType”: 0,
“sessionDuration”: 86400,
“sessionPrivileges”: “setrole:28982642”,
“hashType”: “SHA256”,
“description”: “Course Capture Builder”,
“objectType”: “KalturaAppToken”
}

So now I have a somewhat functioning appToken except I get the following error messages when accessing certain endpoints.

category.List - The access to service [category->list] is forbidden
group.List - The access to service [groupUser->list] is forbidden
groupUser.Add - The access to service [groupUser->add] is forbidden
media.Add - Invalid KS “”, Error “-4,INVALID_TYPE”
metadata.Add - The access to service [metadata_metadata->add] is forbidden

The endpoints that seem to work are:
category.Add
categoryUser.Add
group.Add
media.List
metadata.Add
scheduleEvent.Add
scheduleEvent.List
scheduleResource.List
scheduleEventResource.Add
user.List

What pieces to this puzzle am I missing?