Skip to content

feat: machine-id firewall header — bundled mesh core (Host fix) + openframe-client - #1688

Open
mikhailm-coder wants to merge 7 commits into
mainfrom
hotfix/machine-id-header
Open

feat: machine-id firewall header — bundled mesh core (Host fix) + openframe-client#1688
mikhailm-coder wants to merge 7 commits into
mainfrom
hotfix/machine-id-header

Conversation

@mikhailm-coder

@mikhailm-coder mikhailm-coder commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

The oss-lib side of the machine-id firewall-header work, combining the mesh core and client changes (folds in the former #1729).

Mesh core (openframe-client-core/src/main/resources/meshcentral-core-module)

  • Header-enabled CoreModule.js: in OpenFrame mode the served core stamps x-machine-id (+ Authorization) on tunnel/download/self-update requests.
  • Host-header fix (96954f407): addOpenFrameHeaders now sets Host, fixing the Remote Desktop relay regression the 0.1.0 mesh binary otherwise triggers (a duktape-http quirk drops Host once options.headers exists). Verified working live.

Client (clients/openframe-client/)

  • New MachineIdService: generates a local Uuid::v4(), persists it to the shared app-support machine_id file (read by the mesh/fleet tool agents), cached behind Arc<RwLock>.
  • Sends it as x-machine-id on the HTTP clients, the NATS control connection, and the NATS log stream (replacing the "openframe-client" placeholder). Server-assigned machine_id still names the NATS connection.
  • Ported from openframe-oss-tenant; the client logic now lives here after oss-tenant #2038 reduced that repo's client to a thin wrapper over openframe-agent-lib.

cargo check --features bin + cargo fmt --check pass. Companion PRs: meshagent #78, fleetmdm #96.

🤖 Generated with Claude Code

mikhailm-coder and others added 3 commits July 31, 2026 15:01
…ine-id headers

Refreshes the ARTIFACTORY-served CoreModule.js snapshot from the
meshagent hotfix/machine-id-header branch: in openFrameMode the core
now stamps x-machine-id (read from the shared OpenFrame machine_id
file) and an Authorization bearer token on tunnel, download, and
self-update requests. On agent binaries that predate the
openFrameMode JS property the new code is a silent no-op, so the
core can roll out ahead of the binaries.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

OpenFrame support adds conditional machine ID, bearer authorization, and host headers to outbound HTTP and WebSocket requests. The changes cover tunnels, downloads, file transfers, console connections, and agent self-updates. Tunnel diagnostic logging and minor formatting artifacts were removed.

Changes

OpenFrame request headers

Layer / File(s) Summary
Header resolution and server targeting
openframe-client-core/src/main/resources/meshcentral-core-module
The module caches a platform-specific machine ID, reads mesh.openFrameMode, adds Host, x-machine-id, and bearer authorization headers, and appends the authorization token to server target URLs.
Tunnel header propagation
openframe-client-core/src/main/resources/meshcentral-core-module
Tunnel requests receive the OpenFrame headers. Tunnel diagnostic logging was removed. Existing timeout and close handling remain in place with minor formatting cleanup.
Connection and download header propagation
openframe-client-core/src/main/resources/meshcentral-core-module
OpenFrame headers were added to trusted downloads, server file fetches, console HTTP requests, console WebSocket connections, and agent self-update downloads.

Estimated code review effort: 3 (Moderate) | ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: adding a machine ID header for OpenFrame outbound requests.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch hotfix/machine-id-header

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sync the ARTIFACTORY-served CoreModule.js with meshagent: addOpenFrameHeaders
now restores the Host header the duktape http client drops once a headers
object is present, so openFrame-mode relay/tunnel/download dials reach the
gateway instead of getting rejected host-less. Fixes remote sessions stuck
"connecting" on the 0.1.0 mesh binary — served to installed agents with no
binary rebuild.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@openframe-client-core/src/main/resources/meshcentral-core-module`:
- Around line 1049-1052: Update the token injection block to require both
mesh.openFrameMode and a truthy result from mesh.authToken() before appending
the authorization query parameter. Preserve the existing separator handling, and
URL-encode the token value before adding it so null, undefined, and empty tokens
are never sent.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ea83797b-82db-48e5-a819-c97ea6acfdab

📥 Commits

Reviewing files that changed from the base of the PR and between 86d7c54 and 96954f4.

📒 Files selected for processing (1)
  • openframe-client-core/src/main/resources/meshcentral-core-module

Comment on lines 1049 to +1052
// Inject Openframe JWT token
console.log("Inject Openframe JWT token")
var token = mesh.authToken();
var separator = path.indexOf('?') !== -1 ? '&' : '?';
url += separator + 'authorization=' + mesh.authToken();
url += separator + 'authorization=' + token;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

# Trace token availability checks and authorization query handling.
rg -n -C 4 '\bauthToken\s*\(|\bopenFrameMode\b|authorization' \
  openframe-client-core/src/main/resources/meshcentral-core-module \
  openframe-gateway-service-core

Repository: flamingo-stack/openframe-oss-lib

Length of output: 10546


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- candidate function and surrounding code ---'
cat -n openframe-client-core/src/main/resources/meshcentral-core-module | sed -n '720,770p;1028,1060p'

printf '%s\n' '--- authToken and openFrameMode definitions/usages ---'
rg -n -C 6 'authToken\s*=|authToken\s*[:(]|openFrameMode\s*=|openFrameMode\s*:' \
  --glob '!**/node_modules/**' .

printf '%s\n' '--- gateway authentication filter and entry point ---'
cat -n openframe-gateway-service-core/src/main/java/com/openframe/gateway/security/filter/AddAuthorizationHeaderFilter.java | sed -n '1,140p'
cat -n openframe-gateway-service-core/src/main/java/com/openframe/gateway/security/WsAwareAuthenticationEntryPoint.java | sed -n '65,110p'

Repository: flamingo-stack/openframe-oss-lib

Length of output: 13201


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path

p = Path("openframe-client-core/src/main/resources/meshcentral-core-module")
text = p.read_text()
for needle in ("function getServerTargetUrl", "authToken", "openFrameMode"):
    print(f"--- occurrences of {needle!r} ---")
    for i, line in enumerate(text.splitlines(), 1):
        if needle in line:
            print(i, line)
PY

Repository: flamingo-stack/openframe-oss-lib

Length of output: 610


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- getServerTargetUrl call sites ---'
rg -n -C 5 'getServerTargetUrl(?:Ex)?\s*\(' \
  openframe-client-core/src/main/resources/meshcentral-core-module

printf '%s\n' '--- mesh API references and related documentation ---'
rg -n -i -C 3 'authToken|openFrameMode|OpenFrame.*token|token.*OpenFrame' \
  --glob '!**/node_modules/**' \
  --glob '!openframe-client-core/src/main/resources/meshcentral-core-module' \
  .

printf '%s\n' '--- JavaScript coercion and URL separator probe ---'
node - <<'JS'
for (const token of [null, undefined, '', 'jwt']) {
  const path = 'download?part=1';
  const url = 'https://host/ws/tools/agent/meshcentral-server/' + path;
  const separator = path.indexOf('?') !== -1 ? '&' : '?';
  console.log(JSON.stringify({ token, result: url + separator + 'authorization=' + token }));
}
JS

Repository: flamingo-stack/openframe-oss-lib

Length of output: 36749


Append authorization only for a non-empty OpenFrame token.

The current code converts null or undefined to text and the gateway can create Authorization: Bearer null or Bearer undefined when other token sources are absent. Guard mesh.openFrameMode and mesh.authToken, append only a truthy token, and URL-encode it. The gateway checks cookies and the alternate header before the query parameter.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@openframe-client-core/src/main/resources/meshcentral-core-module` around
lines 1049 - 1052, Update the token injection block to require both
mesh.openFrameMode and a truthy result from mesh.authToken() before appending
the authorization query parameter. Preserve the existing separator handling, and
URL-encode the token value before adding it so null, undefined, and empty tokens
are never sent.

mikhailm-coder and others added 3 commits August 14, 2026 11:51
…connections

Port of the machine-id-header client work from openframe-oss-tenant
(hotfix/machine-id-header). MachineIdService persists a locally
generated UUID in the shared app-support dir (read by mesh/fleet tool
agents) and stamps it as x-machine-id on the HTTP clients, the NATS
connection, and the NATS log stream (replacing the openframe-client
placeholder). The server-assigned machine_id still names the NATS
connection.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@mikhailm-coder mikhailm-coder changed the title Hotfix/machine id header feat: machine-id firewall header — bundled mesh core (Host fix) + openframe-client Aug 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant