Architecting Subhams Secure Agent: Real‑Time Cloud Printing with Node.js & WebSockets
#Security

Architecting Subhams Secure Agent: Real‑Time Cloud Printing with Node.js & WebSockets

Backend Reporter
7 min read

A deep‑dive into the design of Subhams Secure Agent, a RAM‑only, WebSocket‑driven print service that eliminates disk footprints for sensitive Indian documents. The article walks through the problem of insecure public‑cloud printing, the real‑time socket bridge, hardware fingerprinting, and the scalability and consistency trade‑offs of the chosen architecture.

The Problem: Public‑Cloud Printing Leaves a Digital Trail

In many Indian towns, users still rely on internet cafés or neighborhood print shops to produce copies of Aadhaar cards, PAN cards, and bank statements. The usual workflow looks like this:

  1. The user sends the file via WhatsApp, email, or a simple web upload.
  2. The shop’s server stores the document on disk, often in an unencrypted folder.
  3. The document sits there until a staff member prints it, and then it may linger for days or weeks.

Each step creates a persistent copy that can be accessed by anyone with local access to the machine. For highly regulated personal data, that exposure is unacceptable. The goal of Subhams Secure Agent is to eliminate any permanent storage while still delivering a fast, user‑friendly printing experience.


Solution Overview: Real‑Time Sockets + RAM‑Only Processing

Instead of a classic request‑response API, the system uses a bidirectional WebSocket channel (via socket.io) to push documents directly from the client’s mobile device to the shop’s terminal. The flow is:

  1. Client establishes a Socket.io connection to the Node.js gateway.
  2. The user selects a file; the browser reads it into a Blob and streams the binary payload over the socket.
  3. The gateway receives the buffer, stores it in a node‑buffer allocated in RAM, and immediately forwards it to the authenticated printer agent.
  4. The printer agent writes the buffer to the printer’s spooler (most printers accept raw data via USB or network sockets). Once the printer acknowledges completion, the buffer is zeroed and the garbage collector frees the memory.
  5. If the session is cancelled, the buffer is wiped instantly.

Key Components

  • Node.js + Express – lightweight HTTP server that only serves the initial HTML/JS bundle and handles authentication.
  • Socket.io – provides fallback transports (polling) for environments where WebSocket is blocked, ensuring reliability.
  • In‑memory store – a simple Map<sessionId, Buffer>; no external cache like Redis is needed because the data never leaves the process.
  • Hardware fingerprinting – each printer agent registers a signed hardware ID (CPU serial, MAC address) with the gateway. The gateway validates the signature before accepting a print job.
  • MongoDB Atlas – used solely for user accounts, session metadata, and audit logs; no document blobs are stored.

Subhams Secure Agent Print Mobileview


Scalability Implications

Horizontal Scaling

Because the payload never leaves the process memory, a single Node.js instance can handle a limited number of concurrent print jobs – roughly the amount of RAM you can allocate safely. To scale horizontally:

  1. Stateless front‑ends – the Express layer remains stateless; you can spin up additional instances behind a load balancer (e.g., Nginx or AWS ALB).
  2. Sticky sessions – Socket.io requires the client to stay on the same backend instance for the duration of the print job. Using session affinity on the load balancer solves this without a shared memory layer.
  3. Capacity planning – if each document averages 5 MB and you allocate 2 GB of heap per instance, you can safely process ~300 concurrent jobs. Beyond that, you either increase instance size or shard the workload across more nodes.

Consistency Model

Since the data lives only in RAM, the system follows an eventual consistency model for audit logs: once a job finishes, a tiny record ({sessionId, userId, printerId, timestamp, status}) is written to MongoDB. If the node crashes before the write, the print job is lost, but the document never persisted anywhere, preserving the zero‑retention guarantee. This trade‑off is acceptable because the primary security requirement is non‑persistence, not exactly‑once processing.


API Patterns and Security

Authentication Flow

  1. User logs in via a standard JWT endpoint (POST /api/auth).
  2. The JWT is sent as a query parameter when establishing the Socket.io connection (io('wss://gateway.example.com', { query: { token } })).
  3. The server validates the token and attaches the user ID to the socket context.

Authorization Checks

  • Printer registration – each printer agent must present a signed token generated from a private key stored on the hardware. The server verifies the signature against a public key stored in MongoDB.
  • Session scoping – a socket can only send a document to a printer that belongs to the same organization as the user. This prevents cross‑tenant leakage.

Zero‑Disk‑Retention Guarantees

  • All buffers are allocated with Buffer.allocUnsafe and overwritten with buffer.fill(0) after use.
  • The Node.js process runs with the --max-old-space-size flag to bound memory consumption and avoid swapping to disk.
  • The OS is configured with tmpfs for any temporary files (e.g., PDF conversion) to ensure they also reside in RAM.

Trade‑offs and Failure Modes

Aspect Benefit Drawback
RAM‑only processing No persistent copies; strong privacy guarantee. Limited by available memory; large files can cause OOM if not throttled.
WebSocket bridge Near‑real‑time delivery; no polling latency. Requires sticky sessions; more complex load‑balancer configuration.
Hardware fingerprinting Prevents rogue printers from hijacking jobs. Adds operational overhead (key provisioning, rotation).
Stateless HTTP layer Easy to scale horizontally for the UI. Socket affinity means you cannot arbitrarily route sockets after the initial handshake.
MongoDB for metadata only Simple schema, global distribution via Atlas. Not suitable for storing large blobs; audit logs can become a write hotspot under heavy load.

Mitigation Strategies

  • Back‑pressure – the client throttles chunk size (e.g., 64 KB) and waits for an acknowledgment before sending the next chunk. This prevents the server from being overwhelmed.
  • Circuit breaker – if the RAM usage crosses a configurable threshold, new connections are rejected with a clear error message, prompting the shop to upgrade hardware.
  • Graceful degradation – when a printer agent goes offline, the gateway queues the job in an in‑memory FIFO for a configurable timeout (e.g., 30 seconds). If the timeout expires, the job is aborted and the user receives a failure event.

Lessons Learned from Real‑World Failures

  1. Memory leaks are fatal – early prototypes used Array.push to accumulate chunks, which never released memory after a failed print. Switching to a single Buffer.concat with explicit null assignment solved the issue.
  2. Network jitter can corrupt streams – without proper binary framing, a dropped packet caused the printer to receive a truncated PDF, leading to garbled prints. Adding a simple length‑prefix header for each chunk restored integrity.
  3. Clock skew broke audit ordering – printers in different time zones reported timestamps that conflicted with MongoDB’s server time. Normalizing all timestamps to UTC before persisting eliminated the inconsistency.

Where to Find the Code

Subhams Secure Agent Print Dashboard


Closing Thoughts

Subhams Secure Agent demonstrates that a carefully scoped architecture—real‑time sockets, RAM‑only buffers, and strict hardware authentication—can meet a stringent security requirement without sacrificing user experience. The trade‑offs are clear: you gain privacy at the cost of tighter memory constraints and the need for sticky session handling. For any team looking to build a low‑latency, zero‑retention pipeline (e.g., medical imaging, legal document handling), the patterns described here provide a solid starting point.

If you’re interested in extending the system—perhaps adding end‑to‑end encryption of the payload before it hits RAM, or integrating a serverless fallback for burst traffic—feel free to open an issue or submit a PR on GitHub. Collaboration is the fastest way to harden a system that protects people’s most sensitive data.


Image credits: featured screenshots of the Subhams Secure Agent dashboard.

Comments

Loading comments...