<!-- Source: https://docs.squirro.com/en/latest/technical/api/squirro_client/service-account.html -->
# Create a Service Account

A service account is a non-personal user account that an application or integration uses to authenticate with Squirro. Service accounts are useful for automated workflows, integrations, and background services that need to access Squirro without relying on a personal user token.

This page explains how to create a service account and generate a token for it using the SquirroClient Python SDK.

## Prerequisites

Before you start, confirm that you have:

- Python installed and a SquirroClient environment set up. For installation instructions, see the [SquirroClient Installation](install.md#squirro-client-install) page.
- An admin token for the target tenant. To generate one, see [Connecting to Squirro](../../ui/connecting.md#ui-connecting).
- The `user.create` server setting turned on. This is a Configuration Service key that a Squirro administrator can enable. See [Configuration Service](../../admin/configuration/config-service.md#admin-config-service) for details.

## Client Credentials

The `SquirroClient` constructor takes `client_id` and `client_secret` as its first two arguments. These are OAuth2 application credentials that identify the application making the request to the Squirro authentication service. They are registered in the server configuration by a platform administrator and are not per-user credentials.

All operations on this page require real credentials. The `/grants` endpoint that `new_grant()` calls validates the credentials on every request and only accepts trusted registered clients.

For instructions on generating and registering client credentials, see the [user.ini](../../admin/configuration/config-files/user-ini.md#admin-user-ini) page.

## Create the user account

Use the `add_user()` method in your Python script to create the service account. Provide an email address, a password, and a role.

```python
from squirro_client import SquirroClient

client = SquirroClient("<client_id>", "<client_secret>", cluster="<cluster_url>", tenant="<tenant>")
client.authenticate(refresh_token="<admin_refresh_token>")

user = client.add_user(
    email="service-account@example.com",
    password="<secure_password>",
    role="user",
)

user_id = user["id"]
```

For the full parameter reference and return schema of `add_user()`, see [User Management](sc-api-user.md#sc-api-user).

The `role` parameter assigns a server-level role to the account, which controls what the service account can access across the tenant. The available roles are:

- **admin** — Full access to the tenant, including user management.
- **user** — Standard access to projects and content.
- **reader** — Read-only access to content. This role appears as **Restricted** in the Squirro UI.

For the API-level permission strings granted by each server role, see [Permissions Reference](sc-api-permissions.md#sc-api-permissions). For a complete description of what each role can do in the UI, see [Squirro Roles & Permissions](../../ui/permissions.md#ui-permissions).

## Generate a token

Use the `new_grant()` method in your Python script to generate a token for the service account. Set `type` to `"user"` for non-personal integrations.

```python
grant = client.new_grant(
    user_id=user_id,
    type="user",
)

service_token = grant["refresh_token"]
```

The response also contains an `id` field, which is the grant identifier you need if you later call `delete_grant()`. For the full return schema, see [User Management](sc-api-user.md#sc-api-user).

Alternatively, authenticate directly with the service account username and password to retrieve a token:

```python
service_client = SquirroClient("<client_id>", "<client_secret>", cluster="<cluster_url>", tenant="<tenant>")
service_client.authenticate(username="service-account@example.com", password="<secure_password>")
service_token = service_client.refresh_token
```

The `refresh_token` is valid for one year by default. It can expire earlier if the user session is invalidated, for example after a log out or a server-level role change. The SquirroClient automatically exchanges it for a short-lived access token and renews it transparently when the access token expires. For details on how the token model works, see [Authentication](../authentication.md#api-authentication).

Always store the token and password securely. Use an environment variable or a secrets manager rather than hard-coding it in your application.

## Authenticate as the service account

Use the token from the grant to authenticate a new client instance in your Python script as the service account.

```python
service_client = SquirroClient("<client_id>", "<client_secret>", cluster="<cluster_url>", tenant="<tenant>")
service_client.authenticate(refresh_token=service_token)
```

Alternatively, authenticate directly with the service account username and password to retrieve a token:

```python
service_client = SquirroClient("<client_id>", "<client_secret>", cluster="<cluster_url>", tenant="<tenant>")
service_client.authenticate(username="service-account@example.com", password="<secure_password>")
service_token = service_client.refresh_token
```

Always store the token and password securely. Use an environment variable or a secrets manager rather than hard-coding it in your application.

## Scope permissions to a project

To restrict the service account to specific operations within a project, pass a list of permissions using the `project_permissions` parameter in your Python script.

```python
grant = client.new_grant(
    user_id=user_id,
    type="user",
    project_permissions=["items.*", "projects.read.*"],
)

service_token = grant["refresh_token"]
```

Permissions use a dot-notation format with glob-style wildcards. For example:

- `items.*` — All item operations.
- `items.read.*` — Read-only access to items.
- `projects.read.*` — Read-only access to project metadata.

For the complete list of available permission strings and which project role grants each one, see [Permissions Reference](sc-api-permissions.md#sc-api-permissions).

> **Important**
>
> `project_permissions` acts as an **additional restriction** on the token, not a role override. The effective permissions are the intersection of what the token specifies and what the account’s server-level role already grants. For example, a `reader` account with a token scoped to `items.*` ends up with `items.read.*` — because the reader role does not include item write permissions regardless of what the token requests. Granting a broader permission in the token than the role allows has no effect.

## Restrict access to specific projects

By default, a service account with the `user` role can access all projects in the tenant. To restrict the account to specific projects, create it with the `reader` role and then add it explicitly to each allowed project using `add_project_member()` in your Python script.

```python
# Create the account with minimum server-level access
user = client.add_user(
    email="service-account@example.com",
    password="<secure_password>",
    role="reader",
)

user_id = user["id"]

# Grant access to specific projects
client.add_project_member("<project_id_1>", role="member", user_id=user_id)
client.add_project_member("<project_id_2>", role="reader", user_id=user_id)
```

The `role` parameter of `add_project_member()` controls what the service account can do within that project. The available project roles are:

- **reader** — Read-only access to project content.
- **member** — Read and write access to project content.
- **admin** — Full control over the project.

To remove access to a project, use `delete_project_member()`.

```python
client.delete_project_member(project_id="<project_id>", member_id=user_id)
```

> **Tip**
>
> You can also manage project membership through the Squirro UI under Setup → Settings → Project Members as an alternative to using the API. See [Permissions Reference](sc-api-permissions.md#sc-api-permissions) for the full list of permission strings granted by each project role, or [Squirro Roles & Permissions](../../ui/permissions.md#ui-permissions) for the UI-level permissions matrix.

## Manage existing grants

To list all grants for a service account, use `get_user_grants()` in your Python script.

```python
grants = client.get_user_grants(user_id)
print(grants["grants"])
```

To delete a grant, use `delete_grant()` in your Python script.

```python
client.delete_grant(user_id=user_id, grant_id="<grant_id>")
```

To rotate a token — for example if it has been compromised or as part of a regular rotation policy — delete the existing grant and generate a new one. Update any systems using the old token before deleting it.

```python
# Rotate an existing service token
client.delete_grant(user_id=user_id, grant_id="<old_grant_id>")

grant = client.new_grant(user_id=user_id, type="user")
new_service_token = grant["refresh_token"]
```

For a full reference of user management methods, see the [User Management](sc-api-user.md#sc-api-user) page.
