Skip to main content

Security & Privacy

SignalPilot is designed with security-first principles: read-only access, local-first execution, and zero data retention.

Core Security Principles

Read-Only Access

All MCP connections are read-only — no writes to production systems

Local-First Execution

Code runs in your environment — never on SignalPilot servers

Zero Data Retention

No data stored on SignalPilot servers — full privacy

Audit Trail

Track what context was accessed and when

MCP Read-Only Access Model

SignalPilot uses the Model Context Protocol (MCP) to connect to your data stack:

Internal MCP Sidecar

The internal sidecar runs within your Jupyter environment:
  • Kernel introspection: Read variables, dataframes
  • Schema queries: Read table metadata
  • Query history: Read past queries (no execution)
  • Database writes: Not possible
  • File system writes: Not possible (except notebooks)

External MCP Servers

External MCP servers are read-only by design:
IntegrationWhat SignalPilot Can ReadWhat It Cannot Do
dbtModel definitions, lineage, docsModify models, run dbt commands
SlackPublic channel threads, messagesPost messages, access private DMs
JiraTickets, comments, metadataCreate/modify tickets
Snowflake/DatabricksQuery logs, metadataExecute queries, modify data
We recommend using read / view only credentials (db / notions etc.) and MCP tooling for SignalPilot agent to ensure maximum saftey for the agentic harness.

Approval Workflows

SignalPilot includes built-in approval mechanisms:
1

Agent/Planning Mode

Agent creates a plan and waits for your approval before execution
Use Planning Mode for high-stakes investigations or production queries
2

Hands-On Mode

Agent suggests code, but you execute manually in cells
3

Ask Mode

Agent is read-only — no code execution, only answers questions

Hooks: Custom Constraints (Alpha)

Enforce your own rules via pre-execution hooks:

Example: Production Query Hours

# Only allow prod queries during business hours
def validate_query(query, context):
    if is_prod_db(context) and not is_business_hours():
        raise ValidationError("Production queries only allowed 9am-5pm EST")

Example: Row Count Changes

# Warn if row count changes significantly
def check_row_count(result, context):
    if abs(result.row_count - context.expected_count) > 0.2:
        warning("Row count changed by >20% — verify data quality")

Example: Vectorization Enforcement

# Require vectorized pandas operations
def validate_code(code):
    if "for " in code and "df" in code:
        raise ValidationError("Use vectorized pandas operations, not loops")

Data Retention & Privacy

  • Session metadata: Timestamps, user IDs (anonymized)
  • Error logs: Stack traces (no data values)
  • Usage metrics: Feature usage, performance
  • Query results: Never stored on our servers
  • Database schemas: Read in real-time, not cached
  • Slack messages: Read via MCP, not stored
  • Source code: Notebooks stay local
  • TLS 1.3: All connections encrypted
  • API keys: Stored locally, never transmitted
  • MCP connections: Encrypted via SSH/TLS

SOC 2 Compliance

SignalPilot is working on SOC 2 Type II compliance (status: in progress as of 2026).
We follow industry best practices for:
  • Access controls and authentication
  • Data encryption (at rest and in transit)
  • Incident response and monitoring
  • Vendor risk management

Questions?