# Access control

> Control access to Unity Gaming Services by creating rules to restrict service APIs.

You can control access Unity Gaming Services (UGS) including Cloud Code via the [Access Control service](/services/access-control.md).

Using Access Control enables you to create rules to restrict access to service APIs that should not be made available to players.

> **Note:**
>
> If you allow player access to modules, you reduce the security of your game. For more information, refer to [Server authority](/cloud-code.md).

## Control player access to Cloud Code modules example

The example below demonstrates how you can create a project-based policy that denies access to the Cloud Code service APIs. You can wire a Cloud Code C# module to a trigger while denying direct requests from players, increasing the security of your game.
You are able to create access policies with the [UGS CLI tool](https://services.docs.unity.com/guides/ugs-cli/latest/access/Access%20Command%20Line/overview/).

## Prerequisites

First, you need to create a service account with required access roles and configure the [UGS CLI](https://services.docs.unity.com/guides/ugs-cli/latest/general/get-started/install-the-cli/).

### Authenticate using a Service Account

Before you can call the Scheduling and Triggers services, you need to use a service account to authenticate.

1. Navigate to the [Unity Dashboard](https://cloud.unity.com).
2. Select **Administration** > **Service Accounts**.
3. Select the **New** button and enter a name and description for the Service Account.
4. Select **Create**.

Add Product roles and create a key:

1. Select **Manage product roles**.
2. Add the following roles to the Service Account:

* From the LiveOps dropdown, select **Triggers Configuration Editor**, **Triggers Configuration Viewer**, **Scheduler Configuration Editor** and **Scheduler Configuration Viewer** .
* From the Admin dropdown, select **Unity Environments Viewer**, **Project Resource Policy Editor** and **Project Resource Policy Reader**.

3. Select **Save**.
4. Select **Add Key**.
5. Encode the **Key ID** and **Secret key** using base64 encoding. The format is “key\_id:secret\_key”. Note this value down.

For more information, refer to [Authentication](../authentication).

### Configure the UGS CLI

Follow the steps below to get stated with the UGS CLI:

1. [Install the UGS CLI](https://services.docs.unity.com/guides/ugs-cli/latest/general/get-started/install-the-cli/).

2. Use the following to configure your Project ID and Environment:
   `ugs config set project-id <your-project-id>`
   `ugs config set environment-name <your-environment-name>`

3. Authenticate using the service account you created earlier. For more information, refer to [Get Authenticated](https://services.docs.unity.com/guides/ugs-cli/latest/general/get-started/get-authenticated/).

### Create a module endpoint

[Create](/cloud-code/modules/how-to-guides/write-modules.md) a Cloud Code module that broadcasts a message to all connected players in the project.

Refer to [send push messages](/cloud-code/modules/how-to-guides/push-messages.md) for more information.

```csharp
using Microsoft.Extensions.DependencyInjection;
using Unity.Services.CloudCode.Core;
using Unity.Services.CloudCode.Apis;

namespace HelloWorld
{
    public class HelloWorld
    {
        [CloudCodeFunction("SendProjectMessage")]
        public async Task SendProjectMessage(IExecutionContext context, IPushClient pushClient, string message, string messageType)
        {
            await pushClient.SendProjectMessageAsync(context, message, messageType);
        }
    }

    public class ModuleConfig : ICloudCodeSetup
    {
        public void Setup(ICloudCodeConfig config)
        {
            config.Dependencies.AddSingleton<IPushClient>(PushClient.Create());
        }
    }
}
```

Deploy the module.

Refer to [Deploying Hello World](/cloud-code/scripts/getting-started.md#deploying-hello-world) to learn how to deploy a module.

### 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 module endpoint.

```json
{
  "statements": [
    {
      "Sid": "DenyPlayerAccessForSendingMessageToProject",
      "Resource": "urn:ugs:cloud-code:/v1/projects/*/modules/HelloWorld/SendProjectMessage",
      "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 `SendProjectMessage` module endpoint when [authenticated as a player](/cloud-code/modules/how-to-guides/authentication.md#authenticate-players).

```bash
curl 'https://cloud-code.services.api.unity.com/v1/projects/<PROJECT_ID>/players/<PLAYER_ID>/modules/HelloWorld/SendProjectMessage' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <BEARER_TOKEN>' \
--data '{
"params": {
"message": "hello"
}
}'
```

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

```json
{
  "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
}
```

Test that the Cloud Code module is able to execute when authenticated with a service account with the same request.
To continue, you need to obtain a stateless token and use it as a Bearer token in the request.

Refer to [Cloud Code Client API Bearer Authentication](/cloud-code/modules/how-to-guides/authentication.md#cloud-code-client-api-\(bearer-authentication\)) for more information.

```bash
curl 'https://cloud-code.services.api.unity.com/v1/projects/<PROJECT_ID>/modules/HelloWorld/SendProjectMessage' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <BEARER_TOKEN>' \
--data '{
"params": {
"message": "hello"
}
}'
```

If the request is successful, Cloud Code should respond with a `200` HTTP status code.

```json
{
  "output": null
}
```

### Set up Scheduling and Triggers

You can set up a schedule and trigger to invoke the `SendProjectMessage` module endpoint.

#### Create a schedule configuration

Run the `new-file` command to create a schedule configuration locally:

```bash
ugs scheduler new-file schedule-config
```

Update the `schedule-config.sched` file with the following configuration:

```json
{
  "$schema": "https://ugs-config-schemas.unity3d.com/v1/schedules.schema.json",
  "Configs": {
    "send-project-message": {
      "EventName": "announcement",
      "Type": "one-time",
      "Schedule": "2024-08-28T00:00:00Z",
      "PayloadVersion": 1,
      "Payload": "{\"message\": \"hello\"}"
    }
  }
}
```

> **Note:**
>
> Make sure the `schedule` timestamp is in the future.

#### Create a trigger configuration

Run the `new-file` command to create a trigger configuration locally:

```bash
ugs triggers new-file triggers-config
```

To create a trigger that invokes the `SendProjectMessage` module endpoint when the `announcement` event fires, update the `triggers-config.tr` file with the following configuration:

```json
{
  "$schema": "https://ugs-config-schemas.unity3d.com/v1/triggers.schema.json",
  "Configs": [
    {
      "Name": "announcement-trigger",
      "EventType": "com.unity.services.scheduler.announcement.v1",
      "ActionUrn": "urn:ugs:cloud-code:HelloWorld/SendProjectMessage",
      "ActionType": "cloud-code"
    }
  ]
}
```

#### Deploy the configurations

Deploy the files using the UGS CLI tool:

```bash
ugs deploy <path-to-config-files>
```

If configured correctly, the trigger should invoke the `SendProjectMessage` module endpoint when the `announcement` event is fired.
