Security
Last updated: April 14, 2026
Lixir is built to handle your team's decision data with care. This page describes the security measures in place to protect your workspace. For full details on what data we collect and your rights, see our Privacy Policy.
Encryption at Rest
All sensitive data is encrypted using AES-256-GCM with per-tenant encryption keys. Keys are derived via HKDF-SHA256 from a master key combined with each workspace's team ID. This means:
- One tenant's data cannot be decrypted with another tenant's key
- A database breach alone does not expose sensitive content without the corresponding key material
- Key rotation is supported via a versioned master key fallback
Encrypted fields include:
- Slack bot tokens
- Google OAuth access and refresh tokens
Question content (title, context, question text) is not stored in our database. It exists only in Slack messages and, if connected, in Google Sheets that you own. Our database stores only question metadata (status, channel, timestamps) and Slack user IDs.
Tenant Isolation
Every database query is scoped by workspace (team) ID, enforced at the repository layer. A branded TeamId TypeScript type prevents accidental cross-tenant access at compile time. Repositories require teamId as a mandatory first argument — there is no code path that can query across workspaces.
Infrastructure
- Compute: Cloudflare Workers — serverless, isolated V8 execution per request. No persistent servers or shared runtime.
- Database: Cloudflare D1 (SQLite) — parameterized prepared statements only. No string interpolation in SQL, enforced by linting.
- Cache & state: Workers KV — short-lived entries only (OAuth nonces expire in 10 minutes, rate limit counters in 60 seconds).
- Async processing: Cloudflare Queues — Google Sheets sync and heavy operations run asynchronously without blocking user interactions.
Application Security
- Slack request verification: Every incoming request from Slack is verified against the signing secret with timestamp replay protection.
- Rate limiting: Per-workspace rate limits on all Slack command and interaction endpoints.
- No plaintext secrets in logs: Enforced by static analysis rules (opengrep). Tokens and keys are never logged in plaintext.
- Parameterized SQL only: All database queries use prepared statements with bound parameters. No dynamic SQL construction, enforced by linting.
- TypeScript strict mode: No implicit any, unused variables flagged, strict null checks enabled.
- Security scanning: opengrep (OWASP rules) runs on every code change.
OAuth Permissions
Lixir requests the minimum set of permissions (scopes) needed to function. When you install via Slack, only bot-level scopes are requested — no user-token scopes. Google Sheets access is entirely optional and only requested if you choose to connect it from App Home.
Slack Bot Scopes
| Scope | Why it's needed |
|---|---|
commands | Register and respond to the /ask slash command |
chat:write | Post decision questions and outcome messages in channels the app has joined |
chat:write.public | Post messages in public channels without needing to join first |
users:read | Look up display names for question authors and voters |
team:read | Read workspace name and ID during installation |
channels:read | Read channel names and membership information |
channels:join | Join a channel in order to pin the meeting backlog as a channel tab bookmark |
lists:read | Read Slack Lists to display the meeting backlog |
lists:write | Create and update Slack List entries when questions are deferred to the meeting backlog |
canvases:write | Create and update a per-channel meeting-agenda canvas when /agenda is invoked |
bookmarks:write | Pin the meeting backlog Slack List as a tab in the channel for easy access |
im:write | Open direct-message channels to deliver opt-in nudges (deadline reminders, asker escalations) when an admin enables DM delivery |
Google OAuth Scopes (optional)
Only requested if you explicitly connect a Google account from the Lixir App Home tab. This flow is only available on the Team tier. You can disconnect Google access at any time from App Home or from your Google account's third-party apps page.
| Scope | Why it's needed |
|---|---|
spreadsheets | Read and write the meeting-backlog sheets you create or link from Lixir. Full scope URI: https://www.googleapis.com/auth/spreadsheets |
drive.file | Create new spreadsheets in your Drive and access files you explicitly link through Lixir's UI. This scope does not grant access to any other files in your Drive. Full scope URI: https://www.googleapis.com/auth/drive.file |
Data Deletion
When a Slack workspace uninstalls Lixir, all associated data (installation record, questions, votes, and tokens) is automatically cascade-deleted. Individual users can erase their own data via the "Delete my data" button in Lixir's App Home tab. See our Privacy Policy for full retention and erasure details.
Reporting a Vulnerability
If you believe you've found a security vulnerability in Lixir, please report it via email:
Include as much detail as possible: steps to reproduce, affected functionality, and potential impact.
Response Timeline
- Acknowledgment: within 48 hours
- Initial assessment: within 5 business days
- Fix for critical issues: within 7 days where feasible
Scope
In scope:
- The Lixir Slack application and its API endpoints
- The lixir.app website
- Encryption, authentication, and authorization logic
- Data isolation and access control mechanisms
Out of scope:
- Third-party services (Slack, Google, Stripe, Cloudflare) — report to those providers directly
- Social engineering or phishing attempts
- Denial-of-service attacks
Contact
For security concerns: security@lixir.app
For general inquiries: contact@lixir.app