Access control

You can control access to Unity Gaming Services (UGS) including Cloud Code via the Access Control service.

Access Control enables you to create rules to restrict access to service APIs that you don't want to make available to players.

If you allow player access to APIs, you reduce the security of your game. For more information, refer to Server authority.

Control player economies with Cloud Code example

The example below demonstrates how you can create a project-based policy that denies access to the Economy service increment/decrement APIs. As players are unable to manipulate their own balances directly, you can create a Cloud Code script that makes these requests as a trusted client on the player's behalf.

You are able to apply access policies with the UGS CLI tool.

Prerequisites

Ensure you have the following prerequisites for your project before you continue with the example:

  1. Have a published currency in the Economy service.
  2. Have the UGS CLI set up to run commands. For more information, refer to the Get started guide.
  3. Have the project-level Project Resource Policy Editor, Project Resource Policy Reader, and Unity Environments Viewer roles granted to the Service Account you used to authenticate with the CLI tool.

Create an Access Control project policy to restrict access

Create a project-policy.json file with the following content to create a policy that denies players direct access to the increment and decrement APIs in the Economy service.

{
  "statements": [
    {
      "Sid": "DenyPlayerAccessForEconomyIncrementAndDecrement",
      "Resource": "urn:ugs:economy:/*/*crement",
      "Principal": "Player",
      "Action": ["*"],
      "Effect": "Deny"
    }
  ]
}

Use the UGS CLI tool to apply this policy to your project:

ugs access upsert-project-policy project-policy.json

Test that the policy has successfully denied players from making requests directly to the increment API endpoint when authenticated as a player.

curl 'https://economy.services.api.unity.com/v2/projects/<PROJECT_ID>/players/<PLAYER_ID>/currencies/<CURRENCY_ID>/increment' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <BEARER_TOKEN>' \
--data '{
    "amount": 10
}'

If the policy has been successfully applied, this request should return a response with a 403 HTTP status code:

{
    "status": 403,
    "title": "Forbidden",
    "type": "https://services.docs.unity.com/docs/errors/#56",
    "requestId": "b815d154-91f5-470e-a8ef-76c3c8ec7c13",
    "detail": "Access has been restricted",
    "code": 56
}

Create and publish a Cloud Code script

Create and publish a Cloud Code script that includes the latest Economy SDK version to make the increment balance request. This script takes the currencyId as a script parameter to define which currency to apply the balance update to. Ensure this matches the resource ID in your Economy currency configuration.

JavaScript

const { CurrenciesApi } = require("@unity-services/economy-2.4");

module.exports = async ({ params, context, logger }) => {
 const { projectId, playerId } = context;
 const { currencyId } = params;

 const currencies = new CurrenciesApi(context);

  try {
    const result = await currencies.incrementPlayerCurrencyBalance({ projectId, playerId, currencyId, currencyModifyBalanceRequest: { amount: 10 } });
    return result.data;
  } catch (err) {
    logger.error("Failed to update currency balance", {"error.message": err.message}, {"currencyId" : currencyId});
    throw err;
  }
}

module.exports.params = {
  "currencyId" : { "type": "String", "required": true }
}

Important: The Economy SDK default authentication uses the Cloud Code service account from version 2.4+. It authenticates as the player when using version 2.3 and below.

Test that the Cloud Code script is able to increment the balance when authenticated as a player.

curl --request POST 'https://cloud-code.services.api.unity.com/v1/projects/<PROJECT_ID>/scripts/<SCRIPT_NAME>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <BEARER_TOKEN>'
--data '{"currencyId": "<CURRENCY_ID>"}'

If the balance update request was successful, Cloud Code should respond with a 200 HTTP status code and the result of the increment request containing the new balance value.

{
  "result": {
    "balance": 10,
    "created": {
      "date": "2023-06-30T09:12:54Z"
    },
    "currencyId": "GOLD",
    "modified": {
      "date": "2023-06-30T09:12:54Z"
    },
    "writeLock": "1"
  }
}

Validating the script

You can confirm the player currency balance via the Unity Cloud Dashboard using Player Management or by requesting the balance via the Economy service API:

curl 'https://economy.services.api.unity.com/v2/projects/<PROJECT_ID>/players/<PLAYER_ID>/currencies' \
--header 'Authorization: Bearer <BEARER_TOKEN>'

With Cloud Code successfully set up to control player balances, you can insert additional logic to ensure that a player's balance is updated only when it is expected.