Security whitepaper
How Beacon protects your data
Summary
- Isolation is structural. One database serves every organization, and PostgreSQL row-level security, forced on every tenant table, is what keeps them apart. A request without an organization context sees zero rows.
- Encrypted everywhere. TLS in transit, encrypted storage and backups at rest, argon2id password hashes, hashed tokens and API keys, AES-256-GCM for single sign-on secrets.
- AI assists; people decide. Ticket text goes to Anthropic under terms that forbid training. Every feature can be switched off. No ticket is closed by AI and no reply is sent without a person.
- Your data leaves when you say so. Full export on every plan, self-serve deletion of the whole organization, backups that roll off within 30 days.
- No SOC 2 report yet. Section 16 lists what is planned and what is not in place, so a reviewer does not have to guess.
1. Scope
Beacon is a help desk, asset management, and knowledge base platform operated by SYV Technologies LLC. This document describes the hosted service: the web app at app.beaconhelpdesk.com, the API at api.beaconhelpdesk.com, the iOS app, and email-to-ticket at tickets.beaconhelpdesk.com. The on-premises edition runs the same software on a customer's own servers; its hosting controls are the customer's, and sections 3, 4, 6, 8, and 9 apply unchanged.
Everything here describes what is implemented today. Planned work is confined to section 16. If you find a statement that does not match the product, tell us at security@beaconhelpdesk.com and we will correct the document.
2. Architecture
Web app (Next.js) iOS app (Expo) Integrations (REST, webhooks)
\ | /
\ | /
API (Fastify, TypeScript, stateless)
auth · roles · row-level security
tickets · assets · automations · AI
/ | \
PostgreSQL Private encrypted Anthropic API
one database, volume for triage, replies,
RLS per organization attachments article drafts
The API is stateless; production runs one instance today (section 16). All state lives in a single PostgreSQL database with an organization id on every tenant table, and attachments are private objects in an encrypted object-storage bucket (Tigris Data, written from the same United States region). The web app is a client of the same API that customers use; it holds no customer data of its own. Email is sent and received through Resend. AI features call Anthropic's API.
Hosting: the API and database run on Fly.io in the United States (Virginia). The web app and this website run on Vercel in the United States. The whole system is TypeScript end to end, with one shared schema from the database row to the mobile screen, which keeps validation consistent across every surface.
3. Tenant isolation
Beacon is a single-database, multi-tenant system. Isolation is enforced by PostgreSQL row-level security (RLS), not by application code remembering to add a WHERE clause. The mechanism, exactly:
- Every tenant table has a non-null
org_idcolumn referencing the organizations table. - A dedicated database role,
beacon_app, cannot log in directly and cannot bypass RLS. Row-level security is enabled and forced on every tenant table, with a policy that allows a row to be read or written only when itsorg_idequals the organization id set for the current transaction:CREATE POLICY tenant_isolation ON <table> TO beacon_app USING (org_id = NULLIF(current_setting('app.org_id', true), '')::uuid) WITH CHECK (org_id = NULLIF(current_setting('app.org_id', true), '')::uuid); - Every request that touches tenant data runs inside a transaction that first sets the organization id as a transaction-local setting and then switches to
beacon_appwithSET LOCAL ROLE. Both are scoped to the transaction, so a pooled connection carries nothing over to the next request. - If the organization id is unset, the policy expression compares against
NULL, which is never true. A request that somehow skipped the tenant context sees zero rows rather than every row. - The organizations table itself allows the restricted role to read and update only its own row, and never to insert or delete. Platform-level tables are not readable by the restricted role.
- The role the API signs in with is not a superuser and cannot bypass row-level security. The schema owner's connection is used only for migrations and the nightly backup. Platform operations (creating organizations, cross-tenant sign-in lookup by email, the platform console) are reviewed, audited code paths that run under a role allowed to read across organizations for the length of their transaction; reading or writing a district's records never runs as that role. The two device-token paths a signed-in person triggers, registering a push token and removing one at sign-out, run under it so a shared device's token can move between organizations.
- Attachments are private objects in an encrypted object-storage bucket with no public access. The only path to a file is an authenticated download endpoint that resolves the attachment record under RLS and then issues a link that expires within ten minutes.
Automated tests assert that every tenant table has a forced RLS policy and that a cross-tenant read through the tenant context returns nothing.
4. Authentication and authorization
Passwords and sessions
- Passwords are hashed with argon2id at the OWASP 2024 baseline (memory 19 MiB, 2 iterations, parallelism 1). Minimum eight characters. Passwords are never logged.
- A session is a 15-minute signed access token plus a 30-day opaque refresh token. Refresh tokens are stored only as SHA-256 hashes, rotated on every use, and revoked on sign-out, password change, or account disable. Reuse of a rotated refresh token is rejected once a five-minute grace window for lost responses has passed.
- The web app keeps tokens in browser local storage. A short-lived, HttpOnly, Secure cookie protects the single sign-on handshake from tampering.
Single sign-on
- OpenID Connect authorization-code flow with PKCE for Google Workspace, Microsoft Entra ID, Clever, ClassLink, and any generic OIDC provider (Okta, OneLogin, Keycloak, ADFS).
- Administrators can restrict which email domains may sign in and whether users are created automatically on first sign-in, and with which default role.
- Provider client secrets are encrypted at rest with AES-256-GCM using a key held outside the database. Encryption happens on save; decryption happens only at sign-in time; the API never returns the secret.
API keys and webhooks
- API keys are prefixed with
bk_, generated with 40 random characters, shown once, and stored as a SHA-256 hash with a 12-character prefix for display. Keys are scoped read or write, track last use, and can be revoked at any time. - Outbound webhooks are signed: the
x-beacon-signatureheader carries a timestamp and an HMAC-SHA256 of the timestamp and body under the webhook's secret, so receivers can verify authenticity and reject replays.
Roles
Four roles: owner, admin, agent, requester, plus team membership for assignment visibility. Requesters are limited to their own tickets, published public articles, and their own devices. Authorization is checked in every route handler on the server; row-level security is the backstop beneath it. Requesters never receive internal notes or internal events, and API responses never include password hashes, token hashes, key hashes, or secrets.
Platform access
Beacon staff use a separate platform login and credential that has no tenant session of its own. Support impersonation issues an ordinary tenant session and writes an audit entry (platform.impersonate) visible to the organization's administrators.
Abuse protection
- Rate limits: 600 requests per minute per signed-in person, with ceilings per organization and per network address; sign-in 120 per minute per address, single sign-on start 300, token refresh 600, password change 20 per minute per person; five sign-ups per 15 minutes per address.
- Lockout: an email address is locked for a period after 10 failed password attempts in 15 minutes, and a network address after 300 failed sign-ins in 15 minutes.
- Sign-up is protected by a honeypot field and, on top of the rate limit above, a per-address daily ceiling on new organizations, enforced server-side. There is no captcha: school content filters block the scripts captchas load.
5. Data flows
| Flow | Path | Who can see it |
|---|---|---|
| Sign-in | Browser or app → API over TLS → password verification against the hash, or OIDC redirect to your identity provider and back | Beacon (credential hash only); your identity provider |
| Ticket created in the portal, app, or by an agent | Client → API → PostgreSQL under RLS; optional AI triage (section 6); notifications to assignees | Your organization's authorized users; Beacon's infrastructure providers (encrypted) |
| Ticket created by email | Sender → your forwarding address → tickets.beaconhelpdesk.com (Resend) → signed webhook → API → PostgreSQL | Resend sees the message in transit; then as above |
| Ticket created by API | Integration → API with an API key → PostgreSQL | As above |
| Attachment | Client → API (validated, section 8) → private storage under a random key; download via a link that expires within ten minutes | Users with access to the ticket |
| Email notification | API → Resend → recipient; a signed per-ticket reply address threads replies back | Resend sees recipient, subject, and message text |
| Push notification | API → Expo push service → Apple → device | Push token and notification text |
| AI suggestion | API → Anthropic API → result stored with the ticket | Anthropic sees the ticket text and your category, team, and article names |
| Export | Administrator → API → streamed JSON or CSV; not stored; audit entry written | The administrator who requested it |
The marketing website sets no cookies and uses no analytics trackers. The product uses no advertising or analytics trackers.
6. AI usage and data handling
Beacon uses AI for: triage on creation (suggested category, priority, team, duplicates, related articles, with confidence), suggested agent replies, ticket summaries for handoff, knowledge article drafts from resolved tickets, and natural-language reporting questions that are translated into a constrained query language, never raw SQL.
- Provider. Anthropic, under commercial API terms. Anthropic does not use data submitted through its API to train its models. It may retain inputs and outputs for a limited period, currently up to 30 days, for trust and safety, after which they are deleted.
- What is sent. The text of the ticket or question being processed, plus your organization's category names, team names, and knowledge article titles so that suggestions use your real setup. Attachments, passwords, and directory data are never sent.
- What is kept. The suggestion is stored with the ticket so your team can see and audit it, with token counts for metering. Beacon does not store a separate copy of the prompt. Your organization's tickets are used to help your organization only.
- Control. A technician accepts, edits, or ignores every suggestion; AI never closes a ticket or sends a reply. Administrators can turn off triage, suggested replies, and portal deflection independently in Settings. If the model is unavailable or the plan's allowance is used up, everything works manually; no ticket is blocked on AI.
- Structured output. Model responses are parsed against a fixed schema and validated before use, so a malformed or unexpected response is discarded rather than applied.
- Metering. Every AI call is recorded per organization with the feature, model, token counts, and latency, for usage limits and cost analytics.
Crisis screening
Every ticket creation and every public comment is screened, whether AI is on or off. A conservative keyword screen runs inside the same transaction; when AI triage is on, the model is also asked for a safety assessment with explicit guidance to err toward flagging and to ignore IT vocabulary such as "dead battery". A flagged ticket is forced to urgent priority, tagged, and recorded with an internal event hidden from requesters. Every active administrator and owner is notified in-app and by email with a link to the ticket; the notification never includes the message text. The person who submitted it is shown crisis resources, by default the 911 and 988 Suicide & Crisis Lifeline text, which administrators can customize. Automations, AI, and system jobs cannot lower the priority of a flagged ticket; a person can, after review. Beacon is not a crisis service or a substitute for one.
7. Encryption and secrets
- In transit. TLS 1.2 or higher on every public endpoint; HTTP is redirected to HTTPS; HSTS is set for two years including subdomains on both the API and the web app. Database connections stay on a private network. Outbound email uses TLS.
- At rest. Database storage and backups are encrypted. Attachments are stored as private objects in an encrypted object-storage bucket with no public access. Passwords are argon2id hashes; refresh tokens and API keys are SHA-256 hashes; SSO client secrets are AES-256-GCM ciphertext.
- Secrets. Application secrets (database credentials, signing keys, provider API keys) are held in the hosting provider's managed secret store and injected at start. Nothing secret is in the source repository, container images, or CI logs. Tenant secrets (SSO client secrets, webhook secrets) are encrypted in the database.
- Rotation. Signing keys and provider keys can be rotated with a redeploy; rotating the session signing key invalidates every access token, and users are re-issued tokens through refresh.
8. Input, uploads, and output
- Queries. All database access goes through a query builder with parameter placeholders. There is no string-built SQL from user input.
- Validation. Every request body, query string, and path parameter is parsed against a shared schema before it reaches business logic. Field-level rules restrict which roles may change which fields; for example, a requester can edit only their own name, title, phone, and site, and roles are admin-only.
- Uploads. Allow-listed types: PNG, JPEG, GIF, WebP, HEIC, PDF, TXT, CSV, DOCX, XLSX, PPTX, LOG, and ZIP, at most 25 MB. The content type is derived from the file extension, never from the client, and checked against the file's leading bytes for images, PDF, and ZIP-family documents. Text files must be free of control bytes and must not be HTML. SVG, HTML, and executables are rejected. Files are stored under random keys as
<orgId>/<uuid>on a private volume and are never served from a public directory. - Downloads. Images and PDFs are shown inline; everything else is delivered as an attachment. Every download carries
X-Content-Type-Options: nosniffand a sandboxing Content-Security-Policy. - Rendering. User content is escaped by default. Markdown is rendered without raw HTML; links open in a new tab with
rel="noreferrer noopener"and are limited to http(s), mailto, and relative URLs. - Headers. API: HSTS,
X-Frame-Options: DENY, nosniff,Referrer-Policy: no-referrer, Permissions-Policy. Web app: HSTS, nosniff,X-Frame-Options: DENY,Referrer-Policy: strict-origin-when-cross-origin, Permissions-Policy (camera only for the app itself; no microphone or geolocation), and a Content-Security-Policy withframe-ancestors 'none'. Cross-origin requests to the API are limited to the app's origin.
9. Logging and audit
Audit log
Each organization has its own audit log, protected by row-level security like every other tenant table, recording the actor, action, entity, a diff of the change, the source address, and the time. Recorded actions include: SSO configuration changes, role changes, user creation and disabling, API key creation and revocation, webhook and automation changes, organization settings, bulk ticket updates, data exports, deletions, and platform impersonation. Administrators see it in Admin → Audit and through the API. It is retained for the life of the organization. Ticket and asset histories are separate, user-visible timelines.
Application logs
Structured JSON logs carry a request id, user id, organization id, route, status, and latency. Request and response bodies are never logged. Authorization headers, cookies, platform keys, passwords, refresh and access tokens, client secrets, and challenge tokens are redacted at any depth, and download tokens are stripped from logged URLs. Technical logs are retained by the hosting provider for about seven days, never longer than 30.
10. Backups and recovery
- The database is backed up automatically every day, encrypted, with a 14-day retention window.
- Restores are rehearsed so that the procedure is known before it is needed.
- Every application deploy produces an immutable image; rolling back is deploying the previous image. Schema changes follow an expand-and-contract pattern so that the previous application version keeps working against a newer schema, and a code rollback never requires a database rollback.
- Attachment files are written once under unique keys and never overwritten.
- Beacon aims for 99.9% monthly availability measured at the API, excluding announced maintenance. A written service level agreement with service credits for District and Enterprise plans is not yet published (section 16). Measured availability for the last 90 days, for the website, the app and the API, and every incident marked, is published at beaconhelpdesk.com/status.
11. Vulnerability management
- Dependencies are audited before each release against the package manager's advisory database, and the outcome is recorded; there is no automated scanning of dependencies or container images yet.
- Third-party findings: email security@beaconhelpdesk.com. We acknowledge within two business days, triage within five, and aim to fix critical issues within seven days.
- Good-faith research within scope (your own organization, no access to other organizations' data, no denial of service) will not be pursued legally.
12. Incident response
- Severity 1 (data exposure or full outage) is raised by the service's own monitoring, which emails the operator within minutes, and shows on the public status page. A running timeline is kept from the first alert.
- Customer notice. If we learn of a breach affecting personal information, we notify affected customers without undue delay and within 72 hours of confirming it, with the information they need to meet their own notification obligations, or sooner where a customer's agreement or state law requires.
- Post-incident. A written review with timeline, root cause, and action items with owners within five business days.
- Contact. security@beaconhelpdesk.com for anything security-related; a person reads it.
13. Student data: FERPA, COPPA, and state law
Beacon processes directory-type information (names, emails, sites, device assignments) and help desk content that may incidentally contain education records. Beacon is a data processor acting on the school's instructions; the school remains the controller of its data.
- FERPA. Beacon acts as a school official with a legitimate educational interest under the district's direct control, for the limited purpose of providing the service (34 CFR 99.31(a)(1)(i)(B)). Data is used only to provide the service to that district: no advertising, no sale of data, no re-disclosure except as the district directs or the law requires.
- COPPA. Beacon does not knowingly collect information from children under 13 directly. Student accounts, where used, are created by the school under the school-consent model. There is no behavioral advertising and there are no third-party trackers in the portal or the app.
- SOPIPA and similar state laws. No targeted advertising, no profiling for non-educational purposes, no sale of student information, deletion on request, and the security measures described in this document. Beacon signs the Student Data Privacy Consortium National Data Privacy Agreement and state addenda on request.
- AI. No student personal information is used to train any model. Ticket text is processed by Anthropic under terms that forbid training (section 6), and a district can turn AI features off entirely.
- Data processing agreement. A DPA is available on request for any customer; for customers in the EEA, UK, or Switzerland, a data processing addendum with standard contractual clauses.
- Parents and eligible students may review and request correction of student records through their school, which can fulfil the request directly in Beacon.
14. Subprocessors
| Provider | Purpose | Location | What it can see |
|---|---|---|---|
| Fly.io, Inc. | Hosting for the API and the database | United States (Virginia) | All service data at rest and in transit, encrypted |
| Vercel, Inc. | Hosting for the web app and the website | United States | Request logs (IP address, pages requested); the web app stores no customer data on Vercel |
| Anthropic, PBC | AI features (section 6) | United States | Ticket text and organization category and article names when an AI feature runs |
| Resend, Inc. (on Amazon SES) | Sending email notifications; receiving email-to-ticket messages | United States | Addresses, subjects, and message text of email sent and received |
| Cloudflare, Inc. | Domain registration and DNS | United States | DNS queries only |
| Apple Inc. and Google LLC | Mobile app distribution and push notifications | United States | Push tokens and notification text |
| Expo (650 Industries, Inc.) | Mobile app builds, updates, and push delivery | United States | Push tokens and app diagnostic data |
Each provider is bound by contract to use data only to provide its service to Beacon. The list is updated before a new subprocessor is added; District and Enterprise customers receive 30 days' notice by email with the right to object. Beacon does not share data with data brokers.
15. Retention and deletion
| Data | Retained | Deleted by |
|---|---|---|
| Tickets, comments, devices, articles, users | Until your organization deletes them or closes its account | Cascade on delete; an administrator's action |
| Attachments | With the ticket or comment they belong to | The file is deleted after the ticket deletion commits, then the record |
| Users | Until disabled or deleted | Disable immediately; hard delete on request, with tickets re-attributed to an anonymized placeholder to preserve the organization's records |
| Session refresh tokens | 30 days, or until rotation, sign-out, password change, or disable | Expired tokens purged hourly |
| Audit log | Life of the organization | With the organization |
| Technical and security logs | About seven days (the hosting provider's log retention), never more than 30 | Automatic |
| Backups | Rolling, encrypted, 14 days | Automatic; a deleted organization is gone from backups within 30 days |
| AI provider copies | Up to 30 days at the provider | The provider |
| Export bundles | Not stored | Streamed to the requesting administrator |
| Organizations whose deletion is requested | Marked immediately; erased within 30 days | An hourly retention job deletes attachment files, then every row; a deletion certificate is issued on request |
Self-serve deletion: an owner deletes the organization from Settings → Danger Zone by typing its slug. Attachment files are deleted first, then the organization row, and every tenant table cascades, which also revokes every session and API key. After a paid plan is cancelled the organization stays on the free plan with its data intact, and data export remains available for 90 days; deletion happens only on an administrator's request.
16. What is not in place yet
- SOC 2. No SOC 2 report exists. A Type I audit and then a Type II audit are on the roadmap.
- Penetration test. No third-party penetration test report is available yet; one is planned as part of audit readiness.
- Second factor for password accounts. Beacon has no built-in second factor for password sign-in. Single sign-on brings your identity provider's multi-factor policy to Beacon.
- Breached-password checks at sign-up and password change are on the roadmap.
- Data residency. Hosting is United States only. The on-premises edition is the option for customers whose data must stay on their own infrastructure.
- Roster synchronization. Clever is supported for sign-in; synchronizing rosters from it is not yet available. Rosters sync from PowerSchool, read-only, through a plugin the district installs with view-only access to the fields it lists, and students from ClassLink or any OneRoster source, read-only, with the client credentials the district's roster server gives for Beacon (stored encrypted) or from an export the district uploads.
- Point-in-time recovery. On since October 14, 2026: base backups daily and write-ahead logs archived at least every 60 seconds to an encrypted object-storage bucket, kept 7 days, alongside daily snapshots and a nightly dump kept 14 days. The database and its backups are in one region (Virginia).
- High availability. Production runs one API instance and a single database node; since October 14, 2026 a deploy replaces the instance without dropping requests, and a host failure is a restore from backup.
- Second factor for Beacon staff. The platform console signs in with a password only.
- A written service level agreement. The terms state a 99.9% monthly availability target; the service level agreement with service credits for District and Enterprise plans has not been written yet.
- Accessibility conformance report. No audit has been run and no VPAT is available.
- SAML. Sign-in federation is OpenID Connect only.
17. Contact
Security questions and reports: security@beaconhelpdesk.com. Privacy requests: privacy@beaconhelpdesk.com. Anything else: hello@beaconhelpdesk.com.
SYV Technologies LLC
Saint Charles, Illinois, United States
Related documents: Privacy Policy · Terms of Service · Security overview.