Skip to content

Beacon Grouping

Beacon grouping lets operators organize active beacons into named groups for efficient multi-beacon management. Groups carry a color label, appear as badges in the table and graph views, and serve as the unit for batch operations -- tasking, sleep changes, and exits can target an entire group in a single action.

Groups are persistent server-side objects stored in PostgreSQL. They survive beacon reconnections, relay restarts, and server reboots.

Related Features

  • Batch task execution is covered in detail in Automation & Playbooks
  • Filter presets (section below) let you save reusable beacon filter configurations that combine group membership with OS, hostname, and username filters

Overview

Capability Description
Named groups Create groups with a name, description, and color (6 preset colors)
Beacon assignment Add or remove beacons from groups via API or right-click context menu
Saved filter presets Save filter configurations (OS, hostname, username, group) for one-click reuse
Group badges Colored badges appear next to beacon hostnames in table and graph views
Batch operations Execute tasks, change sleep, or exit all beacons in a group at once

Group Management

Creating a Group

API:

curl -s -X POST "https://stentor.app/api/v1/c2/beacon-groups" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Domain Controllers",
    "description": "All DC beacons in the target domain",
    "color": "#22C55E"
  }'

Response:

{
  "id": "a1b2c3d4-...",
  "name": "Domain Controllers",
  "description": "All DC beacons in the target domain",
  "color": "#22C55E",
  "created_by": "operator-uuid",
  "created_at": "2026-02-21T12:00:00Z",
  "updated_at": "2026-02-21T12:00:00Z"
}

Available colors:

Color Hex Code
Red #EF4444
Orange #F97316
Yellow #EAB308
Green #22C55E
Blue #3B82F6 (default)
Purple #A855F7

If no color is provided, the group defaults to Blue (#3B82F6).

UI workflow: Open the cockpit toolbar and click New Group. The Group Management dialog provides fields for name, description, and a color swatch picker with the six preset colors above.

Listing Groups

curl -s "https://stentor.app/api/v1/c2/beacon-groups" \
  -H "Authorization: Bearer $TOKEN"

Returns an array of all groups, ordered by creation date (newest first).

Updating a Group

curl -s -X PUT "https://stentor.app/api/v1/c2/beacon-groups/$GROUP_ID" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "DCs - Primary",
    "description": "Primary domain controllers only",
    "color": "#A855F7"
  }'

All three fields (name, description, color) are sent on update. The name field is required.

UI workflow: In the Group Management dialog, click the edit icon next to an existing group to open the edit form with pre-populated values.

Deleting a Group

curl -s -X DELETE "https://stentor.app/api/v1/c2/beacon-groups/$GROUP_ID" \
  -H "Authorization: Bearer $TOKEN"

Returns 204 No Content on success. Deleting a group cascade-deletes all membership records -- beacons themselves are not affected, only the group association is removed.


Beacon Assignment

Adding Beacons to a Group

Assign one or more beacons to a group in a single request:

curl -s -X POST "https://stentor.app/api/v1/c2/beacon-groups/$GROUP_ID/beacons" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "beacon_ids": [
      "beacon-uuid-1",
      "beacon-uuid-2",
      "beacon-uuid-3"
    ]
  }'

Response:

{
  "status": "added"
}

Duplicate assignments are silently ignored (upsert behavior).

UI workflow: Right-click a beacon row in the cockpit table, select Assign to Group from the context menu, then choose the target group. Multiple beacons can be selected first for bulk assignment.

Removing Beacons from a Group

Remove beacons from a group using DELETE with a request body containing the beacon IDs:

curl -s -X DELETE "https://stentor.app/api/v1/c2/beacon-groups/$GROUP_ID/beacons" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "beacon_ids": [
      "beacon-uuid-1"
    ]
  }'

Response:

{
  "status": "removed"
}

Bulk Removal

The removal endpoint accepts an array of beacon IDs for bulk removal in a single request. There is no per-beacon removal path parameter.

Listing Group Members

Retrieve a group along with its member beacon IDs using the single-group endpoint:

curl -s "https://stentor.app/api/v1/c2/beacon-groups/$GROUP_ID" \
  -H "Authorization: Bearer $TOKEN"

Response:

{
  "id": "a1b2c3d4-...",
  "name": "Domain Controllers",
  "description": "All DC beacons in the target domain",
  "color": "#22C55E",
  "created_by": "operator-uuid",
  "created_at": "2026-02-21T12:00:00Z",
  "updated_at": "2026-02-21T12:00:00Z",
  "beacon_ids": [
    "beacon-uuid-1",
    "beacon-uuid-2",
    "beacon-uuid-3"
  ]
}

The beacon_ids array contains the UUIDs of all beacons currently assigned to the group. There is no separate /beacons GET sub-route -- member IDs are embedded in the group detail response.


Saved Filter Presets

Filter presets save a named combination of beacon list filters for one-click reuse. Presets can filter by OS, hostname, username, and group membership.

Creating a Preset

curl -s -X POST "https://stentor.app/api/v1/c2/filter-presets" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Windows DCs",
    "filters": {
      "os": "windows",
      "hostname": "DC",
      "username": "",
      "group_id": "a1b2c3d4-..."
    }
  }'

Response:

{
  "id": "preset-uuid",
  "name": "Windows DCs",
  "filters": {
    "os": "windows",
    "hostname": "DC",
    "username": "",
    "group_id": "a1b2c3d4-..."
  },
  "created_by": "operator-uuid",
  "created_at": "2026-02-21T12:00:00Z",
  "updated_at": "2026-02-21T12:00:00Z"
}

The filters object is stored as JSON and can contain any combination of filter keys. Empty strings or omitted keys are treated as "no filter" for that field.

Listing Presets

curl -s "https://stentor.app/api/v1/c2/filter-presets" \
  -H "Authorization: Bearer $TOKEN"

Returns all saved presets, ordered by creation date (newest first).

Applying a Preset

UI workflow: Saved presets appear in the filter bar above the beacon table. Click a preset name to instantly apply its saved filter configuration. The beacon list updates to show only matching beacons.

Updating a Preset

curl -s -X PUT "https://stentor.app/api/v1/c2/filter-presets/$PRESET_ID" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Windows DCs (updated)",
    "filters": {
      "os": "windows",
      "hostname": "DC0",
      "username": "",
      "group_id": "a1b2c3d4-..."
    }
  }'

Deleting a Preset

curl -s -X DELETE "https://stentor.app/api/v1/c2/filter-presets/$PRESET_ID" \
  -H "Authorization: Bearer $TOKEN"

Returns 204 No Content on success.


Group Badges

Table View

Groups appear as colored badges next to each beacon's hostname in the beacon table. The badge background color matches the group's configured color. If a beacon belongs to multiple groups, multiple badges are displayed side by side.

Graph View

In the pivot graph (cockpit graph view), each MachineNode displays a group badge overlay. Beacons in multiple groups show stacked badges to indicate all group memberships at a glance.

Visual Identification

Use distinct colors for each group (e.g., Red for high-value targets, Green for domain controllers, Blue for workstations) to quickly identify beacon categories in both table and graph views.


Group Batch Operations

Batch operations let you dispatch a task to every beacon in a group with a single API call or UI action. The endpoint iterates over all group members, enqueues the task for each active beacon, and returns a summary of dispatched and failed deliveries.

API endpoint:

POST /api/v1/c2/beacon-groups/:id/batch-task

Task All Beacons in a Group

Execute a shell command on every beacon in a group:

curl -s -X POST "https://stentor.app/api/v1/c2/beacon-groups/$GROUP_ID/batch-task" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "shell",
    "data": {
      "method": "exec",
      "params": {
        "command": "whoami"
      }
    }
  }'

Response:

{
  "dispatched": 3,
  "failed": 0,
  "errors": [],
  "group_id": "a1b2c3d4-...",
  "beacon_ids": ["beacon-uuid-1", "beacon-uuid-2", "beacon-uuid-3"]
}

The dispatched count indicates successful task enqueues. The failed count and errors array report beacons that could not receive the task (e.g., beacon not found in the active registry).

Sleep All Beacons in a Group

Set the sleep interval and jitter for all beacons in a group:

curl -s -X POST "https://stentor.app/api/v1/c2/beacon-groups/$GROUP_ID/batch-task" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "state",
    "data": {
      "method": "sleep",
      "params": {
        "sleep": 60,
        "jitter": 10
      }
    }
  }'

Exit All Beacons in a Group

Terminate all beacons in a group:

curl -s -X POST "https://stentor.app/api/v1/c2/beacon-groups/$GROUP_ID/batch-task" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "exit",
    "data": {
      "method": "exit",
      "params": {}
    }
  }'

Destructive Operation

Exiting all beacons in a group is irreversible. The UI requires explicit confirmation before dispatching the exit command. All beacons in the group will cleanly self-terminate.

UI workflow: The Group Batch Dialog provides three operation modes accessible from the group context menu:

Operation UI Button Description
Task Execute Choose task type (Shell, PowerShell, PowerShell Import, Run, Execute) and enter a command
Sleep Set Sleep Enter sleep interval (seconds) and jitter percentage (0--99)
Exit Exit All Confirm destructive exit for all beacons in the group

For detailed batch task execution patterns and scheduled playbooks, see Automation & Playbooks.


REST API Summary

Method Endpoint Description
POST /api/v1/c2/beacon-groups Create a new group
GET /api/v1/c2/beacon-groups List all groups
GET /api/v1/c2/beacon-groups/:id Get group details with member beacon IDs
PUT /api/v1/c2/beacon-groups/:id Update a group
DELETE /api/v1/c2/beacon-groups/:id Delete a group (cascade-deletes memberships)
POST /api/v1/c2/beacon-groups/:id/beacons Add beacons to a group
DELETE /api/v1/c2/beacon-groups/:id/beacons Remove beacons from a group
POST /api/v1/c2/beacon-groups/:id/batch-task Dispatch a task to all beacons in a group
POST /api/v1/c2/filter-presets Create a filter preset
GET /api/v1/c2/filter-presets List all filter presets
PUT /api/v1/c2/filter-presets/:id Update a filter preset
DELETE /api/v1/c2/filter-presets/:id Delete a filter preset