How OpenSpec Ensures Data Privacy and Security: A Technical Deep Dive

OpenSpec implements a privacy-first architecture that collects only anonymous command names and version numbers, with explicit opt-out controls and automatic CI detection to prevent data leakage.

OpenSpec is an open-source specification tool developed by Fission-AI that prioritizes user privacy through minimal data collection and transparent telemetry practices. The codebase segregates telemetry logic from the core engine, ensuring that sensitive user data never leaves the local machine. This article examines the specific technical implementations in src/telemetry/index.ts and related modules that enforce these privacy guarantees.

Minimal Data Collection in the Telemetry Pipeline

The telemetry system in OpenSpec is intentionally restricted to the absolute minimum data required for understanding adoption patterns.

What Gets Logged

According to the source code in src/telemetry/index.ts, the system records only two pieces of information:

  • The command name being executed (e.g., "validate", "run")
  • The OpenSpec version currently installed

Critically, the system explicitly excludes arguments, file paths, source code content, or any user-generated data from the telemetry payload. This design ensures that proprietary or sensitive information embedded in command-line arguments remains strictly local.

Anonymous UUID Generation

User identification relies on a randomly generated UUID created once per installation. The getOrCreateAnonymousId() function (lines 65-86 in src/telemetry/index.ts) generates this identifier using cryptographically secure random methods and persists it locally. This UUID contains no personal linkage, server-side correlation, or hardware fingerprinting, making it impossible to trace back to individual users or organizations.

User-Controlled Opt-Out Mechanisms

OpenSpec provides multiple straightforward mechanisms for users to disable telemetry entirely, respecting both explicit preferences and industry-standard environment conventions.

Environment Variable Controls

The isTelemetryEnabled() function (lines 40-60 in src/telemetry/index.ts) checks for three specific environment variables before transmitting any data:

  • OPENSPEC_TELEMETRY=0 — Explicit opt-out specific to OpenSpec
  • DO_NOT_TRACK=1 — Respects the universal Do Not Track standard
  • CI=true — Automatically disables telemetry in continuous integration environments

When any of these variables are detected, the telemetry pipeline short-circuits immediately, ensuring zero network requests occur.

CI Auto-Disable Behavior

The automatic detection of CI environments (including GitHub Actions, GitLab CI, and other common platforms) prevents telemetry from accidentally leaking in automated pipelines. This is particularly important for organizations running OpenSpec in private repositories where internal path structures or build configurations might otherwise be exposed.

Fail-Safe Networking and Error Handling

Even when telemetry is enabled, OpenSpec employs defensive programming to prevent user-facing disruptions or data leakage.

The safeTelemetryFetch() function (lines 25-35 in src/telemetry/index.ts) wraps all network communications with comprehensive error handling. If the telemetry endpoint (https://edge.openspec.dev) is unreachable or returns an error, the function silently swallows the exception and returns a harmless 204 response. This guarantees that telemetry failures never propagate as CLI errors or interrupt the user's workflow.

Additionally, the telemetry endpoint configuration explicitly strips IP addresses from requests ($ip: null), preventing server-side correlation based on network origin.

Secure Local Storage

Telemetry configuration data—including the anonymous UUID and the "notice seen" flag—resides in platform-appropriate global configuration directories. The src/telemetry/config.ts module handles reading and writing to these locations:

  • Unix/Linux: XDG-compliant configuration directories
  • Windows: %APPDATA% directory

The storage format uses simple JSON without encryption (as the data contains only the random UUID), but the location ensures proper filesystem permissions and separation from user source code.

Summary

OpenSpec's privacy and security architecture relies on five core technical strategies:

  • Minimal data model that captures only command names and version numbers, never user content or file paths
  • Anonymous identifiers generated locally via getOrCreateAnonymousId() without personal linkage
  • Environment-based opt-out supporting OPENSPEC_TELEMETRY, DO_NOT_TRACK, and CI variables
  • Fail-safe networking through safeTelemetryFetch() that prevents user-visible errors
  • Secure local storage using platform-standard config directories managed by src/telemetry/config.ts

Frequently Asked Questions

Does OpenSpec collect my source code or file paths?

No. According to the implementation in src/telemetry/index.ts, the telemetry system explicitly excludes arguments, file paths, and source code content from its payload. Only the command name (e.g., "validate") and OpenSpec version number are transmitted.

How do I completely disable telemetry in OpenSpec?

Set either OPENSPEC_TELEMETRY=0 or DO_NOT_TRACK=1 in your environment before running OpenSpec commands. The isTelemetryEnabled() function checks these variables before any network request occurs, ensuring complete telemetry suppression.

Will OpenSpec send telemetry data when running in CI/CD pipelines?

No. The telemetry system automatically detects CI environments via the CI=true environment variable (common in GitHub Actions, GitLab CI, and other platforms) and disables all data collection. This prevents accidental leakage of internal build configurations or repository structures.

Can I reset my anonymous identifier if I want a fresh identity?

Yes. Import updateTelemetryConfig from src/telemetry/config.ts and call it with anonymousId: undefined to regenerate a new UUID. The next telemetry event will automatically create a fresh random identifier using the getOrCreateAnonymousId() function.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →