SECURITY & PRIVACY

Built for organizations that can't afford a breach

Multi-tenant isolation, SSO-gated access, encrypted credentials, and signed asset delivery — documented honestly, without the compliance-theater.

[ IDENTITY — SSO ENFORCEMENT ]

Your identity provider is the only door in

Learners authenticate exclusively through your organization's existing identity provider — OIDC or SAML 2.0. There are no separate platform passwords to manage, reset, or compromise. Sessions are scoped to the SSO token lifetime and force re-authentication when they expire.

  • OIDC and SAML 2.0 support (Okta, Azure AD, ADFS)

  • Session expiry aligned to your IdP's token lifetime

  • Stale sessions rejected — no indefinite access

  • Per-org provider config with encrypted credential storage

  • SSO configuration changes recorded in the audit log

Learner dashboard after SSO authentication

[ MULTI-TENANCY — DATA ISOLATION ]

Every organization is a sealed compartment

Organization IDs partition every table in the database. Queries and mutations at the API layer are scoped to the authenticated tenant before execution — there is no code path that returns another organization's courses, learners, or import data.

Row-level tenant partitioning

Every table carries an org_id foreign key. The tRPC context injects the resolved org on every request — no query runs without it.

Subdomain & path routing

Middleware resolves an org from either acme.platform.com or /org/acme before a single line of business logic runs. Cross-org URL spoofing returns nothing.

Role-based access control

Org admins and learner members are distinct roles. Course builder, enrollment management, reporting, and SSO config are gated — unauthenticated requests are redirected.

Team and member directory showing org-scoped access

[ ASSET SECURITY — SIGNED DELIVERY ]

No file is publicly accessible by default

PDFs, images, and attachments are stored under per-tenant path prefixes in Vercel Blob. Every download URL is a short-lived signed URL generated server-side at render time — not a permanent public link anyone can share, scrape, or hotlink.

  • AES-256 encryption at rest for Teachable import credentials

  • Signed URLs generated per-request, never cached as public

  • Per-org storage path prefixes prevent cross-tenant asset access

  • MIME type and file size validated server-side on upload

  • Attachment download events recorded in the analytics log

[ AUDIT & ACCOUNTABILITY ]

Every sensitive action leaves a record

An immutable audit log captures admin actions — SSO config changes, enrollment modifications, course publishing decisions, and import job initiations — with timestamps and the acting user's identity.

SSO-CONFIGSAML provider updated by admin@acme.orgjust now
ENROLLMENTBulk enroll: 24 learners added to Q4 Onboarding2m ago
COURSE-PUBLISHCourse Security Awareness 2024 set to published11m ago
IMPORT-JOBTeachable import initiated for school acme.teachable.com34m ago
ORG-SETTINGSBrand color updated by admin@globalcorp.io1h ago
PURGE-QUEUESoft-deleted course queued for PII purge after retention window3h ago

[ CONTENT SECURITY ]

Embedded content runs in a controlled perimeter

Content Security Policy on lesson pages

Lesson pages ship with CSP headers that allow iframes only from explicitly trusted video hosts (YouTube, Vimeo, Wistia, Loom). Unauthorized iframe injections are blocked at the header level before the browser renders them.

  • Allowlisted video providers: YouTube, Vimeo, Wistia, Loom

  • All other iframe origins blocked by default

  • XSS protection on rich-text lesson content

Soft delete, PII cleanup & data retention

Courses, lessons, and user records are soft-deleted first, then permanently purged — including associated Vercel Blob assets — by a scheduled background job after a configurable retention window. Organization offboarding queues a full data purge behind a mandatory admin confirmation step.

  • GDPR right-to-erasure supported via scheduled purge

  • Org deletion requires explicit confirmation before queue

  • Asset blob storage purged alongside database records

[ IMPORT PIPELINE — CREDENTIAL HANDLING ]

Teachable credentials never leave the worker context in plaintext

When you authorize a Teachable import, your admin credentials are encrypted with AES-256 before being stored. They are decrypted transiently inside the Inngest background worker — never logged, never returned in an API response, and never held in plaintext outside the execution context.

Import job progress monitor showing live pipeline status

[ HONEST SCOPE ]

What we are — and what we are not claiming

We do not claim third-party certifications we have not obtained. Below is a plain account of the controls that are implemented today.

Encryption at rest

Teachable import credentials are AES-256 encrypted before storage. No plaintext secrets are persisted in the database.

Signed asset delivery

Private file assets are served via short-lived signed URLs computed server-side. Permanent public links are not generated.

Tenant data separation

All database queries are org-scoped at the API context layer. There is no unguarded cross-tenant query path.

Audit trail

Admin actions — SSO config, enrollment changes, publishing — are written to an append-only audit log accessible within the settings panel.

[ SECURITY FAQ ]

Common security questions

Questions about how we handle your data?

We'll answer plainly. Reach us at sf-core-org-support-csi-teachable-replacement-app@saas-factory.ai