Multi-tenant isolation, SSO-gated access, encrypted credentials, and signed asset delivery — documented honestly, without the compliance-theater.
[ AUDIT & ACCOUNTABILITY ]
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.
[ IMPORT PIPELINE — CREDENTIAL HANDLING ]
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.

We'll answer plainly. Reach us at sf-core-org-support-csi-teachable-replacement-app@saas-factory.ai
[ IDENTITY — SSO ENFORCEMENT ]
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
[ MULTI-TENANCY — DATA ISOLATION ]
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.
Every table carries an org_id foreign key. The tRPC context injects the resolved org on every request — no query runs without it.
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.

[ ASSET SECURITY — SIGNED DELIVERY ]
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.
[ CONTENT SECURITY ]
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
[ HONEST SCOPE ]
We do not claim third-party certifications we have not obtained. Below is a plain account of the controls that are implemented today.
Teachable import credentials are AES-256 encrypted before storage. No plaintext secrets are persisted in the database.
Private file assets are served via short-lived signed URLs computed server-side. Permanent public links are not generated.
[ SECURITY FAQ ]
SSO configuration changes recorded in the audit log

Org admins and learner members are distinct roles. Course builder, enrollment management, reporting, and SSO config are gated — unauthenticated requests are redirected.
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
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
All database queries are org-scoped at the API context layer. There is no unguarded cross-tenant query path.
Admin actions — SSO config, enrollment changes, publishing — are written to an append-only audit log accessible within the settings panel.