Back to Home

Security at FocusCap

We would rather show you the mechanism than ask for your trust. Below is how FocusCap actually handles your recordings today — including the parts we have not built yet.

Last verified:

How your data flows

1 — Capture. Your screen and audio are recorded locally by the macOS app and written to ~/Documents/Focuscap/ as an MP4. Nothing has left your Mac yet.

2 — Upload. The file is uploaded over HTTPS to Cloudflare R2 using a pre-signed URL that expires in 1 hour.

3 — Transcription (only if you turn it on). Transcription is off by default. When you enable it in the macOS app under Settings → Audio, the audio track is sent to OpenAI’s transcription API. While it is off, no audio leaves your machine.

4 — Storage. The video lives in Cloudflare R2. Metadata and transcripts live in an AWS RDS PostgreSQL database in US-East-1 (Virginia). Credentials live in AWS Secrets Manager. Your session tokens live in the macOS Keychain.

5 — Access. Sharing produces a unique, unindexed link. Playback is served through short-lived signed URLs — 4 hours for you as the owner, 30 minutes for anonymous viewers. You can add a password or revoke the link at any time.

6 — Deletion. Deleting a recording removes the row and the stored file. Deleting your account starts a 24-hour grace period, after which everything is purged. See Deletion and retention for exactly what “everything” covers, and what it does not.

Encryption

LayerWhat we use
Database at restAES-256 via AWS RDS storage encryption, using the AWS-managed KMS key for RDS. Automated backups inherit the same encryption. The instance is Multi-AZ and not publicly reachable.
File storage at restAES-256-GCM. Cloudflare R2 encrypts every object and its metadata automatically, with Cloudflare-managed keys. It cannot be turned off.
In transitTLS 1.3 is supported and negotiated by current browsers. TLS 1.2 is still accepted for compatibility; TLS 1.0 and 1.1 are not.
Database connectionsThe RDS Proxy requires TLS. Password authentication uses SCRAM-SHA-256. The database sits behind a private security group.
Server credentialsDatabase passwords, the OpenAI key and Stripe keys are stored in AWS Secrets Manager, not in environment variables or source.
Client credentials on macOSAuth tokens are stored in the macOS Keychain with kSecAttrAccessibleAfterFirstUnlock. They are not marked synchronizable, so they are never copied to iCloud Keychain.
Share passwordsHashed with bcrypt. Plaintext is never stored, and a stored value that is not a bcrypt hash is treated as a failed match rather than compared directly.

Network and edge

The API sits behind Amazon CloudFront with an AWS WAF web ACL in front of it, running three managed rule groups — Common Rule Set, Known Bad Inputs, and the Amazon IP Reputation List — plus a per-IP rate limit of 2,000 requests per 5-minute window.

Every response carries:

Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(self), geolocation=()
Content-Security-Policy: default-src 'self'; …explicit allowlists per directive

The marketing site is stricter still: script-src 'none'. The page you are reading runs no JavaScript at all.

Authentication

FocusCap uses AWS Cognito for identity.

  • Sign-in: email and password, Google OAuth via PKCE, and email one-time codes.
  • Two-factor: TOTP is available and can be enabled from web Settings, using any authenticator app — Google Authenticator, 1Password, Authy. It is currently optional, not enforced.
  • Session: access tokens are short-lived and refreshed automatically; signing out clears tokens on the device.

Authorization. Recordings are scoped to their owner, and every query filters by user. Workspaces use role-based access — owner, admin, member — with membership checked server-side. Admin endpoints authenticate separately and write to an audit trail.

Audit logging. We keep an append-only log of privileged administrative actions. To be precise about scope: this records what we do as operators. It is not a per-user activity log, and we do not claim one.

AI processing — and exactly who sees what

This is the section most worth reading closely, because it is the only point at which your content reaches a company other than us.

Transcription

Off by default. Enable it in the macOS app: Settings → Audio → Transcription. When enabled, the audio track of your recording is sent over HTTPS to OpenAI and the returned text is stored in our encrypted database. Our OpenAI API key never reaches the client.

Voice dub

Voice dub — an Advanced-tier feature you invoke explicitly — sends audio to OpenAI for speech-to-text, then text for translation, then generates the dubbed voice with OpenAI’s text-to-speech. All three steps involve OpenAI.

What our OpenAI account is configured to do

  • Training and evaluation sharing is disabled at the organization level, for all three settings OpenAI exposes. Your audio is not used to train or improve models.
  • API call logging is disabled on our organization.
  • A Data Processing Addendum with OpenAI is in progress, awaiting countersignature.

What we do not yet have, and will not pretend to: OpenAI’s Zero Data Retention agreement. Without it, OpenAI may retain API inputs for a limited period for abuse monitoring — currently documented as up to 30 days. ZDR is granted by OpenAI on approval rather than switched on by us. Until it is in place, the honest statement is: your audio is not used for training, and may be briefly retained by OpenAI for abuse monitoring.

What is processed on our own infrastructure

These features do not send your content to any third party:

  • Speaker diarization runs pyannote.audio inside our own AWS Lambda, on CPU. We hold a HuggingFace token, but it is used only to fetch model weights — no audio is sent to HuggingFace.
  • Filler-word removal, silence removal, trimming, stitching and GIF generation are media operations performed in our own compute.

Deletion and retention

Deleting a recording removes its database row and its stored file.

Deleting your account marks the profile with a deletion timestamp and starts a 24-hour grace period. A scheduled job runs every day at 03:30 UTC and removes, in a single database transaction: your recordings, subscription record, roles and device bridge tokens — then deletes your recording and thumbnail objects from R2, your Cognito user, and your Stripe customer record. Failed runs retry, land in a dead-letter queue, and raise an alarm; they do not fail silently. The job also carries a hard batch cap that aborts rather than proceed if the candidate set is unexpectedly large.

One thing we want to be straight about:

Backups. Our database keeps 7 days of automated backups, encrypted at rest. Deleted rows may therefore persist inside a backup snapshot for up to 7 days after deletion before ageing out. Backups are not accessible to the product and are not used to restore individual records — but “deleted everywhere, instantly” would be inaccurate, so we do not say it.

Where your data lives

ProviderWhat they holdRegion
Amazon Web ServicesAccounts, metadata, transcripts, compute, secretsUS-East-1 (Virginia)
CloudflareRecording and thumbnail files (R2), web hosting, CDN, DDoS protectionGlobal edge
OpenAIAudio and text, only when transcription or voice dub is usedUnited States
StripePayment details and subscription state. PCI-DSS Level 1.Global
ResendEmail addresses, for transactional mail onlyUnited States
SentryError diagnosticsUnited States
Small ChatSupport conversations, only if you accept the support-chat cookieUnited States

We do not sell your data, and we do not share it for advertising or third-party analytics.

Sentry specifically: error reporting runs with personally identifiable information disabled. Session Replay — which records screen interactions — is not loaded unless you explicitly grant it, and it masks all text and blocks all media when it is.

Your rights

  • Access and portability — Settings → Export My Data produces a JSON export of your data.
  • Rectification — edit your profile in Settings.
  • Erasure — Settings → Delete Account, as described above.
  • Withdraw consent — turn transcription off in the macOS app; change cookie choices at any time.
  • Object or restrict — email privacy@focuscap.co.

We handle EEA users’ data on a GDPR basis, including documented retention periods and erasure on request. The full Privacy Policy & Terms of Service sets out the legal basis for each purpose.

Monitoring and incident response

Infrastructure alarms page an on-call address through SNS, and application errors are captured in Sentry.

If we suffer a breach affecting your data, our commitment is: contain and revoke first, determine scope second, and notify affected users within 72 hours of becoming aware — telling you what happened, what data was involved, and what to do. We will follow with a technical write-up rather than a statement.

Report a vulnerability: security@focuscap.co. We will acknowledge, and we will not pursue anyone acting in good faith.

What we have not done yet

A security page that lists only strengths is a marketing page. These are open:

  • No SOC 2 report. We are not certified and no audit is underway. We build toward those controls; we have not been audited against them.
  • No third-party penetration test has been performed.
  • No Zero Data Retention agreement with OpenAI (see above).
  • Two-factor authentication is optional, not enforced for any tier.
  • Transcription can only be controlled from the macOS app. If you record on a Mac and manage everything else on the web, the web app cannot currently show or change that setting. We are moving the preference server-side.

If any of these is a blocker for your organization, tell us at security@focuscap.co — knowing what customers actually need decides what we build next.