Request Forwarding (Agents)
Oidis Hub includes a built-in reverse tunneling system that enables communication with devices and services that are not publicly accessible on the internet. The system is called Request Forwarding and the remote endpoints are called agents.
Problem This Solves
Deploying backend services on machines behind firewalls, NAT routers, or private networks normally requires:
- Opening specific firewall ports
- Setting up VPN infrastructure
- Exposing services on a public IP
These requirements are often impossible in corporate environments, IoT deployments, or edge computing scenarios.
Oidis Hub solves this by inverting the connection model: agents connect outward to Hub, not the other way around. Since outbound connections on ports 80/443 are permitted in virtually every network environment, no special configuration is needed.
Architecture
Internet / Public Network
│
┌────▼────┐
│ Hub │ ← Public HTTPS server (port 443)
└────┬────┘
│ WebSocket (persisted)
│
┌────▼──────────────────────────────────┐
│ Private Network / Behind Firewall │
│ │
│ ┌─────────┐ ┌─────────┐ ┌───────┐ │
│ │ Agent A │ │ Agent B │ │ ... │ │
│ │ (IoT) │ │ (CI/CD) │ │ │ │
│ └─────────┘ └─────────┘ └───────┘ │
└───────────────────────────────────────┘
Hub acts as a reverse proxy: it accepts connections from publicly visible clients (browsers, APIs) and forwards requests to agents that connected to it from behind firewalls. From the agent's perspective, it only ever makes outbound connections.
What Is an Agent?
An agent is any machine capable of running Node.js:
- IoT devices (Raspberry Pi, ARM boards, embedded Linux)
- CI/CD runners (GitLab Runner, Jenkins agents)
- Development servers (Windows, macOS, Linux)
- Internal services (private APIs, databases proxies)
- Edge computing nodes
The agent software connects to Hub via WebSocket, authenticates, and then listens for forwarded requests. The agent process itself is lightweight — it does not expose any listening port.
Communication Model
Connection
Agents initiate a WebSocket connection to Hub on port 80 or 443. This port is indistinguishable from regular HTTPS/WSS traffic and passes through standard firewalls without issues.
The connection is:
- Persistent — maintained as a long-lived WebSocket
- Encrypted — TLS on port 443
- Binary — efficient wire format, no JSON overhead for the transport layer
- Silent — no heartbeat noise visible to network monitors beyond standard keepalives
Authentication
Agents authenticate using agent tokens managed in Hub. These are separate from user authentication tokens and have their own lifecycle:
- Tokens are created and managed through the Hub GUI (or API)
- Each token is scoped to a specific agent identity
- Tokens can be revoked without affecting user sessions
- Managed in:
AuthProcessor/AuthTokensManager.ts
Method Whitelisting
Remote methods callable through an agent must be explicitly whitelisted — the same authorization mechanism used for FE→BE communication via @Extern. An agent cannot expose arbitrary code; only declared, permitted methods are reachable through the tunnel.
This ensures that a compromised agent token does not grant unrestricted access to the target machine.
Key Implementation Files
| File | Purpose |
|---|---|
HttpProcessor/Resolvers/ForwardingResolver.ts | HTTP resolver that handles agent WebSocket connections and forwards requests |
Primitives/AgentsRegister.ts | In-memory registry of currently connected agents |
AuthProcessor/AuthTokensManager.ts | Agent token creation, validation, and revocation |
RuntimeTests/AgentsRegisterTest.ts | Development-mode tests for the forwarding system |
Hub's Role
From Hub's perspective, an agent is a registered endpoint. Hub:
- Accepts the agent's WebSocket connection and validates the token
- Registers the agent in
AgentsRegister - Routes incoming requests to the appropriate agent based on the request path or routing rules
- Forwards the response back to the original caller
- Handles disconnections gracefully — queues or rejects requests when an agent is offline
The caller (browser, API client) interacts with Hub exactly as if the service were running locally on Hub's machine. The tunneling is transparent.
Use Cases
| Scenario | Description |
|---|---|
| Remote device management | Hub GUI shows status and sends commands to IoT devices in the field |
| CI/CD pipeline access | DevOps pipelines trigger builds on internal build agents through Hub |
| Internal service proxy | Expose a private API (e.g. internal database tool) through Hub's auth layer |
| Multi-site orchestration | Hub coordinates agents running at different physical locations |
Agent Lifecycle
The agent side of the tunneling system is implemented in io-oidis-connector. Understanding the full lifecycle helps when building or debugging agent applications.
Registration
When started with the agent CLI argument, the connector:
- Resolves the Hub endpoint (CLI
--hub→ configagent.hub→hubLocationsaliases) - Gathers metadata: platform, system fingerprint (SHA-1 of hardware IDs), package info, optional
process.env - Opens a WebSocket to Hub via
HubConnector - Calls
RegisterAgentwith credentials, capabilities, and metadata - Receives a list of authorized (whitelisted)
@Externmethods - Begins listening for forwarded requests through the WebSocket
Heartbeat
Once registered, the agent sends periodic UpdateAgentStatus calls to Hub. This serves as both a health check and a command channel:
- Period: Configurable interval between status updates
- Timeout: If Hub doesn't respond within the timeout, the heartbeat is considered failed
- Recovery: On failure, the agent either restarts the process (for systemd/PM2 to pick up) or silently reconnects the WebSocket
- Hub-initiated restart: Hub can set a
restart: trueflag in the status response to trigger agent restart
Reconnection
The HubConnector handles connection loss automatically:
OnClose→ immediately attempt reconnectionOnError→ retry after a 5-second delay- The reconnect parameter (default: 10 retries) controls the maximum reconnection attempts
System Fingerprint
Agents generate a unique device fingerprint from hardware identifiers (BIOS, motherboard, disks, OS). This SHA-1 hash is sent as part of the metadata during registration and can be used for device identification and licensing.
For full connector configuration and CLI reference, see Connector Overview.
Security Considerations
- All traffic passes through Hub's authentication layer — unauthenticated requests never reach an agent
- Agent tokens have independent revocation from user sessions
- Methods callable on agents must be explicitly whitelisted
- The agent itself opens no listening ports — it cannot be attacked directly from the network
See also: Architecture Overview | Connector Overview | Authentication | Routing