Get SpatialOS

Sites

Menu

Service account maintenance

The Service Account Service is in alpha and may have breaking changes before stabilizing. For more information on maturity stages see Maturity stages.

Introduction

Service accounts are a special type of account which allow you to authenticate API calls for automated jobs such as integrating your own authentication provider or performing game maintenance. Previously, you could only obtain a service account by asking Improbable support to set one up for you. With the Platform SDK, you can create your own service accounts and manage them yourself.

For security reasons, service accounts usually expire. Therefore, if you have many service accounts for different uses you will probably need a script to manage them and keep them up to date. In this example, we demonstrate how to create new service accounts, remove them, and extend the duration of all your service accounts due to expire soon.

For more information on service accounts, see Service accounts. You can find the full code example on GitHub.

Find out how to download the SDK from the Introduction.

Example: setting up service account maintenance

If you encounter problems using the Service Account Service, we may need to grant you access. If you’d like access, raise a support request (for customers with a service agreement) or ask on our forums.

1. Instantiate a client

First, instantiate a client of the ServiceAccountServiceClient type to communicate with the service.

Use the Create method of the ServiceAccountServiceClient.

private static readonly ServiceAccountServiceClient ServiceAccountServiceClient = ServiceAccountServiceClient.Create();

By default, this uses your refresh token saved locally by spatial CLI. You can find your token at:

  • Windows: C:\Users\<username>\AppData\Local\.improbable\oauth2\oauth2_refresh_token\
  • Mac: ~/.improbable/oauth2/oauth2_refresh_token

Since this example is intended to run as an automated task, we recommend using a service account for authentication. If you want to provide a refresh token which is not your own, you can instantiate a PlatformRefreshTokenCredential object and supply it to Create:

var credentialsWithProvidedToken = new PlatformRefreshTokenCredential("my_refresh_token");
private static readonly ServiceAccountServiceClient ServiceAccountServiceClient =
                ServiceAccountServiceClient.Create(credentials: credentialsWithProvidedToken);

2. Create service accounts

In a Setup() function, create some new service accounts using the CreateServiceAccount RPC. You must provide:

  • a descriptive Name
  • a ProjectName which determines the project the service account is associated with
  • a list of Permissions which specify what the service account can do

Optionally, you can also provide a Lifetime which specifies when the service account will expire. If you don’t provide this, the service account will never expire unless you manually delete it.

A service account can have an unlimited number of permissions but we only grant one in this example. To find out which permissions you can grant to a service account, see Service account permissions.

Construct a Permission object which permits read and write access to a project defined in a variable called ProjectName.

var perm = new Permission
{
    Parts = {new RepeatedField<string> {"prj", ProjectName}},
    Verbs =
    {
        new RepeatedField<Permission.Types.Verb>
        {
            Permission.Types.Verb.Read,
            Permission.Types.Verb.Write
        }
    }
};

After defining the Permission, construct the CreateServiceAccountRequest and make the RPC call to CreateServiceAccount. Basic details about the service account, for example expiry time, are viewable by other users who are part of the same project.

var resp = ServiceAccountServiceClient.CreateServiceAccount(new CreateServiceAccountRequest
{
    Name = ServiceAccountName,
    ProjectName = ProjectName,
    Permissions = {new RepeatedField<Permission> {perm}},
    Lifetime = Duration.FromTimeSpan(new TimeSpan(1)) // Let this service account live for one day
});

The service account Name can be any alphanumeric string with underscores between 5 and 64 characters, and does not need to be unique. We recommend choosing a descriptive name to make it easier to manage your service accounts in the future.

To create multiple service accounts, wrap the RPC call in a for loop. Store the returned IDs in a list so you can manipulate the service accounts later.

private static List<long> ServiceAccountIds;

/* ... */

for (var i = 0; i < NumberOfServiceAccountsToCreate; i++)
{
    var resp = ServiceAccountServiceClient.CreateServiceAccount(new CreateServiceAccountRequest
    {
        Name = ServiceAccountName,
        ProjectName = ProjectName,
        Permissions = {new RepeatedField<Permission> {perm}},
        Lifetime = Duration.FromTimeSpan(new TimeSpan(1)) // Let this service account live for one day
    });
    // Add the ID of the service account you just created to a List to allow for deleting it later
    ServiceAccountIds.Add(resp.Id);
}

The response from CreateServiceAccount also includes the refresh token in the Token field. The refresh token is never revealed again. You must safely store the refresh token somewhere to use it for authentication.

3. List your service accounts

It is often useful to list service accounts that expire soon so that you can take action and extend their lifetime before they become invalid and possibly cause unintended consequences such as a script no longer working.

Specify at what point before a service account’s expiry you want to extend it. Then specify how long you want to extend it for.

// Take action if the service account expires in fewer than two days
private const int DaysRemainingAtWhichExpiryShouldBeIncreased = 2;
// Expand a service account's lifetime by a further two days
private const int DaysToExpandServiceAccountBy = 2;

Use the ListServiceAccounts RPC to fetch all of your service accounts associated with the project ProjectName and filter with Where to obtain service accounts whose expiry time is below the threshold you just defined.

var serviceAccounts = ServiceAccountServiceClient.ListServiceAccounts(new ListServiceAccountsRequest
{
    ProjectName = ProjectName
})
.Where(serviceAccount => (serviceAccount.ExpirationTime.ToDateTime() - DateTime.UtcNow).TotalDays <=
                         DaysRemainingAtWhichExpiryShouldBeIncreased);

The ListServiceAccounts RPC is paginated with a default page size of 20. You can use the optional parameter PageSize in the ListServiceAccountsRequest to decrease or increase the number of records returned on each page fetch.

4. Update service accounts nearing expiry

Iterate through the service accounts nearing expiry returned from ListServiceAccounts and use the UpdateServiceAccount RPC to add DaysToExpandServiceAccountBy onto the current expiry time. If you set DaysRemainingAtWhichExpiryShouldBeIncreased to be more than one day, this should extend the expiry times of the service accounts you created in step two.

foreach (var serviceAccount in serviceAccounts)
{
    // Calculate how many days it is until the service account expires
    var daysUntilExpiry =
        Math.Floor((serviceAccount.ExpirationTime.ToDateTime() - DateTime.UtcNow).TotalDays);

    // Now extend the lifetime by increasing the expiry time relative to the current time
    ServiceAccountServiceClient.UpdateServiceAccount(new UpdateServiceAccountRequest
    {
        Id = serviceAccount.Id,
        ExpirationTime = DateTime.UtcNow.AddDays(DaysToExpandServiceAccountBy).ToTimestamp()
    });
}

The UpdateServiceAccount RPC can update either the service account’s expiry time or permissions, or both. To find out what permissions you can grant to a service account, see Service account permissions.

5. Delete service accounts

In a Cleanup() function, delete the service accounts created in step one.

Note: By deleting a service account, any service using the invalid refresh token for authentication may behave unexpectedly.

To delete a service account, supply the service account ID to the DeleteServiceAccount RPC. You saved a reference to every service account created in the ServiceAccountIds list in step two.

foreach (var id in ServiceAccountIds)
{
    ServiceAccountServiceClient.DeleteServiceAccount(new DeleteServiceAccountRequest
    {
        Id = id
    });
}

Search results

Was this page helpful?

Thanks for letting us know!

Thanks for your feedback

Need more help? Ask on the forums