---
title: Activate a session and run commands
description: Open a time-boxed remote-support session on an enrolled agent and run the allowlisted diagnostic commands.
---

# Activate a session and run commands



## Goal

Open a remote-support session against one specific agent and run diagnostic commands: tail its log, read an allowlisted file, get version and camera info, refresh its capability manifest, or apply a signed hotfix patch.

## Prerequisites

* **The full 3-factor operator gate**, all independent and all mandatory:

  1. Caller IP inside `REMOTE_SUPPORT_OPERATOR_CIDRS` (the operator network).
  2. The `X-Argus-Ops-Token` second factor matching `ARGUS_OPS_TOKEN` (pass `--ops-token` or export `ARGUS_OPS_TOKEN`).
  3. A PAT with the `remote_support` scope.

  `REMOTE_SUPPORT_ENABLED` must also be on server-side. Drop any factor and the request 403s.
* The tenant is armed and has signed consent. Activation hard-fails with `tenant_consent_required` otherwise; there is no override.
* The agent is **enrolled and online** (holding its outbound WebSocket). You cannot activate an offline agent.
* A reason for the audit trail.

Optional pre-check without opening a session: the agent's capability manifest is readable with operator auth alone (`GET /support/agents/{id}/capabilities`). A `stale: true` flag means the snapshot is old or the agent is offline.

## Steps: argusctl

```bash
# 1. Find the agent
argusctl agent ls --tenant UTD_7ELEVEN_001

# 2. Activate (returns a show-once session token)
argusctl agent activate agent_macpro_lobby_01 --tenant UTD_7ELEVEN_001 \
  --reason "investigate alert"

# 3. Run commands with the session token
argusctl support command UTD_7ELEVEN_001 --session rst_... --command ping
argusctl support command UTD_7ELEVEN_001 --session rst_... --command agent_info
argusctl support command UTD_7ELEVEN_001 --session rst_... --command tail_log --args '{"lines":200}'
argusctl support command UTD_7ELEVEN_001 --session rst_... --command read_file --args '{"path":"config.yaml"}'
```

The `support activate` spelling hits the same endpoint. Every write supports `--dry-run` (redacted request preview).

**The session token is shown once.** Save it; it is never re-fetchable. Every subsequent command requires it.

### Allowlisted commands and their guards

* `ping`, `agent_info`, `get_capabilities`: read-only status and metadata.
* `tail_log` / `read_file`: paths resolve relative to the agent install root and must match an exact allowlist (`argus.log` and rotated copies, `config.yaml`, `version.txt`, `agent_info.json`, `crashes/*.txt`). Anything else returns `path_not_allowlisted` with no IO performed.
* `apply_patch`: the only write path. Patches must carry a valid Ed25519 signature from the offline ARGUS signing key, target only the patch allowlist, and sit inside a `not_before`/`not_after` window; replayed patch IDs, mode changes, and signature mismatches are rejected and audited.

There is no remote command line and no arbitrary process invocation. Allowlist changes ship only via an agent update, never hot-pushed.

### Session lifetime

Default 30 minutes, hard cap 120 minutes (in code, not env-overridable). End it early with deactivate, or the tenant-side kill switch (`argus-agent remote-support-off`), or by disarming the tenant. Any of these writes `remote_support_session_ended` to audit. On `session_expired`, re-activate.

## Steps: Operations Console

The console's Tunnel In modal provides a guided CLI command for the activation flow above, plus an optional one-click button when the browser path is enabled (next section). When the server flag is off, the button shows a "not enabled yet" hint.

## One-click browser tunnel-in

An optional path lets an operator activate straight from the Operations Console without being on the operator network. A cryptographically verified Cloudflare Access assertion stands in for **factor 1 only** (the IP allowlist): the assertion is RS256-verified against the team JWKS with mandatory `aud`/`iss`/`exp` checks, the ops API independently re-verifies it, and the verified Access identity must match the PAT owner (a leaked PAT cannot be driven under another operator's name). Factors 2 and 3 are unchanged and still mandatory.

It is **default off** and inert until all of these are set on the ops API: `REMOTE_SUPPORT_ALLOW_CF_ASSERTION` (master switch), `CF_ACCESS_AUD`, `CF_ACCESS_TEAM_DOMAIN` (must be a `*.cloudflareaccess.com` host), and at least one of `REMOTE_SUPPORT_CF_ALLOWED_EMAILS` / `REMOTE_SUPPORT_CF_ALLOWED_DOMAINS` (the gate 503s, fail-closed, if the allowlist is empty). The console-side proxy additionally needs `ARGUS_OPS_TOKEN` so it can inject factor 2 server-side; the token is never sent to the browser. The proxy forwards only named actions (`activate` / `deactivate` / `status`), never a caller-supplied path.

## Troubleshooting

| Error                                                   | Meaning                                                                                                                                                                                                               |
| ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `409 agent_offline`                                     | The agent is not holding its outbound WebSocket. Also returned, by design, when no agent has enrolled a passkey yet. Check the agent is running and has network; activation against an offline agent is not possible. |
| `ip_not_allowlisted` / `bad_ops_token` / `missing_role` | A specific factor of the 3-factor gate failed.                                                                                                                                                                        |
| `tenant_consent_required`                               | No signed consent on record. Do not proceed.                                                                                                                                                                          |
| `session_not_found` / `session_expired`                 | Re-activate.                                                                                                                                                                                                          |
| `path_not_allowlisted` / `patch_target_not_allowlisted` | The path is outside the fixed allowlist; needs an agent update, not a workaround.                                                                                                                                     |
| `patch_signature_invalid`                               | The patch was not signed by the offline key. Re-sign it.                                                                                                                                                              |


---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)

For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)