question

Martin avatar image
Martin asked

Unable to register cloud script (azure) function anymore

I have previously successfuly registered few azure functions. Now when I try to register another one I get "Action not authorized by title. : Action not authorized by title". I was looking for some setting in Title settings but I do not see anything to prevent it.

I was changing some API Policy some time ago so I think that is the cause, but I can't find which policy is responsible for this. I have pfrn:api--/Admin/ and pfrn:api--/Server/ Allow. I tried to add pfrn:api--/CloudScript/* but it does not work.

Edit: after setting the policy to pfrn:api--* Allow and waiting few hours, it started working again. I would like to know which specific policy controls this functionality.

apisCloudScript
1 comment
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Martin avatar image Martin commented ·

I replaced all my api policy with pfrn:api--* Allow, but it still does not allow me to add another cloud function. Edit: the next day it worked.

0 Likes 0 ·
Xiao Zha avatar image
Xiao Zha answered

I have changed the policy to test the RegisterHttpFunction API, but cannot reproduce your issue, it works fine in my test. You may check the API policy and the Global Entity policy to see if there is any difference from the normal one (which you can get from a new created Title).

5 comments
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Martin avatar image Martin commented ·

Before I changed my policy I saved the default one. I can't identify which policy statement allow/deny RegisterHttpFunction in the default api policy, because it is not explicitly stated among the default statements.

It seems that the changes take some time to manifest because I set allow all policy yesterday and it didn't work even few minutes after, but the next day it worked.

My custom changed policy was to allow all for Admin and Server and then enumerate specific client calls that are allowed (GetLeaderboard etc). With this policy, I get the "Action not authorized by title" consitently.

0 Likes 0 ·
Xiao Zha avatar image Xiao Zha Martin commented ·

I have tried disabling all APIs using API policy, but the RegisterHttpFunction API still works, and since RegisterHttpFunction is an entity API, your problem might be related to the Global Entity Policy. You can check the Global Entity Policy on the Settings->API Features page to see if it is different from the normal one (you can get the normal one from the newly created Title). Or you can share your API Policy and Global Entity Policy with us so that we can help you solve the issue.

0 Likes 0 ·
Martin avatar image Martin Xiao Zha commented ·

My Global Entity Policy is empty, but I certainly did not change it. Does it get cleared when changing policy with UpdatePolicyRequest with OverwritePolicy = true? I created a test title, so I will copy paste the policy from there as you suggested. Do I need to change EntityId? (what is it anyway). Edit: How do I change the Global Entity Policy from web interface, I can't see a way to save it, it always disappears even if I click "Save"

0 Likes 0 ·
Show more comments
Xiao Zha avatar image
Xiao Zha answered

Here is a Unity C# code example which shows you how to get TitleEntityToken and call PlayFabProfileInstanceAPI.GetGlobalPolicy. As for the SetGlobalPolicy API, you can refer to Account Management - Set Global Policy - REST API (PlayFab Profiles) | Microsoft Learn to know more about Entity Permission Statement, and since there is no document about entity global title policy for now, if you have problems with modifying or adding new entity policies, you can find more information or post specific questions in this forum.

  public void Start()
         { 
             PlayFabAuthenticationContext context = new PlayFabAuthenticationContext();
        
             PlayFabAuthenticationAPI.GetEntityToken(new PlayFab.AuthenticationModels.GetEntityTokenRequest{},
                 result =>
                 {
                 context.EntityToken = result.EntityToken;
                 PlayFabProfilesInstanceAPI instanceAPI = new PlayFabProfilesInstanceAPI(context);
                    
                 instanceAPI.GetGlobalPolicy(new PlayFab.ProfilesModels.GetGlobalPolicyRequest{},
                 result =>
                 {
                     foreach (var permission in (result.Permissions))
                     {
        
                         Debug.Log(JsonUtility.ToJson(permission));
                     }
                 }, error =>
                 {
                     Debug.Log("Get Failure!");
                 });
        
             },  error =>
             {
                 Debug.Log(error);
             });
     }
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Martin avatar image
Martin answered

This is my global entity policy (should be default) [ { "Action": "", "Effect": "Allow", "Resource": "--", "Principal": { "ChildOf": { "EntityType": "namespace", "EntityId": "" } }, "Comment": "The default allow title in namespace full access", "Condition": { "CallingEntityType": "title" } }, { "Action": "", "Effect": "Allow", "Resource": "pfrn:data--![SELF]/Profile/", "Principal": "[SELF]", "Comment": "The default allow profile self access", "Condition": null }, { "Action": "", "Effect": "Allow", "Resource": "pfrn:data--![SELF]/Profile/", "Principal": { "ChildOf": { "EntityType": "[SELF]" } }, "Comment": "The default allow profile child access", "Condition": null }, { "Action": "Write", "Effect": "Deny", "Resource": "pfrn:data--!/Profile/Statistics/", "Principal": "", "Comment": "Only title can edit user statistics", "Condition": { "CallingEntityType": "title_player_account" } }, { "Action": "Write", "Effect": "Deny", "Resource": "pfrn:data--!/Profile/Statistics/", "Principal": "", "Comment": "Only title can edit user statistics", "Condition": { "CallingEntityType": "character" } }, { "Action": "Write", "Effect": "Deny", "Resource": "pfrn:data--!/Profile/Statistics/", "Principal": "", "Comment": "Only title can edit user statistics", "Condition": { "CallingEntityType": "master_player_account" } }, { "Action": "Write", "Effect": "Deny", "Resource": "pfrn:data--group!/Profile/Statistics/", "Principal": { "MemberOf": { "RoleId": "" } }, "Comment": "Only title can edit group statistics", "Condition": null }, { "Action": "LobbyServerFull", "Effect": "Allow", "Resource": "pfrn:data--game_server!/Lobby/Server/", "Principal": { "ChildOf": { "EntityType": "title", "EntityId": "" } }, "Comment": "The Default allow title full Lobby server functionality", "Condition": { "CallingEntityType": "game_server" } }, { "Action": "Read", "Effect": "Allow", "Resource": "--", "Principal": { "ChildOf": { "EntityType": "namespace", "EntityId": "" } }, "Comment": "The default allow game_server in namespace full access", "Condition": { "CallingEntityType": "game_server" } }, { "Action": "Write", "Effect": "Allow", "Resource": "--", "Principal": { "ChildOf": { "EntityType": "namespace", "EntityId": "" } }, "Comment": "The default allow game_server in namespace full access", "Condition": { "CallingEntityType": "game_server" } }, { "Action": "Create", "Effect": "Allow", "Resource": "--", "Principal": { "ChildOf": { "EntityType": "namespace", "EntityId": "**" } }, "Comment": "The default allow game_server in namespace full access", "Condition": { "CallingEntityType": "game_server" } } ]

This is my API Policy [ { "Resource": "pfrn:api--/Admin/", "Action": "", "ApiConditions": null, "Comment": "The default allow all admin APIs statement.", "Effect": "Allow", "Principal": "" }, { "Resource": "pfrn:api--/Server/", "Action": "", "ApiConditions": null, "Comment": "The default allow all client APIs statement.", "Effect": "Allow", "Principal": "" }, { "Resource": "pfrn:api--/Client/LoginWithCustomID", "Action": "", "ApiConditions": null, "Comment": "Custom", "Effect": "Allow", "Principal": "" }, { "Resource": "pfrn:api--/Client/RegisterPlayFabUser", "Action": "", "ApiConditions": null, "Comment": "Custom", "Effect": "Allow", "Principal": "" }, { "Resource": "pfrn:api--/Client/LoginWithEmailAddress", "Action": "", "ApiConditions": null, "Comment": "Custom", "Effect": "Allow", "Principal": "" }, { "Resource": "pfrn:api--/Client/LinkCustomID", "Action": "", "ApiConditions": null, "Comment": "Custom", "Effect": "Allow", "Principal": "" }, { "Resource": "pfrn:api--/Client/AddUsernamePassword", "Action": "", "ApiConditions": null, "Comment": "Custom", "Effect": "Allow", "Principal": "" }, { "Resource": "pfrn:api--/Client/UpdateUserTitleDisplayName", "Action": "", "ApiConditions": null, "Comment": "Custom", "Effect": "Allow", "Principal": "" }, { "Resource": "pfrn:api--/Client/GetPlayerProfile", "Action": "", "ApiConditions": null, "Comment": "Custom", "Effect": "Allow", "Principal": "" }, { "Resource": "pfrn:api--/Client/GetPlayerCombinedInfo", "Action": "", "ApiConditions": null, "Comment": "Custom", "Effect": "Allow", "Principal": "" }, { "Resource": "pfrn:api--/Client/GetAccountInfo", "Action": "", "ApiConditions": null, "Comment": "Custom", "Effect": "Allow", "Principal": "" }, { "Resource": "pfrn:api--/Client/ExecuteFunction", "Action": "", "ApiConditions": null, "Comment": "Custom", "Effect": "Allow", "Principal": "" }, { "Resource": "pfrn:api--/Client/GetTitleData", "Action": "", "ApiConditions": null, "Comment": "Custom", "Effect": "Allow", "Principal": "" }, { "Resource": "pfrn:api--/Client/GetCatalogItems", "Action": "", "ApiConditions": null, "Comment": "Custom", "Effect": "Allow", "Principal": "" }, { "Resource": "pfrn:api--/Client/GetUserData", "Action": "", "ApiConditions": null, "Comment": "Custom", "Effect": "Allow", "Principal": "" }, { "Resource": "pfrn:api--/Client/GetUserInventory", "Action": "", "ApiConditions": null, "Comment": "Custom", "Effect": "Allow", "Principal": "" }, { "Resource": "pfrn:api--/Client/UpdateUserData", "Action": "", "ApiConditions": null, "Comment": "Custom", "Effect": "Allow", "Principal": "" }, { "Resource": "pfrn:api--/Client/SubtractUserVirtualCurrency", "Action": "", "ApiConditions": null, "Comment": "Custom", "Effect": "Allow", "Principal": "" }, { "Resource": "pfrn:api--/Client/ValidateGooglePlayPurchase", "Action": "", "ApiConditions": null, "Comment": "Custom", "Effect": "Allow", "Principal": "" }, { "Resource": "pfrn:api--/Client/ValidateIOSReceipt", "Action": "", "ApiConditions": null, "Comment": "Custom", "Effect": "Allow", "Principal": "" } ]

With this Api Policy I cannot run GetEntityTokenRequest (NotAuthorizedByTitle). When I change Api Policy to "allow all", I can successfully run it and also GetGlobalPolicyRequest, which gives me aforementioned Global Api Policy (I think it is a default one). However I am unable to run SetGlobalPolicyRequest with the exact same global policy that I just got ("HttpStatus":"BadRequest","Error":"InvalidParams","ErrorMessage":"Invalid JSON detected while building PrincipalName '[[[[[]],[[]]]]]').

But it seems that I can suddenly register new azure functions without any error message through PlayFab web interface with my custom API Policy in place. I don't know why.

1 comment
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Xiao Zha avatar image Xiao Zha commented ·

The GetGlobalPolicy API is used to get current version of the global entity policy in your title, which is the global entity policy you post above, and the policy you post is already the default version, you don’t have to call SetGlobalPolicy API to change it.

If you want to restore the API Policy to default, you can call Get Policy API in the new Title to get the default API policy, then replace the old API Policy in your old Title.

Also, if you want to change the Global Entity Policy, the API error message means there are some invalid JSON in your Policy “Principal” statements. You may check the JSON statement again or you can share the API request body which include the policy statement with us?

0 Likes 0 ·
Martin avatar image
Martin answered

So I at least figured out this part: "With this Api Policy I cannot run GetEntityTokenRequest (NotAuthorizedByTitle).". I was missing pfrn:api--/Authentication/ and pfrn:api--/Profile/

As I said, registering azure function works again now, but I don't know which of my action caused it to start work again (and I still don't know which of my action caused it to stop working in the first place).

Regarding the Global Entity Policy - yes, I don't need to change it, because it is the default one, it's just that I tried and it didn't work. Here is my Permission field in SetGlobalPolicyRequest that causes the invalid JSON error:

{ "CustomTags": null, "Permissions": [ { "Action": "", "Comment": "The default allow title in namespace full access", "Condition": { "CallingEntityType": "title" }, "Effect": "Allow", "Principal": { "ChildOf": { "EntityType": "namespace", "EntityId": "" } }, "Resource": "--" }, { "Action": "", "Comment": "The default allow profile self access", "Condition": null, "Effect": "Allow", "Principal": "[SELF]", "Resource": "pfrn:data--![SELF]/Profile/" }, { "Action": "", "Comment": "The default allow profile child access", "Condition": null, "Effect": "Allow", "Principal": { "ChildOf": { "EntityType": "[SELF]" } }, "Resource": "pfrn:data--![SELF]/Profile/" }, { "Action": "Write", "Comment": "Only title can edit user statistics", "Condition": { "CallingEntityType": "title_player_account" }, "Effect": "Deny", "Principal": "", "Resource": "pfrn:data--!/Profile/Statistics/" }, { "Action": "Write", "Comment": "Only title can edit user statistics", "Condition": { "CallingEntityType": "character" }, "Effect": "Deny", "Principal": "", "Resource": "pfrn:data--!/Profile/Statistics/" }, { "Action": "Write", "Comment": "Only title can edit user statistics", "Condition": { "CallingEntityType": "master_player_account" }, "Effect": "Deny", "Principal": "", "Resource": "pfrn:data--!/Profile/Statistics/" }, { "Action": "Write", "Comment": "Only title can edit group statistics", "Condition": null, "Effect": "Deny", "Principal": { "MemberOf": { "RoleId": "" } }, "Resource": "pfrn:data--group!/Profile/Statistics/" }, { "Action": "LobbyServerFull", "Comment": "The Default allow title full Lobby server functionality", "Condition": { "CallingEntityType": "game_server" }, "Effect": "Allow", "Principal": { "ChildOf": { "EntityType": "title", "EntityId": "" } }, "Resource": "pfrn:data--game_server!/Lobby/Server/" }, { "Action": "Read", "Comment": "The default allow game_server in namespace full access", "Condition": { "CallingEntityType": "game_server" }, "Effect": "Allow", "Principal": { "ChildOf": { "EntityType": "namespace", "EntityId": "" } }, "Resource": "--" }, { "Action": "Write", "Comment": "The default allow game_server in namespace full access", "Condition": { "CallingEntityType": "game_server" }, "Effect": "Allow", "Principal": { "ChildOf": { "EntityType": "namespace", "EntityId": "" } }, "Resource": "--" }, { "Action": "Create", "Comment": "The default allow game_server in namespace full access", "Condition": { "CallingEntityType": "game_server" }, "Effect": "Allow", "Principal": { "ChildOf": { "EntityType": "namespace", "EntityId": "" } }, "Resource": "--*" } ], "AuthenticationContext": null }

10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Xiao Zha avatar image
Xiao Zha answered

When I tested the API with Postman, I have added the missing "*" in your post and filled the EntityId (the missing "*" is caused by the markdown format of the forum post), the SetGlobalPolicy API returns OK. Since I cannot reproduce your issue, here is my Global policy, you can check. Also, you may try to call the SetGlobalPolicy in the Postman to rule out the code issue.

 {
   "CustomTags": null,
   "Permissions": [
     {
       "Action": "*",
       "Comment": "The default allow title in namespace full access",
       "Condition": {
         "CallingEntityType": "title"
       },
       "Effect": "Allow",
       "Principal": {
         "ChildOf": {
           "EntityType": "namespace",
           "EntityId": ""
        }
       },
       "Resource": "*--*"
     },
     {
       "Action": "*",
       "Comment": "The default allow profile self access",
       "Condition": null,
       "Effect": "Allow",
       "Principal": "[SELF]",
       "Resource": "pfrn:data--*![SELF]/Profile/*"
     },
     {
       "Action": "*",
       "Comment": "The default allow profile child access",
       "Condition": null,
       "Effect": "Allow",
       "Principal": {
         "ChildOf": {
           "EntityType": "[SELF]"
         }
       },
       "Resource": "pfrn:data--*![SELF]/Profile/*"
     },
     {
       "Action": "Write",
       "Comment": "Only title can edit user statistics",
       "Condition": {
         "CallingEntityType": "title_player_account"
       },
       "Effect": "Deny",
       "Principal": "*",
       "Resource": "pfrn:data--*!*/Profile/Statistics/*"
     },
     {
       "Action": "Write",
       "Comment": "Only title can edit user statistics",
       "Condition": {
         "CallingEntityType": "character"
       },
       "Effect": "Deny",
       "Principal": "*",
       "Resource": "pfrn:data--*!*/Profile/Statistics/*"
     },
     {
       "Action": "Write",
       "Comment": "Only title can edit user statistics",
       "Condition": {
         "CallingEntityType": "master_player_account"
       },
       "Effect": "Deny",
       "Principal": "*",
       "Resource": "pfrn:data--*!*/Profile/Statistics/*"
     },
     {
       "Action": "Write",
       "Comment": "Only title can edit group statistics",
       "Condition": null,
       "Effect": "Deny",
       "Principal": {
         "MemberOf": {
           "RoleId": "*"
         }
       },
       "Resource": "pfrn:data--group!*/Profile/Statistics/*"
     },
     {
       "Action": "LobbyServerFull",
       "Comment": "The Default allow title full Lobby server functionality",
       "Condition": {
         "CallingEntityType": "game_server"
       },
       "Effect": "Allow",
       "Principal": {
         "ChildOf": {
           "EntityType": "title",
           "EntityId": ""
         }
       },
       "Resource": "pfrn:data--game_server!*/Lobby/Server/*"
     },
     {
       "Action": "Read",
       "Comment": "The default allow game_server in namespace full access",
       "Condition": {
         "CallingEntityType": "game_server"
       },
       "Effect": "Allow",
       "Principal": {
         "ChildOf": {
           "EntityType": "namespace",
           "EntityId": ""
         }
       },
       "Resource": "*--*"
     },
     {
       "Action": "Write",
       "Comment": "The default allow game_server in namespace full access",
       "Condition": {
         "CallingEntityType": "game_server"
       },
       "Effect": "Allow",
       "Principal": {
         "ChildOf": {
           "EntityType": "namespace",
           "EntityId": ""
         }
       },
       "Resource": "*--*"
     },
     {
       "Action": "Create",
       "Comment": "The default allow game_server in namespace full access",
       "Condition": {
         "CallingEntityType": "game_server"
       },
       "Effect": "Allow",
       "Principal": {
         "ChildOf": {
           "EntityType": "namespace",
           "EntityId": ""
         }
       },
       "Resource": "*--*"
     }
   ],
   "AuthenticationContext": null
 }
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.