How we handle your data
Honest, specific, and current. This page enumerates the security primitives OCCS enforces in code today — not a roadmap, not an aspirational SOC 2 timeline. Where we don’t have something yet, we say so.
Last updated: June 6, 2026
Authentication & access
- Password complexity, enforced at sign-up and password reset. Minimum 10 characters; must include an uppercase letter, a lowercase letter, and a digit.
- Breach check on every password. We hit the HaveIBeenPwned k-anonymized API with the SHA-1 prefix only (the full password never leaves the request); reject any password that appears in a known breach.
-
Account lockout.
Five failed sign-in attempts triggers a time-based lockout (Devise
lockable,unlock_in15 minutes). Sessions also expire after 8 hours of inactivity. - TOTP two-factor authentication. RFC 6238 with a ±1 step drift window. Replay-protected: a verified code can’t be reused inside its 30-second window. Ten single-use backup codes generated at enrollment and stored only as bcrypt hashes — the plaintext is shown once and is not recoverable from our side.
- OAuth sign-in (Google, Facebook). On callback we match by provider+UID first. If an OAuth identity matches an existing password account by email, we refuse to auto-link — the user has to sign in with their password and link explicitly from Settings. This closes the “attacker controls an OAuth identity for the same email” vector.
- SAML 2.0 SSO (enterprise). Per-organization Identity Provider config (Okta, Azure AD, OneLogin, JumpCloud, Google Workspace). Optional force-SSO blocks password sign-in; JIT provisioning auto-creates members on first successful response. Group-attribute → OCCS-role mapping is configured per IdP. Every SSO event lands in the audit ledger.
-
Cloudflare Turnstile.
Active on the public sign-up form and every public lead form (
/f/:token). Blocks the bulk of automated registration and form-spam without subjecting humans to image-grid CAPTCHAs. -
Email confirmation required before a new account can sign in (Devise
confirmable).
Encryption & data protection
- TLS 1.2+ in transit on every public surface, every authenticated request, and every webhook receiver. Plain HTTP is redirected.
- Application-level encryption at rest via ActiveRecord Encryption for sensitive columns — OAuth access tokens, OAuth refresh tokens, TOTP secrets, TOTP backup-code hashes, customer-provided third-party API keys, and self-hosted S3 access keys. Keys are loaded from environment-managed secrets, not committed.
-
Tenant isolation.
Every customer record (Contact, Sequence, Campaign, ScheduledPost, etc.) carries a
workspace_idand is queried through theacts_as_tenantmiddleware. A query without an active tenant raises rather than returning cross-tenant rows. -
Role-based access control.
Memberships are scoped per workspace with separation-of-duties roles —
client_lead(admin),client_user(author),client_approver(review only, no write),client_billing(billing only),client_viewer(read only),client_sales(CRM-write, marketing read-only). Authorization checks run through Pundit policies, not ad-hocif user.role ==branches.
Audit log & accountability
- Every business-critical write is audit-logged. PaperTrail captures version history with the actor, timestamp, and full before/after state for campaigns, sequences, broadcasts, brand profiles, AI provider config, pipeline-stage moves, and review decisions. Surfaced in the in-app activity feed; queryable for forensic incident response.
- AI Governance ledger. Every AI provider call is recorded with model, prompt version, latency, token counts, and dollar cost. Operators can disable a provider, version-control a prompt with rollback, and route a function key to a different model without code changes.
- Per-send delivery audit. Email broadcasts, SMS dispatches, and scheduled-post publications carry an audit trail of attempt, response code, and (for ESP/SMS adapters) the provider message ID for reconciliation.
Webhook & input integrity
-
HMAC-signed webhooks on every receiver.
Stripe billing events use Stripe’s
t=…,v1=…scheme over the raw request body. Postmark inbound + delivery webhooks are gated by HTTP Basic auth on a dedicated credential separate from any application user. Twilio inbound SMS verifies theX-Twilio-Signatureheader. Customer-configured inbound capture (/inbound/leads) requiresX-OCCS-Signature: sha256=…over the body, with the per-workspace secret rotatable from Settings. - SSRF gate on every customer-supplied URL. URL ingestion (knowledge bank, brand discovery, landing-page analyzer, Followed Sources) goes through a centralized safety check that rejects private IP ranges, link-local addresses, and metadata endpoints before the HTTP fetch. Redirects are re-validated against the same allowlist on every hop.
-
Content Security Policy.
Strict CSP with per-request nonces and
strict-dynamicfor Turbo. Inline scripts that aren’t nonce-stamped are blocked. -
Active Storage upload validation.
Avatars, brand assets, and reference images are content-type checked (
image/png|jpeg|webp|gif) and size-capped at the model layer, not just the upload form.
Outbound compliance
- CAN-SPAM. Every marketing email auto-injects a List-Unsubscribe header (one-click) and a footer unsubscribe link tokenized per recipient. Suppression list is enforced at dispatch time — a re-added contact stays suppressed unless the operator explicitly clears the row.
- TCPA. SMS sends respect 8am–9pm local-recipient quiet hours. STOP / HELP keyword auto-handling is built into the inbound webhook; there is no path to send an SMS to a STOP’d number from any composer or sequence step.
- 10DLC registration wizard. Brand and campaign registration is a guided in-app flow rather than a hand-off to the carrier. Throughput class is set per registered campaign; we don’t silently dispatch on an unregistered brand.
- Bounce + complaint handling. Postmark bounce/complaint webhooks update the recipient state automatically. Hard-bounced and complaint addresses are quarantined from future sends.
Infrastructure & data residency
- Application + database hosted on a managed Rails platform with daily encrypted snapshots. PostgreSQL 16, encrypted at rest by the underlying volume. Point-in-time recovery enabled at the database tier (verified in-house: a forked-snapshot restore exercise was last run and passed on May 10, 2026).
- Network-isolated environments. Production, staging, and preview environments run in separate isolated networks — a misconfiguration in a preview deploy can’t reach production data, and inter-service traffic between our Rails app and PostgreSQL/Redis stays on private networking rather than the public internet.
- HTTPS-only edge with automatic DDoS mitigation. Every request hits a managed edge that enforces HTTPS (HTTP is 301-redirected, HSTS preloaded), absorbs volumetric L3/L4 attacks before they reach the application, and runs an always-on edge firewall with rate-limiting and managed bot-mitigation rules. There is no path to reach the origin without traversing this layer.
- Object storage on Cloudflare R2 via the S3-compatible API. Workspace-scoped paths; signed URLs for time-limited public access (e.g. personalized-video player tokens). Customer-bring-your-own S3 bucket is supported on the Enterprise storage tier and is plan-independent — a workspace on any plan can subscribe to Enterprise storage to keep assets in their own bucket.
- Background jobs run with retry and dead-letter handling so a transient ESP/SMS provider failure doesn’t silently swallow a send.
- Secrets are loaded from environment-injected variables and Rails encrypted credentials — never committed to the repository.
Subject rights & compliance
- GDPR / CCPA data subject access. Customers can export their workspace data (contacts, sequences, broadcasts, audit history) on demand. Verified deletion requests submitted to privacy@1clickcampaign.com are fulfilled within 30 days; we retain only records we’re legally required to keep (billing invoices, abuse logs).
- Meta data-deletion webhook. We honor Meta’s mandatory data-deletion callback for users who revoke our app from their Facebook account.
- Sub-processor transparency. The current vendor list with each processor’s legal entity, HQ region, role, and link to their DPA is on the public subprocessor catalog page; signed-in customers can also view the customer-facing list at Settings → Data processors.
- Data Processing Addendum. A standard DPA is available to customers on Growth and above. Email legal@1clickcampaign.com with your workspace ID.
What we don’t have yet
Honest list. We’d rather you know than discover it during procurement.
- · SOC 2 Type II. Not yet certified. Many of the controls (audit logging, encryption, RBAC, change management) are already in place; the formal report is on the roadmap.
- · ISO 27001 / HIPAA / FedRAMP. Not in scope today.
- · Customer-managed encryption keys (CMEK / BYOK). Not available; encryption keys are managed by us.
- · Public bug-bounty program. Not yet. Coordinated disclosure to security@1clickcampaign.com — see below.
Report a vulnerability
We take coordinated disclosure seriously. If you believe you’ve found a vulnerability, please email security@1clickcampaign.com with reproduction steps and, where applicable, a proof-of-concept. We commit to acknowledging receipt within two business days and keeping you informed through remediation.
Out of scope: denial-of-service tests, brute-force authentication tests against production, social-engineering of staff or partners, and physical attacks.
Need a security questionnaire filled out?
Email security@1clickcampaign.com with the questionnaire attached. We typically turn standard SIG-Lite, CAIQ, or vendor-specific forms in under five business days. Custom forms vary.