Service and access token support

In modules, the IExecutionContext interface provides an AccessToken and a ServiceToken.

Token typeOriginData accessUsage
accessTokenGenerated by the Authentication service.Only the authenticated player.The AccessToken is the JWT you use to authenticate a Cloud Code call. You can pass the token on to other UGS services to access data for the authenticated player.
serviceTokenGenerated by Cloud Code.Cross-player data access.The ServiceToken is a the token you use to call out to other UGS services and interact with cross-player data.

You can authenticate as a player or as Cloud Code with these tokens when you call other UGS services.

Refer to Authentication page for more information.

Overview

Evaluate whether you want to authenticate as a player or as a trusted client.

The module IExecutionContext interface provides you with a AccessToken and a ServiceToken.

If the purpose of the module is to only access the data of the authenticated player, you should use the AccessToken to authenticate as the player calling the module endpoint. This ensures that the player can only access and interact with their own data.

If the purpose of the module is to access cross-player data, you should use the ServiceToken to authenticate as Cloud Code. This will ensure that the module can access and interact with cross-player data. However, this creates an opening for malicious players to call the module endpoint and access cross-player data where not intended. To prevent this, you should ensure that the module is protected with Access Control rules.

To learn more about how you can interact with cross-player data, refer to the Cross-player data documentation.

Access token support

An access token is a JWT that the Authentication service(https://docs.unity.com/ugs/manual/authentication/manual/use-anon-sign-in) generates. You can use the access token to authenticate players.

When an authenticated player calls a Cloud Code module, they pass their access token to the module as the AccessToken property of the IExecutionContext interface.

You can use access tokens with the Cloud Code C# Game SDKs. To use access tokens with other UGS APIs, you need to pass the token as a bearer token in the Authentication header.

Supported services

To check which services support access tokens, refer to the table below:

ProviderSupported services
Cloud Code C# Client SDKsAll Cloud Code C# Client SDKs support the same access tokens as their corresponding service APIs.
UGS Client APIsAll UGS services that support the Authentication service.
Cloud Code C# Admin SDKsNot supported. Use Service Account authentication instead.
UGS Admin APIsNot supported. Use Service Account authentication instead.

Note: Most UGS services are onboarded with the Authentication service and support access tokens.

Use tokens with Cloud Code C# Client SDKs

To use the AccessToken with the Cloud Code C# Client SDKs, you need to pass the token from the IExecutionContext interface.

The example below increments the currency balance for the player that calls the module:

C#

[CloudCodeFunction("IncrementBalance")]
public async Task<ApiResponse<CurrencyBalanceResponse>> IncrementPlayerBalance(IGameApiClient gameApiClient, IExecutionContext ctx, string currencyId)
{
    ...
    try
    {
    // Increment the balance of the currency for the player calling the module
    var res =  await gameApiClient.EconomyCurrencies.IncrementPlayerCurrencyBalanceAsync(ctx, ctx.AccessToken,
            ctx.ProjectId, ctx.PlayerId, currencyId, new CurrencyModifyBalanceRequest(currencyId, 10));

    _logger.LogInformation("Incremented currency {currencyId} balance by {amount}", currencyId, 10);
    return res;

    }
    catch (ApiException e)
    {
        _logger.LogError("Failed to increment {currencyId} balance for the player. Error: {error}", currencyId, e.Message);
        throw new Exception($"Failed to increment {currencyId} balance for playerId {ctx.PlayerId}. Error: {e.Message}");
    }
}

Use with UGS Client APIs

To use the AccessToken with the UGS Client APIs, pass the token as a bearer token in the Authentication header.

Note: If the service you want to call provides a Cloud Code C# SDK, you can use the SDK instead of calling the service API directly. For a list of available SDKs, refer to Available libraries page.

C#

public class Relationships
{
    private readonly RestClient _httpClient;

    public Relationships()
    {
        _httpClient = new RestClient("https://social.services.api.unity.com/v1/relationships");
    }

    public async Task<List<RelationshipsApiResponse?>> GetRelationships(IExecutionContext context)
    {
        var request = new RestRequest()
        {
            // Pass the access token as a bearer token in the header
            Authenticator = new JwtAuthenticator(context.AccessToken)
        };

        ....
    }

}

Service token support

A service token is a JWT that Cloud Code generates. You can use service tokens to authenticate services as Cloud Code. This is a service account token that's gone through the Token Exchange process.

You can use the service token with the Cloud Code C# Client SDKs. To use it with other APIs, you need to pass it as a bearer token in the Authentication header.

Supported services

For a list of services that support service tokens, refer to the table below:

ProviderSupported services
Cloud Code C# Client SDKsRefer to Available libraries for a list of available SDKs.
UGS Client APIs
Cloud Code C# Admin SDKsNot supported. Use Service Account authentication instead.
UGS Admin APIsNot supported. Use Service Account authentication instead.

Note: We are still working on the documentation for Cloud Code C# Client SDKs. For now you can refer to the JavaScript documentation as it has a similar structure. Please also make use of your IDE's auto complete and intellisense features.

Use tokens with Cloud Code C# Client SDKs

To use a ServiceToken with the Cloud Code C# Client SDKs, pass the token from the IExecutionContext interface.

The example below takes in a player ID and increments the balance of a currency for that player:

C#

[CloudCodeFunction("IncrementBalance")]
public async Task<ApiResponse<CurrencyBalanceResponse>> IncrementPlayerBalance(IGameApiClient gameApiClient, IExecutionContext ctx, string currencyId, string playerId)
{
    ...
    try
    {
    // Increment the balance of the currency for the player ID passed in, authenticated as Cloud Code
    var res =  await gameApiClient.EconomyCurrencies.IncrementPlayerCurrencyBalanceAsync(ctx, ctx.ServiceToken,
            ctx.ProjectId, playerId, currencyId, new CurrencyModifyBalanceRequest(currencyId, 10));

    _logger.LogInformation("Incremented currency {currencyId} balance by {amount}", currencyId, 10);
    return res;

    }
    catch (ApiException e)
    {
        _logger.LogError("Failed to increment {currencyId} balance for the player. Error: {error}", currencyId, e.Message);
        throw new Exception($"Failed to increment {currencyId} balance for playerId {ctx.PlayerId}. Error: {e.Message}");
    }
}

Use tokens with UGS Client APIs

To use a ServiceToken with the UGS Client APIs, pass the token as a bearer token in the Authentication header.

Note: If the service you call provides a Cloud Code C# SDK, you can use the SDK instead of calling the service API directly. For a list of available SDKs, refer to the Available libraries page.

For example, if you define an interface for Cloud Save API, you can use the ServiceToken to authenticate and interact with cross-player data. The example below takes in a player ID and returns all the data stored for that player:

C#

using System.Net;
using Unity.Services.CloudCode.Core;
using Newtonsoft.Json;
using RestSharp;
using RestSharp.Authenticators;

namespace ExampleModule;

public interface ICloudSaveData
{
    public Task<CloudSaveResponse?> GetData(IExecutionContext context, string playerId);
}

public class CloudSaveResponse
{
    public CloudSaveItem[] Results { get; set; }
}

public class CloudSaveItem
{
    public string Key { get; set; }
    public object Value { get; set; }
}

public class CloudSaveData : ICloudSaveData
{
    private readonly RestClient _httpClient;

    public async Task<CloudSaveResponse?> GetData(IExecutionContext context, string playerId)
    {
        var request = new RestRequest($"v1/data/projects/{context.ProjectId}/players/{playerId}/items")
        {
            // Authenticate as Cloud Code to interact with cross-player data
            Authenticator = new JwtAuthenticator(context.ServiceToken)
        };

           // Pass through the analytics user id and Unity installation id to the service.
        if (context.AnalyticsUserId != null)
            request = request.AddHeader("analytics-user-id", context.AnalyticsUserId);
        if (context.UnityInstallationId != null)
            request = request.AddHeader("unity-installation-id", context.UnityInstallationId);

        RestResponse response = await _httpClient.ExecuteGetAsync(request);
        if (response.Content == null)
            throw new Exception("Failed to load data from Cloud Save: Content was null");

        if (response.StatusCode != HttpStatusCode.OK)
            throw new Exception("Failed to load data from Cloud Save: " + response.Content);

        return JsonConvert.DeserializeObject<CloudSaveResponse>(response.Content);
    }
}

Note: Cloud Code provides a Cloud Save C# SDK that you can use to interact with Cloud Save data. This sample above is demonstrates how you can use the ServiceToken to authenticate with other UGS services.