Security model

How mog.md keeps packages safe — scan pipeline, SHA-256 verification, signed URLs, and secrets detection.

mog distributes code that runs inside AI agent environments. We take package security seriously. This page describes every layer of protection.

Upload scan pipeline

Every uploaded release is processed by an asynchronous scan worker before it can be published. The scan runs in an isolated worker process.

Scan steps

  1. Download archive: The worker downloads the .zip from secure storage.
  2. Unzip and enumerate: Every file in the archive is listed.
  3. File type check: Each file's extension is checked against the allowlist. Any disallowed file type causes an immediate scan failure.
  4. SHA-256 hash: SHA-256 is computed for every file and stored in the release record.
  5. Secrets scan: Text files (.md, .yaml, .yml, .json, .txt) are scanned for secret patterns.
  6. Required files check: Both mog.yaml and README.md must be present.
  7. Result: scanStatus is set to passed or failed. Failure reasons are stored in scanResult and shown in the seller dashboard.

File type allowlist

v0 packages are content-only — no executable scripts:

ExtensionNotes
.mdScanned for secrets
.yaml, .ymlScanned for secrets
.jsonScanned for secrets
.txtScanned for secrets
.png, .jpg, .svgImages — not scanned for secrets

Any other extension — including .js, .sh, .py, .exe — is disallowed and causes the scan to fail.

Secrets detection

Text files are scanned for common credential patterns including:

  • Cloud provider API keys (AWS, GCP, Azure)
  • AI service keys (OpenAI, Anthropic, etc.)
  • Source control tokens (GitHub, GitLab)
  • Messaging platform tokens (Slack, Discord)
  • Private cryptographic keys (RSA, EC, SSH)

We do not publish the exact patterns or thresholds — doing so would make them easier to circumvent. If a secret is detected, the scan fails and the seller is notified with the category of finding (but not the matched value).

SHA-256 integrity verification

Every package archive is SHA-256 hashed on upload and the hash is stored immutably in the release record. When a user installs a package, the CLI:

  1. Requests a signed download URL from the API (requires an active entitlement)
  2. Downloads the archive
  3. Computes the SHA-256 of the downloaded bytes
  4. Compares against the hash stored in the release record
  5. Aborts with an error if they don't match

This prevents tampering in transit. Even if an attacker intercepted the download, the hash mismatch would be caught before any files are written to disk.

Signed download URLs

Package archives are stored in private cloud storage with no public access. Download URLs are cryptographically signed with a 5-minute expiry.

To get a download URL, a request must:

  1. Present a valid Bearer token with the download scope
  2. Have an active (non-revoked) entitlement for the listing

Path traversal protection

During installation, each file path from the zip archive is resolved against the install base directory. If the resolved path escapes the base directory (a "path traversal" attempt), the install fails immediately:

Path traversal detected: ../../etc/passwd

Atomic lockfile writes

If the lockfile write fails after extraction, the extracted files are removed to leave a clean state. This prevents a partially installed package from being treated as installed.

Authentication security

  • Device code flow (RFC 8628): No passwords. Authentication happens in a browser with your OAuth provider (GitHub or Google). The CLI never sees your OAuth credentials.
  • Tokens: API tokens are hashed (SHA-256) before storage. The plaintext token is only returned once, at issuance time.
  • Spend policies: Enforced server-side, not just in the CLI. See Spend policies.

Rate limiting

All API endpoints are rate-limited. Limits vary by endpoint sensitivity — authentication and upload endpoints have stricter limits than read-only endpoints. When a limit is exceeded, the API returns HTTP 429 with a Retry-After header.

Rate limits may be adjusted without notice.

Transport security

All API and web traffic is served over TLS 1.2 or higher. HTTP Strict Transport Security (HSTS) is enforced on all production domains, preventing downgrade attacks.

Web application security

The web application sets security headers on all responses, including Content Security Policy (CSP), X-Content-Type-Options, and X-Frame-Options. State-changing API endpoints are protected against CSRF. All user-supplied content is escaped before rendering.

Dependency management

Dependencies across the API, web app, and CLI are monitored for known vulnerabilities. Critical vulnerabilities in direct dependencies are patched within 7 days of disclosure.

Data at rest

The database and all package storage use encryption at rest. Sensitive fields (API token hashes, credentials) are never stored in plaintext.

Reporting security issues

If you discover a security vulnerability, please report it privately by emailing security@mog.md. Do not open a public GitHub issue for security vulnerabilities.