Sender CLI Reference

cloud-share-sender is the NuGet global tool that starts the local web server, creates the Dev Tunnel, and manages the queue of items to be shared.


Synopsis

  cloud-share-sender [options]
  

Flags

FlagShortDefaultDescription
--port-p5000The local port to listen on
--log-lwarningsLog level: verbose, warnings, or errors
--resetRe-authenticate with DevTunnels (clears saved login)
--no-auto-openDo not open the web UI in the browser on startup
--help-hShow help text
--versionShow the tool version

Flag details

--port / -p

Sets the local TCP port the sender’s HTTP server listens on. The Dev Tunnel proxies to this port.

  # Use port 8080 instead of the default 5000
cloud-share-sender --port 8080
cloud-share-sender -p 8080
  

ℹ️ Info: The tunnel URL always uses port 443 (HTTPS) regardless of your local port. The local port only affects what port the browser uses when opening http://localhost:<port>.


--log / -l

Controls the verbosity of console log output.

LevelWhat is shown
verboseAll log messages including debug info, request traces, DevTunnel output
warningsWarning and error messages only (default)
errorsError messages only
  cloud-share-sender --log verbose
cloud-share-sender -l errors
  

Use verbose when troubleshooting DevTunnel connectivity or unexpected behavior.


--reset

Clears the saved DevTunnels authentication from preferences.json and forces re-authentication on next start. Use this if your login token has expired or you want to switch accounts.

  cloud-share-sender --reset
  

After clearing, the tool will prompt you to authenticate with Microsoft or GitHub OAuth on the next run.


--no-auto-open

By default, the sender opens the web UI (http://localhost:<port>) in your default browser automatically on startup. Use this flag to suppress that behavior.

  cloud-share-sender --no-auto-open
  

Useful for:

  • Headless servers
  • Scripted/automated use
  • Environments without a browser

Environment variables

VariableDescription
CLOUDSHARE_SECRETIf set, overrides the randomly generated session secret. Avoids exposing the secret in shell history or the process argument list (ps aux).
  # Safer alternative to: cloud-share-sender --secret aB3kP9mQ2rTs
export CLOUDSHARE_SECRET="aB3kP9mQ2rTs"
cloud-share-sender
  

⚠️ Warning: Run unset CLOUDSHARE_SECRET (or close the terminal) after the session to prevent the value persisting in the environment.


Startup output

When the sender starts successfully, you will see output similar to:

   ██████╗██╗      ██████╗ ██╗   ██╗██████╗
██╔════╝██║     ██╔═══██╗██║   ██║██╔══██╗
██║     ██║     ██║   ██║██║   ██║██║  ██║
██║     ██║     ██║   ██║██║   ██║██║  ██║
╚██████╗███████╗╚██████╔╝╚██████╔╝██████╔╝
 ╚═════╝╚══════╝ ╚═════╝  ╚═════╝ ╚═════╝
         SHARE

[12:34:56] Checking devtunnel CLI...
[12:34:56] Starting tunnel...
[12:34:58] Tunnel ready.

Tunnel URL : https://abc123def456.devtunnels.ms
Secret     : ****rTs
Web UI     : http://localhost:5000/?token=a1b2c3d4e5f6... (opening in browser...)

[12:34:58] Listening on http://localhost:5000
  

ℹ️ Info: The secret is displayed masked by default (****<last-4-chars>). Use --show-secret to reveal the full value.

Tunnel URL format

The tunnel URL follows the pattern:

  https://<random-identifier>.devtunnels.ms
  

This URL is publicly accessible over HTTPS (port 443) and proxies to your local sender. Share this URL along with the secret with your recipient.

Secret token

The secret is a fresh 12-character alphanumeric string generated on each run. It:

  • Authenticates all API requests via Authorization: Bearer <secret> header (never in URLs)
  • Provides the key material for AES-256-GCM encryption via HKDF-SHA256
  • Is never saved to disk
  • Is displayed masked as ****<last-4-chars> — use --show-secret to reveal the full value
  • Is invalidated when the sender stops

After 10 consecutive authentication failures the sender enters a 60-second lockout and returns HTTP 429 Too Many Requests with a Retry-After header until the lockout expires.

Web UI token

Separately from the encryption secret, a 128-bit random UI access token is generated at startup. The browser is automatically opened to http://localhost:{port}/?token=<uiToken>. This token authenticates your browser session and is set as an HttpOnly SameSite=Strict cookie after the first visit. If you navigate to http://localhost:{port}/ directly without the cookie, you will receive 401 Unauthorized.


Examples

Start with defaults

  cloud-share-sender
  

Start on a custom port without opening the browser

  cloud-share-sender --port 8000 --no-auto-open
  

Start with verbose logging for troubleshooting

  cloud-share-sender --log verbose
  

Re-authenticate and start

  cloud-share-sender --reset
  

API endpoints (reference)

The sender exposes these HTTP endpoints:

MethodPathAuth requiredDescription
GET/ui_token cookie (or ?token=<uiToken> on first visit)Serves the sender web UI
GET/queueAuthorization: Bearer <secret>Returns the current queue as a JSON array
POST/upload/textAuthorization: Bearer <secret> + Anti-CSRFQueue a text item ({"text": "..."})
POST/upload/fileAuthorization: Bearer <secret> + Anti-CSRFQueue a file (multipart form, file field)
POST/upload/zipAuthorization: Bearer <secret> + Anti-CSRFQueue a zip bundle (multipart form, file[] + password fields)
GET/item/{id}Authorization: Bearer <secret>Download an encrypted item; marks it as received
DELETE/item/{id}Authorization: Bearer <secret> + Anti-CSRFRemove an item from the queue
GET/eventsAuthorization: Bearer <secret>SSE stream of queue change events

All API endpoints (everything except GET /) require Authorization: Bearer <secret>. The root / endpoint is independently gated by the UI access token.

Anti-CSRF: Mutating endpoints (POST, DELETE) also validate the Origin or Referer header when present. Browser requests from a different origin are rejected with HTTP 403 Forbidden. API clients that do not send browser-injected headers (curl, Postman, the receiver proxy) are not affected.