Security knobs.
The security controls that matter, where they live in the product, and how to use them well.
This page is a working reference, not a marketing page. If you want the policy view of how Felarity is built, see Trust · Security. If you want the legal view, see Privacy and the DPA. What follows is what you, the operator of a workspace, can actually configure — and the reasoning behind the defaults.
We are forensic intelligence over meetings. The product is only useful if the audit trail, the attribution chain, and the workspace boundary all hold under scrutiny. The controls below exist so that they do.
1. Authentication
By default, Felarity authenticates users with Google OAuth 2.0. We do not store passwords for any account. The OAuth flow returns a short-lived ID token, which we exchange for a Felarity session JWT scoped to the workspace and the user's role inside it.
Session JWTs are signed with a workspace-rotating key, expire after twelve hours of inactivity or seven days absolute, and bind to a single browser fingerprint (User-Agent + accept-language hash). A copied cookie pasted into a different browser will not validate.
On Professional and Enterprise, you can require SAML 2.0 single sign-on through your identity provider (Okta, Azure AD/Entra ID, Google Workspace as IdP, JumpCloud, OneLogin, generic SAML). When SAML is enforced at the workspace level, Google OAuth is disabled for that workspace and every member must sign in through your IdP. SCIM 2.0 user provisioning is available on Enterprise.
2. Multi-factor authentication
Every user, on every plan, can enroll a TOTP authenticator (Google Authenticator, 1Password, Authy, Yubico Authenticator). Hardware tokens that speak TOTP are fine. We do not currently support WebAuthn / FIDO2 hardware keys directly — that is on the roadmap for Q2 2027.
Enrollment lives at /app/account/security/. The flow:
POST /api/account/mfa/setup
→ returns { secret, qr_code_data_url, recovery_codes: [10 strings] }
POST /api/account/mfa/verify
body: { code: "123456" }
→ activates MFA on the account
Recovery codes are shown once, at enrollment. They are single-use. We do not store them in recoverable form — if you lose them, your workspace admin can reset MFA, but no one at Felarity can read them back to you.
Workspace owners on Professional and Enterprise can require MFA workspace-wide. Members without MFA enrolled are blocked at the next sign-in until they enroll. There is no grace period flag; this is by design.
3. Workspace isolation
Every database row, every audio file, every transcript, every contradiction, every report carries a workspace_id. Every API handler resolves the caller's authorized workspaces from the session or API key, and rejects any request whose path or body references a workspace the caller does not belong to.
We close the IDOR class server-side, not in the UI. A user who edits a URL from /api/reports/abc123 to /api/reports/xyz789, where xyz789 belongs to another workspace, receives a 404 — not a 403, because we do not want to confirm the report exists. The check is enforced in a single middleware (require_workspace_access) that every report, meeting, session, and account route depends on. It is tested on every deploy.
Cross-workspace queries are not exposed by the API. Internally, our analyst services run with row-level security enforced at the Postgres role layer, so even an application-layer bug cannot leak rows across workspaces.
4. PHI-eligible workspaces
A workspace can be flagged as PHI-eligible. This is gated on two things being true at the same time:
- The workspace is on Professional or Enterprise and
- A signed Business Associate Agreement (BAA) is on file with Felarity.
To request a BAA, email legal@felarity.com from a domain matching the workspace owner's email. Turnaround is typically three business days. We will counter-sign and return a PDF; once it is logged against your account, your workspace owner can flip the PHI-eligible flag in /app/workspace/compliance/.
What changes when the flag is on:
- DLP runs in strict mode (see §6) — every transcript chunk and every LLM prompt is scanned for PHI patterns before it leaves the gateway boundary.
- Cross-region data movement is disabled. Audio, transcripts, embeddings, and reports stay in US-East-1.
- Council analysis is restricted to the on-premise models on prod1 — no third-party LLM provider sees content from this workspace, ever.
- Retention defaults change: audio retention is capped at 30 days even if you set it higher, unless you co-sign a written retention exception.
- Audit log fields expand: every read of a transcript, report, or sample produces an
accessrow with the requesting user, IP, and route.
5. Retention
Three retention timers, all separately configurable per workspace at /app/workspace/retention/:
| Stream | Default | Minimum | Maximum |
|---|---|---|---|
| Raw audio chunks | 30 days | 0 (process and delete) | 365 days |
| Transcripts | 90 days | 0 | 2,555 days (7 years) |
| Reports (with attestation) | 2,555 days | 30 days | 2,555 days |
"Process and delete" — a retention of 0 — means the artifact is deleted at the close of the post-session pipeline, after the report is signed. The audio is gone; the report references hashes, not bytes. This is the right setting for most legal and HR workspaces. It does cost you the ability to re-run a session against improved models later.
Deletes are hard deletes. We do not keep a tombstone copy in cold storage. The only artifact that survives a 0-day retention is the report (with its hash references to audio that no longer exists).
POST /api/account/export to receive a zip of every artifact tied to their account, and DELETE /api/account (with the X-Felarity-Confirm-Delete: yes header) to hard-delete their account. Workspace owners can do the same for the workspace at /app/workspace/danger/.
6. DLP
Data loss prevention runs in two modes — standard (default for non-PHI workspaces) and strict (PHI-eligible workspaces, opt-in elsewhere).
The primary engine is Microsoft Presidio with our extended recognizer set: US Social Security numbers, US ITINs, US driver's license patterns by state, credit card PANs (Luhn-checked), routing+account number pairs, US passport numbers, MRNs in HL7 format, NPI numbers, ICD-10 codes adjacent to names, and the standard PII set (email, phone, address). A regex fallback catches anything Presidio misses for the well-known patterns; the fallback is the safety net, not the primary detector.
What DLP does, in order:
- Every transcript chunk is scanned before it is persisted. Detected entities are tagged with a span and a confidence score.
- Before any chunk is sent to the council for analysis, high-confidence detections are redacted in the prompt (replaced with
<REDACTED:SSN>,<REDACTED:MRN>, etc.). The original token is preserved in the database for your operators to see; only the prompt to the model is redacted. - In strict mode, if a redaction is necessary on a chunk, the chunk is also flagged in the report's data handling appendix. You see what we redacted and why.
DLP does not prevent a user from speaking a SSN out loud. It prevents that SSN from reaching the analysis model and from sitting in an unredacted form in the prompt logs.
7. API key hygiene
API keys are minted from the web app at /app/account/keys/. Only an authenticated browser session can mint a key — you cannot mint a key from another key. Keys are scoped to a single workspace and to a set of permissions (read reports, write reports, read usage, manage members).
The key is shown once, at the moment of creation. We display the full token (flrt_*) on the response, and after you dismiss the dialog, we display only the prefix (flrt_abc1...) forever after. We do not store the plaintext. If you lose a key, revoke it and mint a new one.
# mint (browser session required)
POST /api/v1/keys
body: { name: "ci-runner", scopes: ["reports:read","usage:read"] }
→ { id, key: "flrt_a1b2c3...", prefix, scopes, created_at }
# list
GET /api/v1/keys
→ [ { id, name, prefix, scopes, last_used_at, created_at } ]
# revoke
DELETE /api/v1/keys/{id}
→ 204
Recommended handling:
- Store keys in a secret manager (1Password, AWS Secrets Manager, HashiCorp Vault, Doppler). Do not commit them to source control. Do not paste them in Slack.
- Mint a separate key for each automation. If a CI runner is compromised, you revoke one key, not all of them.
- Rotate keys on a schedule you can stomach — quarterly for read-only, monthly for write.
- Watch
last_used_at. A key that has not been used in 30 days should be revoked. - On Enterprise, you can require that all keys be scoped (no full-permission keys). That setting is at
/app/workspace/security/api-policy/.
8. Audit log
Every state-changing action in a workspace produces an audit log entry. Sign-in, sign-out, MFA enrollment and reset, member add and remove, role change, workspace setting change, retention change, API key mint and revoke, report generation, report export, account export, account delete.
The log is append-only and hash-chained. Each entry contains the SHA-256 of the previous entry in prev_hash; tampering with any historical entry breaks the chain and is detected on the next verification pass. The chain is verified automatically once per day and on every export.
Workspace owners can read the log at /app/workspace/audit/ or stream it via GET /api/v1/audit?since=... (Bearer flrt_*, scope audit:read). The web view supports filtering by actor, by action type, and by date range. Export to CSV or JSON is one click.
The log is retained for the lifetime of the workspace, regardless of the per-stream retention timers above. You cannot configure it shorter. This is intentional: an audit log you can delete is not an audit log.
9. Attestation chain
Every report Felarity produces is signed with an eight-node Merkle attestation chain. The nodes are:
- Audio capture (hash of the concatenated raw audio for the session)
- Transcription (hash of the full transcript, before diarization)
- Contradiction detection — pre-attribution (hash of detected contradictions with span references)
- Diarization (hash of the speaker turn map)
- Attribution binding (hash of contradiction-to-speaker bindings)
- Acoustic analysis (hash of credibility markers — speech rate, pause patterns, stress)
- Topology (hash of the NetworkX graph and the pattern classification)
- Final report (hash of the rendered report body)
The Merkle root is signed with our Ed25519 signing key. The public half lives at /.well-known/felarity-signing-key.pem and at GET /api/verify/public-key. Anyone — not just a Felarity customer — can verify a report by posting it to POST /api/verify, or by running the verification offline against the public key.
curl -X POST https://api.felarity.com/v1/api/verify \
-H "Content-Type: application/json" \
-d @report.json
# → { valid: true, signed_at, signing_key_fingerprint, chain: [...] }
If a report's contents are altered after signing — by anyone, including us — the signature no longer validates. We do not have a "trust us" override.
10. Incident response
If you believe you have found a vulnerability, write to security@felarity.com. PGP key fingerprint and full disclosure policy are at /trust/responsible-disclosure/.
Our commitments:
- Two business day acknowledgement. A human, not an autoresponder, replies within two business days of receipt.
- 72 hours for material incidents. If we confirm a security incident that materially affects your workspace — unauthorized access, data exposure, integrity loss — you receive direct written notification within 72 hours of confirmation. Notification goes to the workspace owner's email of record. For Enterprise, also to the security contact on file.
- Post-incident report. Within 30 days of resolution, we publish a post-incident report covering scope, root cause, timeline, and remediations. Customer-affecting incidents are reported privately first; the public summary follows.
- No silent fixes. If a fix changes behavior you can observe, the changelog says so.
For the avoidance of doubt: scraping, automated scanning, denial-of-service testing, and social engineering of Felarity staff are out of scope. Good-faith manual testing against your own workspace is in scope and we will not take legal action against researchers who follow the disclosure policy.
Questions about a control in production: hello@felarity.com. Reporting a vulnerability: security@felarity.com. BAA or legal paperwork: legal@felarity.com.