Skip to content

Known Limitations

Bubori Attila edited this page Aug 11, 2026 · 3 revisions

Known Limitations & Design Decisions

This page documents intentional design trade-offs and known, currently-unaddressed limitations — so future work doesn't waste time re-discovering or re-litigating the same questions.


The API Token does not identify a specific machine

This is by design, not a bug. The API Token (see [Client-Server Communication](Client Server Communication)) only answers "is this sender authorized?" — it carries no per-machine identity. Workstation identity is established completely separately, via hardware fingerprinting (product serial, motherboard serial, UUID, MAC address) in identifyWorkstation().

Implication: the same token can safely be shared across many workstations (e.g. one token per deployment batch/site when mass-deploying via tools like Faronics Deploy) without weakening machine identity — a shared token doesn't let one workstation impersonate another's data, since identity is derived independently.

Trade-off: revoking a shared token cuts off every workstation using it simultaneously (they'll show as "Unreachable" after ~121s), not just one. See Recovery after revoking a token below.

Token → workstation binding is first-use-only

api_tokens.tokenable_id is set once, on the first request that includes a real wsid using that token — it is never updated afterwards. If a token is shared across N workstations, tokenable_id will only ever show the first one, not a full list.

If accurate per-token usage tracking is ever needed: this would require a new log table (e.g. api_token_usages, storing token_id + wsid + timestamp per request) rather than a single mutable column. Not currently implemented.

Recovery after revoking a shared token

Because the Console channel (port 8080) authenticates with a separate per-workstation AES key (ws_keys), it is independent of the API Token. A workstation whose API Token was revoked can still be reached via Console (if it's on a registered LAN subnet and its Windows Firewall allows inbound 8080), and sent a Change-Token command to restore reporting — without re-running the installer.

This only works if the workstation is Console-reachable at the time of recovery. There is currently no way to update a client's token remotely if it's not Console-reachable (e.g. different subnet, firewall blocking 8080) other than re-running the installer.

Console tab visibility depends on a registered subnet

The Console tab on a workstation's page is only shown if WorkstationsController::isIPInSubnet() finds a matching entry in the subnets table (IP Table → New Subnet). If no subnet has been registered at all, the Console tab never appears for any workstation, regardless of actual network reachability — this is a manual setup step, not automatic network detection.

Console channel uses a fixed AES IV

Both the client (Service1.cs) and server (WorkstationsController::command()) use a hardcoded, constant IV (0x30 repeated 16 times) for AES-256-CBC encryption on the Console channel, instead of a fresh random IV per message. This is a known cryptographic weakness (reused IVs in CBC mode can leak plaintext patterns across messages encrypted with the same key) — not currently fixed. Given this channel carries remote command execution, this is the highest-priority item on this list to address.

No firewall rule is created automatically

Neither the Windows MSI installer nor the client itself creates a Windows Firewall inbound rule for port 8080. Without one, the Windows Firewall silently drops inbound Console connection attempts (rather than actively refusing them), which shows up as a ~15 second hang before failing — see [Client-Server Communication](Client Server Communication) for the exact symptom. For mass deployments, it's worth adding a firewall rule as part of the deployment script/package rather than relying on manual per-machine setup.

network_edges and other per-workstation rows require explicit cleanup on delete

There is no database-level cascading delete (ON DELETE CASCADE) between workstations and its related tables (ws_events, ws_ips, network_edges, ws_keys, etc.) — cleanup is done explicitly, row by row, in WorkstationsController::archiveWorkstation(). This means any new per-workstation table added in the future must also be added to that cleanup list manually, or it will silently accumulate orphaned rows. As of now, all ws_* tables and network_edges (both source and target directions) are covered.

Migrations are not always chronologically ordered by filename

Several early migrations (e.g. create_workstations_table.php) do not use Laravel's usual timestamp-prefixed filename convention, and instead rely on plain alphabetical ordering. Newer migrations that depend on an older, non-timestamped migration (e.g. adding a column to a table created elsewhere) must be named carefully so that plain alphabetical sort still produces the correct dependency order — timestamp-prefixing a new migration does not guarantee it runs after a non-timestamped one (digits sort before letters in ASCII). See existing examples: create_apitokens_table_token_hash.php, create_workstations_table_ws_user_accounts_is_admin.php.

Clone this wiki locally