Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.spitshake.io/llms.txt

Use this file to discover all available pages before exploring further.

Security Architecture

DocuTrust employs defense-in-depth security across encryption, authentication, session management, API access, and audit logging. Every layer is designed to align with HIPAA safeguards, SOC 2 Trust Service Criteria, and GDPR principles.

Encryption at Rest

All documents are encrypted using AES-256-GCM before being written to storage. Encryption occurs automatically on upload across all ingestion paths (API, web UI, template creation, and signing submissions). Documents are decrypted on-the-fly when accessed by authorized users. Personally identifiable information (PII) stored in the database is protected with Active Record Encryption:
FieldModePurpose
emailDeterministicAllows lookups via find_by while keeping data encrypted
nameNon-deterministicMaximum privacy; no query matching needed
phoneNon-deterministicMaximum privacy; no query matching needed
ip_addressNon-deterministicMaximum privacy; no query matching needed
user_agentNon-deterministicMaximum privacy; no query matching needed
valuesNon-deterministicSubmitted field values (signatures, text, dates)
metadataNon-deterministicSubmitter metadata and preferences
Deterministic encryption produces the same ciphertext for the same plaintext, enabling database-level equality queries. Non-deterministic encryption produces unique ciphertext every time, providing stronger protection against frequency analysis.

Encryption in Transit

All connections to DocuTrust are secured with TLS 1.2+. This applies to:
  • Browser-to-server communication (web UI and signing pages)
  • API requests and responses
  • Webhook deliveries to your endpoints
  • Internal service communication in production
Older TLS versions (1.0, 1.1) and unencrypted HTTP connections are rejected.

Session Management

Production sessions are stored server-side in Redis, not in browser cookies. This provides:
  • 30-minute inactivity timeout: Sessions expire after 30 minutes without activity. Users are redirected to the login page.
  • Immediate invalidation: Administrators can revoke all sessions instantly via the SessionInvalidator service during security incidents.
  • No session fixation: Session IDs are regenerated on login and destroyed on logout via reset_session.
In development environments, cookie-based sessions are used for convenience.

Authentication

Password Hashing

Passwords are hashed with bcrypt via Rails’ has_secure_password. Bcrypt applies an adaptive cost factor that increases computational difficulty over time, defending against brute-force attacks.

Password Policy

All user passwords must meet the following requirements:
  • Minimum 12 characters
  • At least one uppercase letter
  • At least one lowercase letter
  • At least one number
  • At least one special character (e.g., !@#$%^&*)

Multi-Factor Authentication (TOTP)

DocuTrust supports Time-Based One-Time Password (TOTP) MFA compatible with authenticator apps such as Google Authenticator, Authy, and 1Password. Administrators can enforce MFA for all users at the account level. See the MFA guide for setup details.

Account Lockout

After 5 consecutive failed login attempts, the account is locked. Locked accounts trigger a user.locked security event and require administrator intervention or a password reset to unlock.

API Security

Token Scopes

API tokens support granular scopes that restrict which endpoints a token can access. Tokens without the required scope receive a 403 Forbidden response.

IP Allowlisting

Administrators can configure CIDR-based IP allowlists at the account level. Requests from IP addresses outside the allowlist are blocked and logged as security.ip_blocked events. A lockout prevention mechanism ensures administrators cannot accidentally lock themselves out.

Rate Limiting

API requests are rate-limited to 120 requests per minute per token. Exceeding this limit returns a 429 Too Many Requests response with a Retry-After header indicating when the client can retry.

Audit Logging

Every significant action in DocuTrust is recorded in an immutable audit trail:
  • Immutability: Audit entries are protected by a PostgreSQL trigger that prevents UPDATE and DELETE operations on the submission_audit_entries table.
  • Chain hashing: Each entry includes a SHA-256 hash of the previous entry, forming a tamper-evident chain. Any modification to a historical record breaks the chain and is detectable.
  • 7-year retention: Audit records are retained for 7 years to meet regulatory requirements.
  • 30+ event types: Actions across document lifecycle, user management, security events, and API access are all captured.
See the Audit Trails guide for querying and filtering events.

SSRF Protection

Webhook delivery URLs are validated to prevent Server-Side Request Forgery (SSRF) attacks. DocuTrust blocks webhook URLs that resolve to:
  • Private IP ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
  • Loopback addresses (127.0.0.0/8)
  • Link-local addresses (169.254.0.0/16)
  • Internal cloud metadata endpoints (169.254.169.254)

Breach Detection

DocuTrust runs an automated breach detection service that monitors for:
  • Privilege escalation attempts
  • Off-hours access patterns
  • Unusual login velocity
  • Multiple failed MFA attempts
Detected anomalies generate security.breach_detected events and can trigger automatic session invalidation across the account.

Graduated autonomy for AI agents

API tokens support granular scopes that enforce a draft-then-confirm model for AI agent integrations:
ScopeAllows
submissions:draftCreate and update draft submissions (no emails sent)
submissions:sendSend drafts for signing (legally binding)
submissions:remindSend signing reminders
submissions:writeFull access (superset of draft + send + remind)
An agent token minted without submissions:send cannot dispatch a binding document, even if the model is fully compromised. This is enforced server-side.

Idempotency

Create and send operations support an Idempotency-Key header backed by a Postgres table (not Redis) to prevent duplicate legally-binding submissions on retry.

Further Reading