Security

PDFPipe is built with security as a foundational requirement. This page describes the measures we have in place to protect your data.

For questions about our data processing practices, see our Data Processing Agreement. To report a security concern, email security@pdfpipe.dev.

Encryption

  • All API traffic is encrypted in transit with TLS 1.2+ (HTTPS only). HTTP connections are rejected. The .dev TLD enforces HSTS by default.
  • Data at rest is encrypted in DynamoDB using AWS-managed encryption keys (AES-256).
  • PDF files stored in S3 are encrypted with server-side encryption (SSE-S3 minimum, SSE-KMS preferred).

API Key Security

  • API keys are stored as bcrypt hashes — the raw key is only shown once at creation and never stored.
  • Key lookup uses a SHA-256 hash prefix for fast retrieval without exposing the full key.
  • Keys can be scoped to specific IP addresses via an allowlist when creating a key in the dashboard, blocking requests from unauthorised origins.
  • Keys can be revoked instantly from the dashboard, and revoked keys are rejected immediately.

Authentication & Sessions

  • Dashboard sessions use signed JWT tokens with a 24-hour expiry.
  • JWT tokens contain only the minimum claims needed (userId, accountId, memberRole).
  • Suspended accounts are blocked at the authentication middleware layer before any processing occurs.

Ephemeral Data Storage

  • Converted PDF output is stored temporarily in S3 and served via presigned URLs scoped to the exact object path.
  • Primary cleanup: an asynchronous Lambda deletes the S3 object as soon as the presigned URL response is delivered.
  • Backstop cleanup: an S3 lifecycle policy automatically deletes all objects after 48 hours, regardless of other cleanup.
  • Presigned URL expiry varies by tier — 1 hour (Free), 24 hours (Starter), 7 days (Pro/Business).
  • There is no long-term storage of PDF content. PDFPipe does not retain your documents.

Data Isolation

  • Every request is assigned a unique UUID v4 request ID.
  • S3 objects are namespaced to /{userId}/{requestId}/ — cross-user access is impossible by design.
  • Presigned URLs are scoped to the exact S3 object path and cannot be used to access other objects.
  • DynamoDB records are partitioned by user/account with composite keys preventing cross-tenant queries.

Input Validation & SSRF Prevention

  • All incoming requests are validated at the API boundary using Zod schemas. Invalid requests are rejected before processing.
  • Request body size is limited to 64 KB to prevent abuse.
  • URL validation blocks private and reserved IP ranges (10.x, 172.16-31.x, 192.168.x, 127.x, 169.254.x) to prevent SSRF attacks.
  • Only HTTP and HTTPS protocols are accepted — no file://, ftp://, or other schemes.
  • URLs are limited to 2,048 characters.

Infrastructure

  • Hosted on AWS EU (London) — eu-west-2 — using SST v3 (Ion) with infrastructure-as-code. All resources are defined declaratively and version-controlled.
  • Compute runs on AWS Lambda with IAM least-privilege policies — each function has only the permissions it needs.
  • The S3 bucket has no public access. All file access goes through presigned URLs.
  • Processing queues use AWS SQS FIFO with dead letter queues (DLQ). Failed jobs are retried up to 3 times before moving to the DLQ.
  • API Gateway enforces a 30-second timeout and CORS policies restricting origins to production domains.
  • CloudFront CDN serves the web application globally from edge locations, with the origin in eu-west-2.

Monitoring & Audit

  • Structured JSON logging with request ID, hashed user ID, tier, duration, and outcome for every request.
  • Admin audit logging tracks all administrative actions (account suspension, tier changes, etc.).
  • AWS CloudWatch captures Lambda invocation logs, errors, and latency metrics.

Responsible Disclosure

If you discover a security vulnerability, please email security@pdfpipe.dev with details. We will acknowledge receipt within 48 hours and provide an initial assessment within 5 business days.