> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.itential.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.itential.com/_mcp/server.

# Administer Itential Platform

> Routine administration and maintenance procedures for Itential Platform, including health checks, service management, adapter and application administration, job management, and log management.

Itential Platform on-prem runs on Linux with [systemd](https://systemd.io/). Procedures that modify state, restart services, or alter data are marked with a warning and should be scheduled and confirmed before you run them in production.

## Before you begin

The examples in this guide authenticate using a dedicated admin service account rather than a personal user account. A service account isn't tied to an individual and doesn't break when a team member leaves or rotates their password, which makes it the right credential for scripted administration and maintenance tasks.

For information about creating a service account, see [Service accounts](https://docs.itential.com/itential-platform/6/admin-essentials/authorization#service-accounts). Or, to create a service account using the API, see [Create a service account in the database](https://docs.itential.com/itential-platform/6/6/api-reference/oauth/create-service-account).

### Create an admin client

Platform service accounts are OAuth2 clients managed under **Admin Essentials > Authorization > Clients**.

#### Open Clients

Navigate to **Admin Essentials > Authorization > Clients** in the Platform UI and click **Add Client**.

#### Configure the client

Set the client name to something that identifies its purpose, such as `platform-admin`. Set the grant type to **Client Credentials**. Assign the client a role with `admin` permission so that it can perform the operations covered in this guide: adapter management, application management, worker control, job management, and user management.

For information about setting roles, see [Roles](/itential-platform/admin-essentials/authorization#roles).

#### Save the client

Save the client and copy the generated client ID and client secret.

Store the client secret in your secrets manager immediately. It can't be retrieved again after the creation screen is closed.

### Store and use the client secret

Store the client secret in your secrets manager before proceeding. All credentials must be managed through your secrets manager. Never store them in scripts or configuration files.

**Example using HashiCorp Vault:**

```bash
vault kv put <platform-credentials-path> \
  platformClientId="<client-id>" \
  platformClientSecret="<client-secret>"
```

Retrieve the credentials at runtime and cache the bearer token locally to avoid repeated calls during a maintenance session. Tokens issued by Platform are valid for approximately 60 minutes.

```bash
# Retrieve the service account credentials from your secrets manager.
# Example using HashiCorp Vault:
PLATFORM_CLIENT_ID=$(curl -s -X GET \
  -H "X-Vault-Token: $VAULT_TOKEN" \
  "$VAULT_ADDR/<platform-credentials-path>" \
  | jq -r '.data.data.platformClientId')

PLATFORM_CLIENT_SECRET=$(curl -s -X GET \
  -H "X-Vault-Token: $VAULT_TOKEN" \
  "$VAULT_ADDR/<platform-credentials-path>" \
  | jq -r '.data.data.platformClientSecret')

# Fetch and cache the Platform bearer token to /tmp/.platform_token.
# Skip the login call if a cached token less than 60 minutes old exists.
if [ ! -f /tmp/.platform_token ] || \
   [ $(( $(date +%s) - $(stat -c %Y /tmp/.platform_token) )) -gt 3600 ]; then
  curl -sk -X POST "https://$PLATFORM_HOST/oauth/token" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -H "accept: application/json" \
    -d "grant_type=client_credentials&client_id=$PLATFORM_CLIENT_ID&client_secret=$PLATFORM_CLIENT_SECRET" \
    | jq -r '.access_token' > /tmp/.platform_token
fi

PLATFORM_TOKEN=$(cat /tmp/.platform_token)
```

Replace `$PLATFORM_HOST` with the hostname or IP address of your Platform node. In [high-availability](/itential-platform/plan/architecture/high-availability) (HA) deployments, use the load balancer address for read-only queries (health checks, listing) and the address of an individual Platform node for write operations (adapter restarts, worker control).

## Check health and status

Check Platform's health before any maintenance activity to establish a baseline, and again afterward to confirm the work didn't introduce a regression.

### Check Platform health

The [/health/status](/itential-platform/6/6/api-reference/health/get-health-status) endpoint is the only unauthenticated Platform route and the fastest way to confirm Platform is up.

```bash
curl -s -X GET "https://$PLATFORM_HOST/health/status" | jq .
```

### Check adapter health

The [/health/adapters](/itential-platform/6/6/api-reference/health/get-adapters-health) endpoint returns the health of every adapter and requires authentication. Each adapter has a `state` field (`RUNNING`, `STOPPED`, or `DEAD`) and a nested `connection.state` field (`ONLINE` or `OFFLINE`). A fully healthy adapter shows `state: RUNNING` and `connection.state: ONLINE`.

Pipe the response through `jq` to get just the fields you care about, or to filter for adapters that aren't fully healthy:

```bash
# List all adapters with state and connection status
curl -sk -X GET "https://$PLATFORM_HOST/health/adapters" \
  -H "Authorization: Bearer $PLATFORM_TOKEN" \
  -H "accept: application/json" \
  | jq '.results[] | {id, state, connection: .connection.state}'

# Filter for adapters that aren't fully healthy
curl -sk -X GET "https://$PLATFORM_HOST/health/adapters" \
  -H "Authorization: Bearer $PLATFORM_TOKEN" \
  -H "accept: application/json" \
  | jq '.results[] | select(.state != "RUNNING" or .connection.state != "ONLINE") | {id, state, connection: .connection.state}'
```

### Check application health

The [/health/applications](/itential-platform/6/6/api-reference/health/get-applications-health) endpoint returns the health of every Platform application. Applications don't have a `connection.state` field.

```bash
curl -sk -X GET "https://$PLATFORM_HOST/health/applications" \
  -H "Authorization: Bearer $PLATFORM_TOKEN" \
  -H "accept: application/json" \
  | jq '.results[] | select(.state != "RUNNING") | {id, state}'
```

### Check the Platform version

Confirm the running [version](/itential-platform/6/6/api-reference/authentication/get-release-version) before applying patches, opening a support case, or verifying a completed upgrade. The version returned reflects the actively running process, not the installed package.

```bash
curl -sk -X GET "https://$PLATFORM_HOST/version" \
  -H "Authorization: Bearer $PLATFORM_TOKEN" \
  -H "accept: application/json" \
  | jq .
```

## Manage the Platform service

Platform runs as the `itential-platform` systemd service on Linux. In HA deployments, restart one node at a time and confirm the health endpoint returns `200` on each node before proceeding to the next. Restarting all nodes simultaneously causes a full outage.

### Check service status

```bash
systemctl status itential-platform
```

The `Active:` line should read `active (running)`. Investigate anything else before making further changes.

### Restart the service

Restarting Platform drops all active API connections and interrupts any in-flight API calls. In production, deactivate the workflow engine workers and drain active jobs first, see [Shut down Platform safely](#shut-down-platform-safely).

```bash
sudo systemctl restart itential-platform
```

Poll the health endpoint until Platform responds. This typically takes 30 to 120 seconds:

```bash
for i in $(seq 1 24); do
  STATUS=$(curl -s -X GET -o /dev/null -w "%{http_code}" "https://$PLATFORM_HOST/health/status")
  if [ "$STATUS" = "200" ]; then
    echo "Platform is healthy after $((i * 5)) seconds"
    break
  fi
  echo "Waiting... attempt $i/24"
  sleep 5
done
```

### Start and stop the service

```bash
sudo systemctl stop itential-platform
sudo systemctl start itential-platform
```

## Shut down Platform safely

An uncontrolled shutdown can leave jobs in a `running` state with no process to advance them, and can leave automation targets partially configured if a workflow is interrupted mid-execution. A controlled shutdown suspends job intake, lets in-progress work settle, and then stops the service cleanly.

The worker deactivation calls in this procedure must target individual Platform nodes, not the load balancer. In HA deployments, run each step on every node.

#### Deactivate the workflow engine workers

Deactivating the job and task workers stops Platform from starting or advancing jobs. Any job already in progress remains in its current state but doesn't progress further.

```bash
curl -sk -X POST "https://$PLATFORM_HOST/workflow_engine/deactivate" \
  -H "Authorization: Bearer $PLATFORM_TOKEN" -H "accept: application/json" -d ''

curl -sk -X POST "https://$PLATFORM_HOST/workflow_engine/jobWorker/deactivate" \
  -H "Authorization: Bearer $PLATFORM_TOKEN" -H "accept: application/json" -d ''
```

#### Wait for running jobs to settle

Poll the running job count. For non-critical maintenance windows, wait for this count to reach zero to avoid canceling jobs.

```bash
curl -sk -X GET \
  "https://$PLATFORM_HOST/operations-manager/tasks?skip=0&order=1&sort=name&actionableTasks=false" \
  -H "Authorization: Bearer $PLATFORM_TOKEN" -H "accept: application/json" \
  | jq '{total: .metadata.total, running: (.data | length)}'
```

Re-poll until `total` reaches `0`. If tasks remain stuck, review them before canceling, see [Manage jobs](#manage-jobs).

#### Cancel remaining jobs if the window is too short

Don't cancel jobs in production if you can avoid it. Canceling terminates in-progress automation workflows and can leave managed systems partially configured. Prefer waiting for jobs to drain naturally.

If the maintenance window doesn't allow time to wait, cancel running jobs through `/operations-manager/jobs/cancel`, which accepts a list of job IDs. Retrieve running job IDs from `/operations-manager/jobs?status=running` first, then submit them in batches. Canceling a large batch through the API is slow; if the backlog is large, consider whether the maintenance window is realistic or whether the work should wait for the queue to drain.

#### Stop the service

```bash
sudo systemctl stop itential-platform
```

#### Verify shutdown

```bash
systemctl status itential-platform
```

The `Active:` line should show `inactive (dead)`.

## Manage adapters

Adapters connect Platform to external systems such as network devices, ticketing platforms, and cloud APIs. Knowing how to inspect, stop, start, and restart adapters without a full Platform restart resolves connectivity issues without impacting unrelated workflows.

Adapter management calls must target individual Platform nodes, not the load balancer. In HA deployments, run each command on every node.

### List and check adapters

`/health/adapters` returns runtime state; `/adapters` returns configuration data, not status. Use the adapter-specific health endpoint to see connection error counts and the last connection attempt before deciding whether to restart:

```bash
ADAPTER_ID="<adapter-name>"
curl -sk -X GET "https://$PLATFORM_HOST/health/adapters/$ADAPTER_ID" \
  -H "Authorization: Bearer $PLATFORM_TOKEN" -H "accept: application/json" | jq .
```

### Stop, start, and restart an adapter

Stopping an adapter breaks its connection to the target system. Any workflow step that depends on it fails until the adapter is restarted. Stop an adapter only to modify its configuration or isolate a connectivity problem.

```bash
# Replace <action> with: stop, start, or restart
curl -sk -X PUT "https://$PLATFORM_HOST/adapters/$ADAPTER_ID/<action>" \
  -H "Authorization: Bearer $PLATFORM_TOKEN" \
  -H "accept: application/json" \
  -H "Content-Type: application/json"
```

Always confirm the adapter reached the expected state afterward. A successful API call doesn't guarantee it:

```bash
curl -sk -X GET "https://$PLATFORM_HOST/health/adapters/$ADAPTER_ID" \
  -H "Authorization: Bearer $PLATFORM_TOKEN" -H "accept: application/json" \
  | jq '{id: .id, state: .state, connection: .connection.state}'
```

Expected output after a start or restart: `"state": "RUNNING"`.

## Manage applications

Platform applications provide capabilities such as Operations Manager, Studio workflows, and other licensed features. An application in an error state can block workflow execution or Platform functionality independent of whether the Platform process itself is healthy.

Application management calls must target individual Platform nodes, not the load balancer. In HA deployments, run each command on every node.

Applications share the `/adapters/<id>/start|stop|restart` endpoints used by adapters, substituting the application ID:

```bash
APP_ID="<application-name>"

# Check health
curl -sk -X GET "https://$PLATFORM_HOST/health/applications/$APP_ID" \
  -H "Authorization: Bearer $PLATFORM_TOKEN" -H "accept: application/json" | jq .

# Restart
curl -sk -X PUT "https://$PLATFORM_HOST/adapters/$APP_ID/restart" \
  -H "Authorization: Bearer $PLATFORM_TOKEN" \
  -H "accept: application/json" -H "Content-Type: application/json"
```

Stopping an application makes its functionality unavailable to all users and workflows. Confirm no active workflows depend on it before stopping.

Restarting an individual application is less disruptive than restarting the full Platform service and is often enough to recover from an error state without affecting other applications or adapters.

## Manage the workflow engine

The workflow engine has two workers, a task worker that processes individual automation steps, and a job worker that manages the overall job lifecycle. Pausing and resuming these workers without restarting the Platform service is a key tool for maintenance windows, upgrades, and controlled drains.

Worker management calls must target individual Platform nodes, not the load balancer. In HA deployments, activate or deactivate workers on each node separately.

### Check worker status

```bash
curl -sk -X GET "https://$PLATFORM_HOST/workflow_engine/workers/status" \
  -H "Authorization: Bearer $PLATFORM_TOKEN" -H "accept: application/json" \
  | jq '{jobWorker: .jobWorker.running, taskWorker: .taskWorker.running}'
```

Example response:

```json
{
  "jobWorker":  { "running": true,  "clusterValue": "not defined", "localValue": "enabled", "startupValue": true },
  "taskWorker": { "running": false, "clusterValue": "not defined", "localValue": "enabled", "startupValue": true }
}
```

### Activate and deactivate workers

```bash
# Task worker
curl -sk -X POST "https://$PLATFORM_HOST/workflow_engine/<activate-or-deactivate>" \
  -H "Authorization: Bearer $PLATFORM_TOKEN" -H "accept: application/json" -d ''

# Job worker
curl -sk -X POST "https://$PLATFORM_HOST/workflow_engine/jobWorker/<activate-or-deactivate>" \
  -H "Authorization: Bearer $PLATFORM_TOKEN" -H "accept: application/json" -d ''
```

Deactivating the task worker halts task execution without canceling jobs, letting in-progress tasks complete before the worker stops pulling new work. Deactivating the job worker stops Platform from starting new jobs while the task worker continues executing tasks that are already running.

## Manage jobs

Jobs left `running` during a maintenance window can block upgrades, leave automation targets partially configured, and complicate post-maintenance health checks.

### Count and list active jobs

```bash
# Count
curl -sk -X GET "https://$PLATFORM_HOST/operations-manager/jobs?status=running&limit=1" \
  -H "Authorization: Bearer $PLATFORM_TOKEN" -H "accept: application/json" \
  | jq '{total: .metadata.total, running: (.data | length)}'

# List (review before canceling anything)
curl -sk -X GET "https://$PLATFORM_HOST/operations-manager/jobs?status=running&limit=100" \
  -H "Authorization: Bearer $PLATFORM_TOKEN" -H "accept: application/json" \
  | jq '[.data[].name]'
```

### Cancel active jobs

Canceling jobs interrupts in-progress automation workflows. Know what you're stopping before you stop it.

`/operations-manager/jobs/cancel` accepts a list of job IDs (`jobIds`) in the request body. Retrieve IDs from `/operations-manager/jobs?status=running`, then submit them in batches. Canceling through the API is slow; for large queues, waiting for jobs to drain naturally is usually more reliable within a tight maintenance window.

Verify the count reached `0` after cancellation using the count query above.

## Manage data retention

Platform stores every job, task, and associated log event in MongoDB. Without a retention policy, the `itential` database grows without bound, degrading query performance and consuming disk space.

Each executed job produces documents across the `jobs` and `tasks` collections and others. These collections carry compound indexes that support Operations Manager query patterns; as they grow, index size grows proportionally, increasing memory pressure on MongoDB nodes.

Itential maintains an open source [job and task archiver](https://github.com/itential/job-and-task-archiver) that connects directly to MongoDB and supports archive mode (copy then delete) and delete mode. Refer to the repository for installation, configuration, and minimum required MongoDB permissions.

Run the archiver on a recurring schedule during off-peak hours:

```bash
# Run nightly at 02:00, retaining data from the last 90 days
0 2 * * * /usr/local/bin/job-and-task-archiver \
  --retention-days 90 \
  >> /var/log/job-archiver.log 2>&1
```

Coordinate the retention window with your operations team before reducing it below 30 days; some compliance frameworks require a minimum audit trail period. After a run, confirm collection sizes decreased (see [Administer MongoDB](/itential-platform/administer/mongodb) for compaction and storage diagnostics). Stable or growing sizes indicate the archiver isn't connecting, is misconfigured, or hit errors.

For broader backup and retention policy guidance across Platform and Gateway, see [Archive and purge data](/itential-platform/maintain/archive-purge-data).

## Manage logs

Platform writes application logs to `/var/log/itential/platform/`. Each running application and adapter produces its own log file in that directory. General Platform messages go to `itential.log`.

| Log type                  | Location                                            |
| ------------------------- | --------------------------------------------------- |
| General Platform messages | `/var/log/itential/platform/itential.log`           |
| Per-application log       | `/var/log/itential/platform/<application-name>.log` |
| Per-adapter log           | `/var/log/itential/platform/<adapter-name>.log`     |
| Web server access log     | `/var/log/itential/platform/webserver.log`          |

Start with the log file for the specific application or adapter you're investigating. If those files don't contain enough information, `journalctl` is a secondary source for process-level output:

```bash
journalctl -u itential-platform -n 100 --no-pager
journalctl -u itential-platform -f
journalctl -u itential-platform -p err -n 200 --no-pager
```

The web server log records every HTTP request Platform receives. Use it to identify high-volume clients, error rates by endpoint, or latency spikes:

```bash
grep ' 5[0-9][0-9] ' /var/log/itential/platform/webserver.log | tail -50
```

For more information about logging, see [Logging overview](/itential-platform/6/monitor/log/overview).

### Adjust the log level

Platform supports log levels from least to most verbose: `error`, `warn`, `info`, `verbose`, `debug`, `trace`. The production default is `info`. `debug` and `trace` produce significant log volume and degrade performance; don't leave them enabled after a troubleshooting session.

Log levels are set per adapter or application in its service config, not in a single platform-wide file. Retrieve the config to inspect or update it:

```bash
curl -s -X GET "https://$PLATFORM_HOST/adapters/<adapter-name>" \
  -H "Authorization: Bearer $PLATFORM_TOKEN" -H "accept: application/json" | jq .

curl -s -X PUT "https://$PLATFORM_HOST/adapters/<adapter-name>/loglevel" \
  -H "Authorization: Bearer $PLATFORM_TOKEN" \
  -H "accept: application/json" -H "Content-Type: application/json" \
  -d '{"properties": {"transport": "file", "level": "debug"}}'
```

Remember to restore the level to `info` after the troubleshooting session ends.

For more information about log levels, see [Configure logging](/itential-platform/6/monitor/log/configure#log-level-and-output).

### Configure log rotation

Rotation for each adapter and application is configured in its service config via the `loggerProps` block:

| Field                                                         | Description                                                       |
| ------------------------------------------------------------- | ----------------------------------------------------------------- |
| `log_max_files`                                               | Maximum number of log files retained before the oldest is removed |
| `log_max_file_size`                                           | Maximum size in bytes of a single log file before rotation        |
| `log_directory`, `log_filename`, `log_level`, `console_level` | Other relevant fields                                             |

```json
"loggerProps": {
  "log_max_files": 100,
  "log_max_file_size": 1048576,
  "log_level": "info",
  "log_directory": "/var/log/itential/platform",
  "log_filename": "<adapter-or-application-name>.log",
  "console_level": "warn",
  "syslog": {
    "level": "warning",
    "host": "localhost",
    "port": 514,
    "protocol": "udp4",
    "facility": "local0",
    "type": "BSD",
    "path": "/dev/log",
    "localhost": "localhost"
  }
}
```

See [Manage logs](/itential-platform/monitor/log/manage) for centralized log collection with Loki or the Elastic Stack.

## Rotate credentials

Platform is designed to integrate with enterprise identity providers over SSO or LDAP. In an enterprise deployment, user lifecycle management such as provisioning, deprovisioning, and credential rotation, is handled by the identity provider, not directly within Platform. This is the recommended approach. It ensures access is governed by the same policies and audit controls that apply to every other enterprise system.

Platform ships with a default local admin account used during initial installation and configuration. After SSO or LDAP integration is established and verified, disable this account. An active local admin account after SSO is in place creates an unaudited access path that bypasses your identity provider's controls.

Coordinate credential or access changes with your identity provider administrators rather than managing them directly in Platform.

## Manage role-based access control

Platform uses role-based access control (RBAC) to govern which users can view, execute, and manage Platform resources. RBAC configuration, users, groups, roles, and permissions, is best managed through the Platform UI rather than the API, which provides a complete view of the permission hierarchy and reduces the risk of misconfiguration.

RBAC administration is found under **Admin Essentials > Authorization**. For the full permission model and step-by-step instructions, see [Authorization](/itential-platform/admin-essentials/authorization).

## Related resources

* For installation and configuration properties, see [Configure Platform](/itential-platform/configure/platform).
* For log rotation, log levels, and centralized logging with Loki and Elastic Stack, see [Monitor Itential](/itential-platform/monitor/monitor-itential).
* For backup, archiving, and retention policy guidance, see [Archive and purge data](/itential-platform/maintain/archive-purge-data).