Servo

Information Security Policy

Effective Date: February 1, 2025  ·  Last Updated: February 19, 2026

Servo maintains a documented, operationalized information security program. This policy describes the controls, practices, and technical safeguards that govern how we identify, mitigate, and monitor security risks across our platform.

1. Scope and Applicability

This Information Security Policy applies to all systems, personnel, data, and processes that support the Servo platform — including the application infrastructure, cloud environments, third-party integrations, and any personnel with access to customer data.

Servo is an AI-native ERP platform serving field service companies. Our security program is designed to protect customer data, maintain system availability, and ensure the confidentiality and integrity of all information we process on behalf of our clients.

2. Authentication and Access Control

Access to the Servo platform is controlled through a layered authentication and authorization model designed to ensure that only authorized users can access the data and functions appropriate to their role.

Identity Provider and JWT Authentication

Servo uses WorkOS as our identity provider. All user sessions are authenticated through industry-standard OAuth 2.0 / OIDC flows, and access is granted via signed JSON Web Tokens (JWTs). Token signatures are validated against WorkOS's published JWKS (JSON Web Key Set) public keys, with keys cached and refreshed on a one-hour cycle. We do not store user passwords — password management is delegated entirely to WorkOS and the identity providers it supports (SSO, social login, etc.).

Token Lifecycle and Refresh Security

Access tokens carry a short expiry window. Refresh tokens are issued alongside access tokens and are used to obtain new credentials without re-authentication. A synchronized refresh mechanism prevents race conditions in concurrent sessions. Refresh token revocation invalidates a session immediately. Tokens are transmitted exclusively over HTTPS.

Passwordless Magic Links

For certain invitation and onboarding flows, Servo issues short-lived, single-use magic link tokens. These are signed with a secret key, stored in Redis with a strict TTL, and validated via a session ID composed of cryptographically random bytes. Magic links grant narrowly scoped access and cannot be used to access general authenticated routes.

API Key and Service Authentication

Service-to-service communication is authenticated via a shared internal service secret compared using constant-time equality checks to prevent timing attacks. API keys issued to customers are scoped, logged, and tied to the requesting identity in the audit trail.

Tiered Authorization Model

Every route in the Servo API is assigned an explicit authorization level, generated automatically from route definitions. The tiers are:

  • Public — No authentication required (health checks, webhooks)
  • Magic Link — Temporary passwordless access, narrowly scoped
  • Full Auth — Standard JWT, required for all customer-facing routes
  • Servo Admin — Elevated internal access, cross-tenant operations
  • Blocked — Deprecated or unsafe routes explicitly denied

Authorization is enforced at the global middleware layer — not in individual handlers — ensuring consistent enforcement across all routes.

3. Tenant Data Isolation

Servo is a multi-tenant platform. Every record in every database table carries a tenant_id (a UUID) that binds it to a specific customer organization. This architecture ensures complete logical separation of customer data.

Enforcement at Every Layer

Tenant context is extracted from the authenticated JWT at the start of every request and propagated through the application context. It is automatically applied to all database queries via the query layer. Clients cannot override or spoof their tenant identity — the server strips any client-supplied tenant_id and uses only the authenticated value.

Cross-Tenant Access Controls

Cross-tenant operations are restricted exclusively to Servo platform administrators with the “servo” role. Any cross-tenant access is validated, explicitly flagged in the request context, and captured in the audit log. No customer user can access another tenant's data.

Relationship Data

Inter-entity relationships (e.g., people-to-organizations) are stored in a centralized junction table that includes tenant_id, soft-delete timestamps, and temporal validity windows (dtstart/dtend). All queries against this table enforce tenant isolation.

4. Encryption

Data in Transit

All communication between clients and the Servo platform is encrypted using TLS. HTTPS is enforced at the AWS Application Load Balancer (ALB) layer before traffic reaches the application. Internal service communication within the VPC is isolated by network controls. Database connections support SSL/TLS and are configured with SSL mode enabled in production.

Data at Rest

Sensitive third-party API credentials and connection keys stored in the database are encrypted at rest using AES-256. Database volumes and S3 buckets are encrypted using AWS-managed encryption at rest. No plaintext credentials are stored in application data.

Secret Management

All application secrets — database credentials, API keys, signing keys, encryption keys — are managed via SOPS (Secrets OPerationS) with age encryption (AES-256-GCM). Encrypted secrets are stored in version control; the private decryption key is never committed and is distributed out-of-band. Pre-commit hooks automatically encrypt any local secret changes before they reach the repository. CI/CD pipelines use separate, environment-scoped secrets stored in GitHub Actions encrypted secrets, not the repository's encrypted file.

5. Audit Logging

Servo maintains a comprehensive, tamper-evident audit trail of all data modifications across the platform.

Automatic Database Triggers

Every table in the Servo database (except the audit log itself) has a database-level trigger that fires on INSERT, UPDATE, and DELETE. These triggers capture old and new values, the affected table and record, and the timestamp. Trigger coverage is validated at application startup — missing triggers fail fast.

What Is Logged

Each audit log entry captures:

  • User identity (user_id) and actor type (human, agent, system, API key)
  • AI agent identity and the person the agent acted on behalf of, if applicable
  • API key used, if the request was API-key authenticated
  • Action type (INSERT, UPDATE, DELETE)
  • Affected table and record ID
  • Previous and new field values (JSONB diff)
  • Request ID for correlating all changes within a single API call
  • Client IP address
  • Timestamp (UTC)
  • Whether the action was performed by a Servo administrator

Write Operations Require Audit Context

All services that perform write operations are required to use an audit-aware database handle (AuditDB). Transactions that lack the required audit context — containing authenticated user ID, tenant ID, and IP address — will fail at the database layer. This is enforced structurally in code, not by convention.

Soft Deletes Preserve History

Records are never physically deleted by default. All tables support soft deletion via a deleted_at timestamp, preserving the audit trail and enabling data recovery. Physical deletion requires explicit administrative action.

6. API Security

Rate Limiting

All API endpoints are protected by a sliding window rate limiter (200 requests per 30 seconds per client IP). The sliding window algorithm prevents boundary-burst attacks that fixed-window limiters are vulnerable to. Clients that exceed the limit receive HTTP 429 responses with a Retry-After header. Failed authentication attempts count toward the rate limit, which defends against credential stuffing.

Input Validation and SQL Injection Prevention

All SQL queries are executed using parameterized statements — user-supplied values are never interpolated into query strings. Dynamic identifiers (table and column names used in generic CRUD and sort operations) are validated against an allowlist regex and quoted using PostgreSQL identifier escaping before use. Jinja2/DBT SQL templates used in reporting features are resolved server-side with sanitized context.

Type-Safe API Responses

All HTTP handlers are required to return typed response structs. Untyped response maps (fiber.Map) are blocked by a static analysis tool integrated into the pre-commit hook and CI pipeline. This prevents accidental data leakage through overly broad response shapes and ensures all response fields are explicitly declared.

Request Field Stripping

System-managed fields (created_at, updated_at, deleted_at, tenant_id) are stripped from all incoming request bodies before processing. Clients cannot set or override these values.

CORS Policy

Cross-Origin Resource Sharing is configured with an explicit allowlist of permitted origins. Requests from unlisted origins are rejected. Allowed headers are enumerated explicitly; wildcard header allowlists are not used.

Client-Provided ID Validation

Servo supports client-generated UUIDs (UUIDv7) for optimistic UI patterns. Server-side validation enforces UUID format correctness and verifies that the embedded timestamp in the UUIDv7 falls within ±5 minutes of server time, preventing replay or pre-fabricated ID attacks.

Panic Recovery

A global panic recovery middleware catches unhandled application panics, logs the full stack trace, and returns a safe error response. Panics do not crash the server process or leak internal state to the client.

7. Infrastructure Security

Cloud Provider and Compute Isolation

Servo runs on AWS using Amazon ECS Fargate. Each container runs in its own isolated execution environment with no shared compute resources between tenants. Network traffic is controlled via VPC security groups. Container images are pulled from a private ECR registry.

Least-Privilege IAM

ECS tasks are assigned IAM roles with least-privilege access. The execution role grants only ECR image pull and CloudWatch log write permissions. The task role grants only the specific S3 and database access the application requires — no administrative AWS permissions are granted to running application containers.

Database Security

The production database uses connection pooling with configurable limits to prevent resource exhaustion. Database schema migrations are managed using Atlas, an automated migration tool, with all migration files tracked in version control. Credentials are never hardcoded — they are loaded from the environment configuration at runtime.

Cache and Session Store

Redis is used for session token caching, magic link storage, and rate limiter state. Redis connections are authenticated and isolated per environment. Magic link tokens are stored with strict TTLs and are invalidated on use.

8. Code Security Practices

Static Analysis and Pre-Commit Enforcement

A suite of automated checks runs before every commit. These include static analysis for untyped API responses, linter rules for known insecure patterns, and validation that the encrypted secrets file is up to date. Commits that violate these rules are rejected at the Git hook layer without requiring a CI round-trip.

Protected Git History

The repository enforces a merge-only workflow. Force pushes, rebases, and history rewrites are blocked by a pre-push hook that cannot be bypassed. This protects the integrity of the commit history and the audit trail of code changes.

Dependency Pinning

Go module files and frontend lockfiles pin exact dependency versions, ensuring reproducible builds and preventing unintended dependency drift.

Observability and Anomaly Detection

All application activity is instrumented with OpenTelemetry tracing, which exports traces, metrics, and structured logs to Axiom. Every request carries a request_id, tenant_id, and user_id through the full trace. This provides full observability into system behavior and enables detection of anomalous activity patterns.

9. Data Classification and Handling

Sensitive Data

Servo handles personally identifiable information (PII) including names, email addresses, phone numbers, and IP addresses as part of normal platform operation. Passwords are never stored — authentication is delegated to WorkOS. Third-party credentials (API keys, tokens) are encrypted at rest using AES-256 before storage.

Data Residency

Customer data is stored in AWS infrastructure in the United States (us-east-1 region). Data is not transferred to other regions without explicit configuration.

Timestamps and Time Zones

All timestamps are stored in UTC. The API returns ISO 8601 formatted timestamps with explicit UTC offsets. Display-layer time zone conversion is handled client-side based on user preferences, ensuring consistent time representation across the system.

10. Third-Party Services

Servo uses a limited set of third-party services as part of its infrastructure:

  • WorkOS — Identity and SSO management
  • AWS — Cloud infrastructure (compute, storage, networking)
  • Twilio — SMS and communication services
  • Plaid — Financial data connectivity
  • Axiom — Log and trace storage

Third-party integrations are authenticated using scoped API keys stored encrypted at rest.

11. Incident Response and Policy

If you discover a security vulnerability or have a concern about how data is handled, contact us directly at hi@servohq.com. We respond as quickly as possible.

This policy reflects the current state of our platform and is updated on a continuous basis as the system evolves.