Security Model
This document describes how ThreatWeaver protects customer data, controls access, and defends itself against attack. It is written for security-conscious buyers, compliance teams, penetration testers, and IT leadership evaluating the platform.
The security model is grounded in defense in depth: multiple independent controls that each limit blast radius if another layer fails.
Security Architecture Overviewβ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β BROWSER LAYER β
β HttpOnly cookies (no localStorage) Β· CSP headers Β· SameSite β
ββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββ
β TLS 1.2+
ββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββββββ
β API GATEWAY LAYER (Express.js) β
β Rate limiting Β· CORS allowlist Β· Origin CSRF validation β
β Body size limit Β· JSON depth check Β· HSTS Β· X-Frame-Options β
ββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββββββ
β AUTHENTICATION LAYER β
β HS256 JWT Β· HttpOnly cookie Β· Token blacklist Β· MFA (TOTP) β
β SSO (Entra ID / SAML) Β· IP allowlist/blocklist enforcement β
ββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββββββ
β AUTHORIZATION LAYER β
β RBAC (8 built-in roles) Β· 70+ granular permissions β
β requirePermission() middleware Β· requireModule() gating β
ββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββββββ
β DATA LAYER (PostgreSQL) β
β Schema-per-tenant isolation Β· search_path scoping β
β Row-Level Security (RLS) Β· Parameterized queries (TypeORM) β
β AES-256-GCM for stored secrets β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Each layer operates independently. A bypass at one layer does not grant access at the next.
Authentication Securityβ
JWT Implementationβ
ThreatWeaver authenticates users with JSON Web Tokens (JWT). Key properties of the implementation:
| Property | Value |
|---|---|
| Algorithm | HS256 (HMAC-SHA256) β algorithm pinned on both sign and verify to prevent algorithm confusion attacks |
| Access token lifetime | Default 15 minutes (JWT_EXPIRES_IN, configurable) |
| Refresh token lifetime | 7 days (JWT_REFRESH_EXPIRES_IN, configurable) |
| Token payload | userId, role, tenantId, tenantSlug, tenantPlan, licenseJti |
| Secret | Separate secrets for access tokens and refresh tokens (JWT_SECRET and JWT_REFRESH_SECRET) |
The JWT algorithm is pinned to HS256 at both jwt.sign() and jwt.verify() using algorithms: ['HS256']. This prevents the well-known alg: none and RS256βHS256 confusion attacks.
Cookie Securityβ
Tokens are delivered and stored as HttpOnly cookies, not in localStorage or sessionStorage. This is a deliberate architectural choice:
- HttpOnly prevents any JavaScript β including XSS payloads β from reading the token value
- SameSite is set to
Laxin development andNone(withSecure) in production - Secure flag is set in production, ensuring cookies are only transmitted over TLS
- The
refreshTokencookie is scoped topath: /api/authso it is not sent on every API request β only to the token refresh endpoint
Cookie: token=<jwt>; HttpOnly; Secure; SameSite=None; Path=/
Cookie: refreshToken=<jwt>; HttpOnly; Secure; SameSite=None; Path=/api/auth
Bearer token fallback (the Authorization: Bearer <token> header) is also accepted for API clients, scripts, and Postman β but browser-based sessions always use cookies.
Token Blacklisting and Revocationβ
ThreatWeaver implements two layers of token revocation:
1. User-level revocation β when an account is deactivated or suspended, the user ID is added to an in-process revocation set (_revokedUserIds). This takes effect on the very next request with zero propagation delay β there is no cache window during which a deactivated user can still make requests.
2. Token-level blacklist β when a user logs out or is force-logged-out, the specific JWT is added to:
- An in-memory bounded cache (up to 5,000 tokens, self-cleaning)
- The
token_blacklistdatabase table (for persistence across restarts)
Incoming tokens are checked against both before any database query. A revoked token returns 401 USER_REVOKED immediately.
3. Monotonic timestamp protection β the license service validates that the system clock has not moved backwards (anti-clock-tampering). This prevents an attacker from setting the clock back to make expired tokens appear valid.
Multi-Factor Authentication (MFA)β
ThreatWeaver supports TOTP-based MFA (Time-based One-Time Password) compatible with Google Authenticator, Authy, Microsoft Authenticator, and 1Password.
- MFA setup generates a TOTP secret, a QR code, and backup codes
- Once enrolled, MFA is required at every login
- MFA status is stored per-user (
twoFactorEnabledflag) - Backup codes are hashed and stored β they are shown only once at setup
- MFA validation endpoint (
/api/auth/mfa/validate) is rate-limited to 10 attempts per 15 minutes
Administrators can force MFA for all users via Admin β Settings β Security Policy.
Single Sign-On (SSO)β
| Provider | Protocol | Status |
|---|---|---|
| Microsoft Entra ID (Azure AD) | OAuth2 / OIDC | Supported |
| Okta | SAML 2.0 | Supported |
| Google Workspace | SAML 2.0 | Supported |
| Custom SAML IdP | SAML 2.0 | Supported |
SSO is configured per-tenant in Admin β Settings β SSO. Role mapping from IdP group attributes is supported. When SSO is the exclusive authentication method, local password login can be disabled.
The SSO implementation:
- Validates SAML assertions against the configured IdP certificate
- Maps IdP user attributes to ThreatWeaver user fields
- Creates user accounts on first SSO login (just-in-time provisioning)
- Respects the tenant's seat limit during JIT provisioning
Password Securityβ
| Control | Implementation |
|---|---|
| Password hashing | bcrypt with configurable salt rounds (default 10) |
| Timing normalization | Pre-computed bcrypt hash used during login to prevent user enumeration via response timing |
| Account lockout | Configurable failed-attempt threshold before lockout |
| Password complexity | Minimum length and complexity enforced server-side via Zod schema |
| Forgot password | Time-limited reset tokens, rate-limited to 10/minute |
Authorizationβ
RBAC with 8+ Built-In Rolesβ
ThreatWeaver implements role-based access control with fine-grained permissions. Eight built-in roles ship with the platform:
| Role | Typical User | Access Level |
|---|---|---|
| admin | Security team lead, IT administrator | Full platform access including user management, settings, and security configuration |
| analyst | SOC analyst, security engineer | View and manage vulnerability data, create reports, manage findings |
| security_analyst | Dedicated security engineer | Focused on vulnerability analysis with scan creation and AppSec access |
| viewer | Executive, stakeholder | Read-only access to dashboards and reports |
| compliance_officer | Compliance team member | Compliance reporting and attestation |
| scanner_admin | AppSec engineer, scan infrastructure | Full scanner and scan management, remediation |
| manager | Security manager, project lead | View and manage vulnerability data, create reports, manage teams |
Administrators can create custom roles with any combination of the 70+ available permissions using the RBAC v2 system (Admin β User Management β Roles).
Permission Model (70+ Permissions)β
Permissions are organized by domain. Key permission categories:
| Category | Sample Permissions |
|---|---|
| User & Role Management | view_users, manage_users, view_roles, manage_roles |
| System | view_settings, manage_settings |
| Dashboard & Data | view_dashboard, export_data |
| Assets & Vulnerabilities | view_assets, view_vulnerabilities, manage_assets |
| AppSec | view_appsec, manage_appsec |
| Scan Management | create_scans, launch_scans, pause_resume_scans, stop_scans, delete_scans, view_scan_results, export_scan_results |
| VFP (Fix Planner) | view_vfp, vfp_prioritize, vfp_generate_workpack, vfp_create_ticket, vfp_approve_exception |
| AI Features | use_ai, ai_fix_plan, ai_ticket_writer, ai_exec_summary, ai_root_cause, ai_chat |
| Compliance | view_compliance, manage_compliance, view_reports, manage_reports |
| Cloud Security | view_cloud_security, manage_cloud_security |
| Identity Security | view_identity_security, manage_identity_security |
| AI Security | view_ai_security, manage_ai_security |
| Connectors | view_connectors, manage_connectors |
| Remediation | approve_remediation, execute_remediation |
| Security Administration | view_security, manage_security, view_audit_logs, manage_sso, manage_sessions |
| Scanner Management | view_scanners, manage_scanners, view_scan_budget |
Permission checks are enforced in middleware on every route using requirePermission(). There is no way to bypass this check from the client.
Module Gatingβ
Every product module has a corresponding requireModule() middleware check applied at the router level. This check happens after authentication and before the route handler executes:
Request β authenticate() β requirePermission() β requireModule() β handler
If a module is not in the tenant's allowedModules list (from the license JWT), the request returns 403 MODULE_DISABLED regardless of the user's role. Module gating and RBAC are independent checks β both must pass.
Tenant Isolation via PostgreSQL Schema-per-Tenantβ
ThreatWeaver runs in schema-per-tenant mode in multi-tenant deployments. Each tenant gets a dedicated PostgreSQL schema (tenant_{slug}) containing a complete copy of all application tables.
How isolation is enforced:
- On every request, the tenant ID is decoded from the user's JWT
- The tenant middleware sets
search_path = tenant_{slug}for the database connection - All TypeORM queries execute within that schema β there is no cross-schema access possible through the ORM
- A PostgreSQL GUC variable is set per-connection and reset before the connection returns to the pool, preventing data bleed between requests
- Row-Level Security (RLS) policies on sensitive tables enforce
tenant_idmatching at the database level as a defense-in-depth measure - Schema names are validated against a strict regex before use to prevent SQL injection via schema name
What this means:
- Customer A's vulnerability data is physically stored in
tenant_acme.vulnerabilities - Customer B's data is in
tenant_globex.vulnerabilities - Even if application-level authorization is bypassed, RLS at the database level prevents cross-tenant data reads
- The
publicschema contains only template data and registries β no customer data
Network Securityβ
CORS Configurationβ
CORS is configured with an explicit allowlist per environment. Only origins that are explicitly configured in CORS_ORIGIN are permitted. The credentials: true flag is set to allow cookies to be sent on cross-origin requests (required for the frontend-backend architecture).
Wildcard CORS (*) is never used in any environment.
HTTP Security Headersβ
ThreatWeaver sets the following security headers on every response using the helmet middleware:
| Header | Value | Purpose |
|---|---|---|
Content-Security-Policy | default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline' fonts.googleapis.com; img-src 'self' data: https:; connect-src 'self' [tenable-api-url] | Prevents XSS and data injection |
Strict-Transport-Security | max-age=31536000; includeSubDomains | Forces HTTPS for 1 year, including all subdomains |
X-Frame-Options | SAMEORIGIN (via helmet default) | Prevents clickjacking |
X-Content-Type-Options | nosniff | Prevents MIME sniffing |
Referrer-Policy | strict-origin-when-cross-origin | Controls referrer information leakage |
Permissions-Policy | camera=(), microphone=(), geolocation=(), payment=(), usb=() | Restricts browser feature access |
Cache-Control | no-store, no-cache, must-revalidate, private | Prevents sensitive data caching |
ETags are disabled (app.disable('etag')) to prevent cache fingerprinting.
Rate Limitingβ
ThreatWeaver applies tiered rate limiting:
| Layer | Limit | Window | Applies To |
|---|---|---|---|
| Global API | 100 requests | 1 minute | All /api/* routes (configurable via RATE_LIMIT_MAX_REQUESTS) |
| Auth endpoints | 10 requests | 15 minutes | /api/auth/login, /api/auth/change-password, /api/auth/mfa/validate |
| Invite/reset flows | 5 requests | 1 minute | /api/auth/invite, /api/auth/reset-password |
| Forgot password | 10 requests | 1 minute | /api/auth/forgot-password |
| AppSec routes | Per-route limits (2000/min read, 120/min write) | 1 minute | Applied per-route within AppSec module |
Rate limiting is keyed by client IP. Standard headers (RateLimit-Remaining, RateLimit-Reset) are returned so clients can self-throttle.
High-traffic routes that are safe to exempt from global rate limiting (dashboard polling, AppSec reads, health checks) are explicitly excluded from the global limiter.
CSRF Protectionβ
ThreatWeaver protects against Cross-Site Request Forgery using Origin header validation on all mutating requests (POST, PUT, PATCH, DELETE):
- The
OriginorRefererheader is extracted from the request - It is matched against the configured CORS allowlist
- If the origin is not in the allowlist, the request returns
403 Forbiddenwith message"Cross-origin request blocked"
Requests without an Origin header (same-origin or non-browser clients) are allowed through β this is correct behavior because browsers always include the Origin header on cross-origin requests.
Combined with SameSite=None cookies (which require Secure), this provides defense-in-depth: cookies are not sent cross-site unless the origin is also allowed.
IP Allowlisting and Blocklistingβ
Administrators can configure per-tenant IP rules in Admin β Security:
- IP allowlist: When configured, only IPs matching the allowlist can authenticate (CIDR ranges supported)
- IP blocklist: IPs on the blocklist are rejected at the login endpoint
- Both lists support CIDR notation (e.g.,
192.168.1.0/24) - Entries can have optional expiration times
- All IP enforcement events are logged to the security audit log
Body Size and Depth Limitsβ
- Body size limit: 1 MB maximum request body (reduced from a previous 10 MB limit; legitimate payloads are under 10 KB)
- JSON nesting depth: Requests with JSON bodies nested deeper than 20 levels are rejected with
400 Bad Requestβ this prevents DoS via deeply nested object attacks - Both limits return clear error messages:
"Request body exceeds the size limit"and"Request body nesting depth exceeds limit"
Data Securityβ
AES-256-GCM Encryption for Stored Secretsβ
Sensitive data stored in the database is encrypted at rest at the application layer using AES-256-GCM:
| Data type | Encryption method |
|---|---|
| Scan target credentials (usernames, passwords, API keys) | AES-256-GCM, encrypted before writing to DB |
| Phase 0 intelligence session data | AES-256-GCM in Phase0Session entity |
| License key on disk | AES-256-GCM, machine-bound key derived from host identity |
| License checkin nonce on disk | AES-256-GCM, machine-bound key |
Credentials are never:
- Stored in plaintext in the database
- Logged (the logging middleware strips credential fields)
- Included in finding reports or API responses beyond what the user intentionally submits
Input Validation via Zodβ
All API request bodies are validated against Zod schemas before reaching route handlers. This provides:
- Type checking with runtime enforcement (not just TypeScript compile-time checking)
- Allowlist-based field validation β unexpected fields are stripped or rejected
- Custom validators for security-sensitive fields (URLs, email addresses, IDs)
Validation failures return 400 Bad Request with specific field-level error messages.
SQL Injection Preventionβ
All database queries use TypeORM with parameterized queries. Raw SQL is used only in specific migration and administrative operations, and even there, user-supplied values are always passed as bound parameters β never interpolated into the query string.
Tenant schema names are additionally validated against a strict regex before being used in search_path statements β this closes the specific vector of SQL injection via schema name.
XSS Preventionβ
ThreatWeaver implements multiple XSS defenses:
- CSP headers β
script-src 'self'blocks inline script execution and external script loading - HttpOnly cookies β even if XSS code executes, it cannot read the authentication token
- Output encoding β React's JSX encoding handles the vast majority of reflected XSS vectors automatically
stripHtmlTagsmiddleware β applied to user-provided text fields stored in the database, preventing stored XSS in displayed content- CSV injection prevention β exported CSV files prefix dangerous characters (
=,+,-,@) in cell values to prevent formula injection when opened in spreadsheet software
Outbound URL Validationβ
All outbound HTTP requests from the backend (webhooks, integration endpoints, AI provider calls) are validated through a validateOutboundUrl service. This prevents Server-Side Request Forgery (SSRF) attacks where an attacker could supply a URL pointing to internal infrastructure.
The validator blocks:
- Private IP ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.0/8)
- Link-local addresses (169.254.0.0/16)
- IPv6 loopback and private ranges
- Non-HTTP(S) schemes
Threat Modelβ
Key Assets to Protectβ
| Asset | Sensitivity | Why |
|---|---|---|
| Vulnerability data | High | Contains detailed exploitability information for customer infrastructure |
| Scan credentials | Critical | API keys and passwords for target systems |
| Tenant data (schema isolation) | Critical | Customer data must not cross tenant boundaries |
| Authentication tokens | High | Compromise leads to full account takeover |
| License key | Medium | Compromise could enable unauthorized access |
| Audit logs | Medium | Tampered logs impede incident investigation |
Threat Actorsβ
| Actor | Capabilities | Primary Concern |
|---|---|---|
| External attacker (unauthenticated) | Network access, credential stuffing, public exploit tools | Gaining initial access |
| Malicious insider (authenticated user) | Valid session, legitimate permissions | Privilege escalation, data exfiltration |
| Compromised tenant (cross-tenant) | Authenticated to their own tenant | Accessing another tenant's data |
| Compromised dependency | Code execution in application context | Supply chain attack |
Threat Mitigationsβ
| Threat | Mitigation |
|---|---|
| XSS leading to token theft | HttpOnly cookies make the token inaccessible to JavaScript. CSP blocks inline scripts. |
| CSRF | SameSite cookie policy + Origin header validation on all mutating requests |
| SQL injection | TypeORM parameterized queries + schema name regex validation |
| Token replay after logout | In-memory token blacklist + database blacklist checked on every request |
| Token algorithm confusion | JWT algorithm pinned to HS256 at both sign and verify |
| Tenant data leak | Schema-per-tenant + search_path + RLS policies at the database level |
| Brute-force login | 10 attempts per 15 minutes rate limit + account lockout |
| Password enumeration | Timing normalization via pre-computed bcrypt hash dummy comparison |
| Privilege escalation | RBAC permission checks on every route via requirePermission() middleware |
| Module access beyond license | requireModule() middleware checks allowedModules from license JWT |
| Stored secret exposure | AES-256-GCM encryption before writing to database |
| DoS via large payloads | 1 MB body limit + JSON nesting depth limit (20 levels) |
| DoS via request flooding | Tiered rate limiting on all API routes |
| SSRF from webhook/integration URLs | validateOutboundUrl service blocks private IP ranges |
| Clock manipulation (license tampering) | Monotonic timestamp tracking with cross-referencing across file and DB stores |
| Supply chain attack via npm | Dependency pinning, regular npm audit, no wildcard version ranges |
| Data exfiltration via CSV exports | CSV injection prevention in export service |
Scan Sensor Securityβ
Distributed scan sensors (used for remote network scanning) have their own security model:
| Layer | Mechanism |
|---|---|
| Enrollment | Cryptographic enrollment token (twen_{tenantSlug}_{32hexChars}) with regex validation before use |
| Mutual authentication | ECDSA P-256 challenge-response with 30-second TTL |
| Transport | Encrypted WebSocket over TLS (outbound-only, port 443 β no inbound ports) |
| Session | JWT issued post-enrollment; exponential backoff reconnection |
| Tenant scoping | Sensors are bound to a specific tenant and cannot access other tenants' data or targets |
Sensors initiate all connections outbound to the platform. There are no inbound firewall holes required. Compromising a sensor does not give access to other tenants' data.
Audit Loggingβ
ThreatWeaver maintains comprehensive audit logs for security monitoring and compliance.
What Is Loggedβ
| Category | Events |
|---|---|
| Authentication | Login success/failure, MFA verification, password changes, session creation/termination, account lockout, IP block enforcement |
| Administrative actions | User creation/deletion, role changes, permission changes, feature flag changes, system settings modifications |
| Data access | API access logs (available for high-sensitivity endpoints), security audit queries |
| Scan operations | Assessment creation, scan execution, finding lifecycle changes (open β accepted risk β remediated) |
| Tenant operations | Schema creation, entitlement changes, tenant provisioning and deprovisioning |
| License events | License import, activation, state transitions, phone-home success/failure, lockout triggers |
| Security events | IP allowlist/blocklist changes, failed authentication attempts, CSRF rejection, rate limit enforcement |
Accessing Audit Logsβ
- Security audit logs: Admin β Security β Audit Log
- License audit log: Admin β Settings β License β View Audit Log
- Logs are queryable with date ranges and event type filters
Exporting Audit Logsβ
Audit logs can be exported in two ways:
- CSV/JSON export β from the Admin panel for manual review or external processing
- S3 export β configured in Admin β Settings β Data Retention for continuous archival to an S3-compatible bucket (suitable for long-term SIEM retention)
Retentionβ
Default retention is indefinite (no automatic deletion). Data retention policies can be configured in Admin β Settings β Data Retention to define automatic archive or deletion schedules.
Incident Responseβ
Discovering a Security Issueβ
If you discover a potential security vulnerability in ThreatWeaver:
- Do not disclose publicly until BluCypher has had the opportunity to investigate and patch
- Report to: security@blucypher.com with a description of the issue and reproduction steps
- Include your contact information for follow-up
- BluCypher commits to acknowledging reports within 24 hours and providing a status update within 72 hours
Critical findings (remote code execution, authentication bypass, data exposure) are patched within 48 hours of confirmed reproduction.
For Customers Experiencing a Security Incidentβ
If you believe your ThreatWeaver deployment has been compromised:
- Immediately revoke all user sessions via Admin β Security β Force Logout All Sessions
- Rotate the
JWT_SECRETandJWT_REFRESH_SECRETenvironment variables and restart the backend (this invalidates all existing tokens) - Review the security audit log (Admin β Security β Audit Log) for unexpected logins or actions
- Check IP allowlist enforcement (Admin β Security β IP Management)
- Contact BluCypher support if operating on the managed SaaS platform
Self-Testing: ThreatWeaver Uses Itselfβ
ThreatWeaver's AppSec Scanner module is used for ThreatWeaver's own internal security testing. The platform runs automated assessments against its own staging environment as part of the development process. Findings discovered through this process are treated with the same priority as customer-reported vulnerabilities.
This means:
- The team has direct operational experience with the scanner's output quality
- Security issues discoverable by the scanner are prioritized for remediation before release
- The scanner's ground truth benchmark includes ThreatWeaver itself as a target
Compliance and Certificationsβ
Frameworks ThreatWeaver Helps Customers Meetβ
ThreatWeaver maps its findings and controls to major compliance frameworks:
| Framework | Coverage |
|---|---|
| PCI-DSS 4.0 | Requirements 1, 6, and related controls |
| SOC 2 Type II | Trust Service Criteria CC6, CC7 |
| ISO 27001:2022 | Annex A controls A.8.28, A.8.29, and related |
| NIST 800-53 | Full control mapping |
| OWASP Top 10 (2021) | Full coverage in AppSec scanner agents |
| OWASP API Security Top 10 | Full coverage in AppSec scanner agents |
Platform Certifications (ThreatWeaver's Own Compliance Status)β
| Certification | Status |
|---|---|
| SOC 2 Type II (platform) | In progress β target completion H2 2026 |
| ISO 27001 (platform) | Planned β following SOC 2 |
| FedRAMP | Under evaluation |
Contact sales for the latest certification status and timeline. Customers requiring compliance documentation (questionnaires, security assessments) should contact security@blucypher.com.
Frequently Asked Questionsβ
Q: Can BluCypher staff access our data?
In the SaaS deployment, BluCypher engineering has infrastructure-level access (database, logs) for operational support. All access is logged. On-premises deployments give customers full control with no BluCypher access. BluCypher is working toward a formal access control audit trail for SaaS environments as part of SOC 2 compliance.
Q: Where is SaaS data hosted?
The SaaS platform runs on Render (backend), Vercel (frontend), and Supabase (PostgreSQL). All providers enforce encryption at rest and in transit.
Q: Can we bring our own encryption keys (BYOK)?
Not currently for SaaS. On-premises deployments manage their own encryption at the infrastructure level. Customer-managed keys for SaaS is under consideration for a future release.
Q: Is there a SOC 2 report available?
SOC 2 Type II certification for the ThreatWeaver platform is in progress. Contact sales for current status.
Q: How are scan credentials protected?
Scan credentials are AES-256-GCM encrypted before writing to the database. They are never logged, never included in finding reports, and are accessible only to users with the manage_scan_credentials permission.
Q: Does ThreatWeaver support SAML-based SSO?
Yes. ThreatWeaver supports SAML 2.0 for Okta, Google Workspace, and any custom SAML IdP. Microsoft Entra ID is supported via OAuth2/OIDC. Configuration is per-tenant in Admin β Settings β SSO.
Q: What happens if a user's account is compromised?
An administrator can immediately deactivate the account in Admin β User Management. Deactivation adds the user ID to an in-process revocation set β all active sessions are invalidated on the next request with no caching delay.