Core Concepts

Before diving into advanced features, it helps to understand the building blocks that make cloud-share work. This page explains each concept at a level that will inform how you use the tool day-to-day.


Dev Tunnels

A Microsoft Dev Tunnel is an outbound HTTPS connection from the sender machine to Microsoft’s relay infrastructure. It creates a publicly accessible URL (e.g. https://mtszwr0l.uks1.devtunnels.ms:5000) that proxies all requests back to the sender’s local port 5000.

Why this matters:

  • No port forwarding or firewall rules needed on the sender
  • The receiver only needs outbound HTTPS (port 443) — works from corporate networks, coffee shops, mobile hotspots
  • The tunnel is ephemeral — it exists only while the sender is running
  • Microsoft’s relay sees only encrypted HTTPS traffic; it cannot read the content

The devtunnel CLI manages tunnel creation and authentication. Cloud Share calls it automatically.


Secret tokens

Every time you start cloud-share-sender, it generates two independent random values:

  1. Session secret (_secret) — a fresh 12-character alphanumeric string (e.g. aB3kP9mQ2rTs). This serves two roles:

    • API authentication — every API call from the receiver includes Authorization: Bearer <secret>. Requests with a missing or invalid secret are rejected with 401 Unauthorized.
    • Encryption key material — the AES-256 encryption key is derived from this secret using HKDF-SHA256 (RFC 5869).
  2. UI access token (_uiToken) — a separate 128-bit random hex token that gates access to the sender web UI independently of the encryption secret. The browser is automatically opened to http://localhost:{port}/?token=<uiToken>. On the first visit the server validates the token, sets an HttpOnly SameSite=Strict cookie, then redirects to /. All subsequent visits are validated against the cookie. Unauthenticated requests receive 401 Unauthorized.

ℹ️ Info: The UI token and the encryption secret are independent values — they are never reused for each other’s purpose. Compromising one does not compromise the other.

The session secret is:

  • Generated randomly on each sender start
  • Never saved to disk
  • Transmitted only via Authorization: Bearer header (never in URLs or query strings)
  • Scoped to a single session — starting the sender again creates a new secret and invalidates the old one

The sender also enforces a brute-force lockout: after 10 consecutive authentication failures, all API endpoints return HTTP 429 Too Many Requests with a Retry-After: 60 header for 60 seconds.

⚠️ Warning: Share the secret through a separate secure channel (e.g. Signal, phone call). Anyone who has both the tunnel URL and the secret can receive your queued items.


AES-256-GCM encryption

Every item — text, file, or zip bundle — is encrypted before it leaves the sender’s memory using AES-256-GCM:

ComponentDetail
AlgorithmAES-256 in Galois/Counter Mode (GCM)
Key32 bytes derived from the secret via HKDF-SHA256 (RFC 5869 / NIST SP 800-56C)
Nonce12 bytes, randomly generated per item
Authentication tag16 bytes, appended to ciphertext
EncodingNonce + ciphertext + tag, all base64-encoded for transport

GCM mode provides both confidentiality (no one can read the content) and authenticity (no one can tamper with the ciphertext without the tag becoming invalid).

See Encryption Architecture for the full technical breakdown.


The queue model

The sender maintains an in-memory queue of items waiting to be received. Items are added when you click Share/Upload in the sender UI. Each item has:

  • A unique ID (UUID)
  • A type (text, file, zip)
  • Encrypted content
  • A SHA-512 hash of the plaintext
  • A status (Queued, Received)

Items remain in the queue until they are received (downloaded by the receiver) or explicitly deleted. The queue is not persisted to disk — restarting the sender clears all queued items.

The receiver fetches item metadata from GET /queue and downloads individual items from GET /item/{id}. All requests use Authorization: Bearer <secret> — the secret is never passed in URLs.


SHA-512 hash verification

Before encrypting an item, the sender computes a SHA-512 hash of the plaintext content and stores it alongside the encrypted item. When the receiver downloads and decrypts an item, it:

  1. Decrypts the content using AES-256-GCM
  2. Computes SHA-512 of the decrypted plaintext
  3. Compares it to the hash provided by the sender using a constant-time comparison

If the hashes match → ✅ content is intact and untampered.

If the hashes do not match → ❌ the item is permanently deleted from the sender queue and an error is shown in the receiver UI. This prevents a corrupted or tampered item from being kept or retried silently.


Real-time updates (SSE)

The receiver maintains a persistent connection to the sender’s /events endpoint, which streams Server-Sent Events (SSE). The receiver authenticates via a local_token HttpOnly cookie (the EventSource API cannot set custom headers). This means:

  • New items appear in the receiver queue instantly — no polling, no page refresh
  • When an item is received, its status updates everywhere in real time
  • When an item is deleted, it disappears from all connected receivers

If the SSE connection drops (network hiccup, tunnel reconnect), the receiver automatically reconnects after a 3-second backoff. After reconnecting, the queue is refreshed to catch any items missed during the gap. A connection status badge in the UI shows whether the event stream is live.


Session history

The receiver saves the last 5 tunnel connections (tunnel ID, region, port, and secret) to receiver-session.json in %APPDATA%\CloudShare\ (Windows) or ~/.config/CloudShare/ (macOS/Linux). Entries expire automatically after 7 days.

On the next run, the receiver shows a SelectionPrompt listing recent connections so you can arrow-key to re-connect without re-entering anything. If you select “Connect to a new tunnel…”, the structured sub-prompts guide you through tunnel ID → region → port and reconstruct the full URL automatically.

The sender saves your DevTunnels login (OAuth tokens) to preferences.json so you do not have to re-authenticate on every run.

Use cloud-share-sender --reset to clear the saved DevTunnels login and re-authenticate. Use cloud-share-receiver --no-prompt to skip the startup prompt entirely (useful in scripts when --url/--code and --secret are provided via flags).