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.