Security & privacy

Exactly what stays on your server, what reaches OpsGates Cloud, and how the agent is locked down.

The short version is on the security page. This page has the technical details of Server mode; Computer mode is described at the end.

What OpsGates Cloud receives

The agent sends one HTTPS request to https://mcp.opsgates.com/api/v1/usage every 30 seconds while in use, and every 5 minutes when idle:

{
  "delta": 12,
  "batch_id": "b_9f2c…",
  "agent_id": "ag_51e0…",
  "version": "1.0.0",
  "url": "https://203-0-113-7.sslip.io/mcp"
}

delta is the number of tool calls since the last report. The other fields are a random batch id (so a retry is never counted twice), a random id for this installation, the agent version, and the connector URL shown in your dashboard. The license key travels in the Authorization header. Nothing else — no tool names, arguments, paths, output, hostnames or credentials. The code is in /opt/opsgate/app/meter.py.

The cloud answers with your plan, limit and usage. If it cannot be reached, the agent keeps working and counting locally for 72 hours, then pauses tool calls until it can report again.

What stays on your server

Secret Where How
Login password /etc/opsgate/env (root only) scrypt hash (N=32768, r=8)
OAuth codes, access and refresh tokens /var/lib/opsgate/oauth.db SHA-256 only; codes are single-use (5 min), access tokens last 1 h, refresh tokens rotate
Static tokens /etc/opsgate/env + tokens.json SHA-256 only
License key /etc/opsgate/env (root only) plain (it only identifies your account for billing)
Audit log /var/log/opsgate/audit.jsonl secrets masked

Sign-in (OAuth 2.1)

  • Authorization server built into the agent; no third party involved.
  • PKCE (S256) required; dynamic client registration only for redirect addresses of known apps.
  • The sign-in page has a 10-minute window, 5 attempts per request, and locks for 15 minutes after 10 failures.
  • sudo opsgate password deletes every issued token: all apps must sign in again.

Sandbox

The service runs as opsgate (no login shell, no home) with ProtectSystem=strict, ProtectHome=read-only, PrivateTmp, protected kernel tunables, modules, logs and clock, restricted namespaces and address families, and UMask=0077. The file system is read-only for it except its own state folders and the folders you allowed. NoNewPrivileges is intentionally off only so the exact sudo rules you created can work.

Guard rails in the tools

  • Path checks: every path is resolved (following symlinks) and must be inside the allowed folders; system directories themselves cannot be moved or chmod-ed; .git internals cannot be modified.
  • Protected names: .env, .env.*, *.pem, *.key, *.p12, id_rsa*, id_ed25519*, *.kdbx, authorized_keys, shadow, gshadow, oauth.db are never read.
  • Redaction: private keys, bearer/basic credentials, URL credentials, secret values in the usual config formats (password=…, password: …, 'password' => …, define('DB_PASSWORD', …), requirepass …, .netrc, .pgpass, XML <password>, <add key="…Password" value="…">, mysqldump -p…, curl -u user:…, Authorization: headers) and known token formats (JWT, GitHub, Google, OpenAI/Anthropic, Stripe, AWS, Slack, Telegram…) are replaced with *** before anything is returned. Masking is a safety net for the usual formats, not a guarantee for every file that could exist: the hard guarantees are the blocked secret files, the operating-system permissions of the opsgate user and, on servers with very sensitive data, limiting reading to the folders the AI needs (sudo opsgate config set MCP_READ_ROOTS=/var/www/app,/var/log).
  • No shell: commands are parsed and executed directly; options that execute other programs or write files (find -exec, find -delete, tree -o…) are refused. Git runs without pager, hooks, external diff or text conversion, git pull is fast-forward only, and a repository whose own config defines programs to run (filters, merge drivers, ssh or credential helpers, includes) is refused.
  • Its own files are off limits: the tools can never modify the agent's state, audit log, backups, code or configuration, and cannot even read its configuration and state.

OpsGates Cloud

  • Passwords: scrypt. Sessions, license keys and email links: SHA-256 only. CSRF protection on every form, strict Content-Security-Policy, HSTS, rate limits on sign-in, sign-up and API.
  • Payments: Stripe Checkout and the Stripe customer portal. Card data never touches OpsGates.
  • Stripe webhooks are verified with their signature and processed idempotently.

Report a vulnerability

Write to support@opsgates.com. Please include steps to reproduce. We do not take legal action against good-faith research.

Signed updates

Every OpsGates Agent release is signed offline by the vendor. The first time you install, the installer prints the release-key fingerprint (16 characters) and stores the key on your server; from then on sudo opsgate update only accepts packages signed with that key, refuses older versions, and never runs a script it just downloaded. To verify the very first install, compare the fingerprint with the one the vendor publishes on an independent channel, or pass it to the installer: --fingerprint <16 characters>.

Optional two-step login

Add an authenticator-app code to your server's login page: sudo opsgate 2fa on.

Computer mode

  • Relay: the app on the computer keeps one HTTPS long-poll request open to https://mcp.opsgates.com/api/device/poll. Tool calls from your AI apps are queued in memory and handed to it; answers come back on /api/device/result. Nothing in transit is written to disk. Delivery is at-least-once and the app remembers recent calls, so a call is never run twice.
  • What is stored: computer name, platform, app version, the folders it reports and the ones you chose, the permission level; per call, the tool name, time, duration and success (90 days, last 1,000 per computer). Never paths, contents, commands or output.
  • Secrets: the computer's secret (ogd_…) is created when you approve the link, delivered once and stored in the cloud only as SHA-256. OAuth codes, access tokens (1 h) and rotating refresh tokens (30 days) are SHA-256 only and bound to one computer and its connector URL (RFC 8707).
  • Linking: device-code flow. The 8-character code expires after 15 minutes, is single-use and must be approved by a signed-in account; email confirmation is required when email is configured.
  • Sign-in for AI apps: OAuth 2.1 with PKCE (S256 only), dynamic client registration restricted to known AI apps and local apps, consent page with the account's session (and two-step verification), iss in the response.
  • On the computer: every path is resolved (following links) and must be inside the folders you chose; protected locations are refused by name and by place; the permission level is enforced again on the computer, and --readonly caps it locally. The app runs as your user, never as administrator, installs only in your user folder, and updates only to versions signed with the offline release key.
  • Trust: the relay is the path to your computer. Someone controlling OpsGates Cloud could send calls to connected computers within their folders and permission level. Choose read only where that is enough, and remove computers you no longer use.