It took me far too long to figure out how to authenticate, so here’s exactly what you need to do to get your stateless authentication token to use REST services as Admin.
This is intended as addendum for the official authentication page and works for me on Windows 11 but OSX/Linux may be different. See the docs for details, I only added more details and correction where it was confusing or failed to work.
Create a service account
Click “Add Key” to add a key with secret
Store the secret in a save place! If you don’t and lose it, you need to generate a new key/secret combo.
Click “Manage organization roles” and then click “Manage project roles” (see below for details)
Authenticate using service account credentials
Create a string using your project key and secret, separated by colon
Note: Base64 encode is optional for Windows (see below for details)
Authenticate using a stateless token
The curl example did not work for me. Corrections:
Write “curl.exe” because in Powershell “curl” is an alias to some other tool that isn’t working with this example.
Add another header: -H “content-length: 1000” (otherwise you get “requires content-length” errors; note: even length 0 worked for me)
Enclose the URL in brackets, otherwise you get “environmentId is not a recognized as a command”
Environment must be specified via its GUID, not the environment name (eg “production”). In the Dashboard, select your project and switch to Environments tab to see the Environment IDs.
Hope this helps others saving some time trying to figure this out.
Which Roles?
Which roles you need for what is not really documented. The title for Organization Roles can be unclear, for instance does “Storage & Transformation” affect Cloud Save? Probably not. This seems to relate to one of the lesser known services: Presence. This page lists the services with an admin API.
Project roles are easier to pick, all Gaming Services are found under “LiveOps”. However, the list is not sorted alphabetically so carefully go through all items.
Base64 encoding?
Base64 encode of key/secret is not necessary on Windows, but at least for authentication it also works. I would recommend doing so regardless just so you’re compatible with non-Windows OS.
Note that it may be necessary to base64 encode on OS X since that’s essentially Unix too.
CAUTION: There are online services for base64 encoding but keep in mind you’re giving away your project key:secret if you use those! Who knows what kind of database these inputs may get stored in and regularly / automatically getting scraped and tried against known public webservices for a “success” status. Don’t underestimate the haxx0rz! If I were a hacker, I would chuckle devilishly at everyone voluntarily sending me their keys & secrets in plain text! Particularly because base64 encoding almost guarantees it’s going to be used in a web request!
I thought I’ll peek into it but then I was like … oh-kay, before I grasp what THIS does it’s summer.
Certainly!
I consider creating an in-editor Admin interface for some services but I’m hesitant due to all the REST request setup and error handling (rate limit, timeout).
Peeking into the Cloud API code I see some nice foundational (general purpose) wrappers for web requests with error handling etc. I wish that would be a separate package we could just consume for custom editor tooling.
Speaking of which, is there any in-editor tooling planned? I vaguely remember something but I may be confusing this with in-editor multiplayer services (relay etc).
I’ve been pushing to make some of the APIs we use public, but we tend to err on the side of caution when it comes to making API public, so concrete customer feedback helps a ton.
I started using the Cloud Services Apis package. Works wonderfully, especially the Services => API Samples window is really helpful.
Only thing I don’t understand is the difference between a “trusted client” and the “admin client”. I assume the service account is the trusted client, but who is the admin client?
Here’s my test code for reference, might help others. This writes custom items in Cloud Save, using both trusted and admin clients - which both work with the same key and secret.
var apiKey = "enter yours";
var apiSecret = "dont tell anyone";
await EnvironmentsApi.Instance.RefreshAsync();
var envId = EnvironmentsApi.Instance.ActiveEnvironmentId.Value.ToString();
var projectId = CloudProjectSettings.projectId;
Debug.Log($"project: {projectId} ({CloudProjectSettings.projectName})");
Debug.Log($"environment: {envId} ({EnvironmentsApi.Instance.ActiveEnvironmentName})");
var trustedClient = ApiService.CreateTrustedClient();
trustedClient.SetServiceAccount(apiKey, apiSecret);
var signInResponse = await trustedClient.SignInWithServiceAccount(projectId, envId);
var trustedResponse = await trustedClient.CloudSaveData.SetCustomItem(projectId, "trustedTestCustomItemId",
new SetItemBody("theKey", "someValue"));
Debug.Log($"trusted - set item response: {trustedResponse.ErrorText} {trustedResponse.Content}");
var adminClient = ApiService.CreateAdminClient();
adminClient.SetServiceAccount(apiKey, apiSecret);
var adminResponse = await adminClient.CloudSaveData.SetCustomItem(projectId, envId, "adminTestCustomItemId",
new Unity.Services.Apis.Admin.CloudSave.SetItemBody("theKey", "someValue"));
Debug.Log($"admin - set item response: {adminResponse.ErrorText} {adminResponse.Content}");
And the required usings:
using Unity.Services.Apis;
using Unity.Services.Apis.CloudSave;
using Unity.Services.Core.Editor.Environments;
using UnityEditor;
using UnityEngine;
First, in you didn’t see it, there’s an index.md in the Documentation~ folder of the package which goes a bit into the explanation of each clients and the overall functionality.
Unity gaming services offer two types of APIs: Cilent & Admin.
You can see the split between those for most products when browsing through https://services.docs.unity.com/
Game apis support large player scale use and have different authorization mechanisms, relying on JWTs.
The Admin Client deals exclusively with Admin Apis.
The Trusted Client deals exclusively with Game Apis.
Both of them use service accounts to authorize the operations, but they do it differently.
Admin apis use the service account directly in the request authorization header.
Trusted apis will exchange the service account for an access token that will then be used to authorize the operations. (this enables support for larger scale)
The admin client is mostly for managing service configuration, though some services offer more than that.
The trusted client is essentially there for when you want to call game apis authoritatively, for example to get player information. It’s very similar to the Server Client in that sense, except the intent is for it to be used in the editor context for custom tooling.
The api editor samples for things like cloud save, economy, etc use the Trusted Client to retrieve player data for example.
The differences between those clients are found in the REST API docs? I noticed for example some Admin API Leaderboards methods require Leaderboard Admin role, others also work with the Leaderboard Viewer role which I assume would be a Trusted or Server client.