Security at RosterSafe
Effective: August 25, 2026
RosterSafe holds Social Security Numbers, DEA registration numbers, and the credentialing record for every provider on your book. This page describes how that is protected, and is specific enough that you can hold us to it.
What we have not done
Starting here, because a security page that only lists strengths is not worth reading.
- We are not SOC 2 certified. No Type I, no Type II. If your compliance program requires one, we do not clear that bar today.
- We do not sign Business Associate Agreements, because whether credentialing data makes us a HIPAA business associate at all is unsettled and we will not claim a status we have not established.
- We have not had an external penetration test.
- RosterSafe is early. It is a small product from a small team, and it does not have the compliance apparatus of a company with a hundred engineers.
Everything below this box is built and running. Everything in this box is not. We will move items out of it as they change, and we will not blur the line in the meantime.
Tenant isolation is enforced by the database
The most serious failure a multi-tenant product can have is showing one customer another customer's data. In most applications the only thing standing between those two outcomes is whether every query remembered to filter correctly. That is a promise about code review, not a guarantee.
RosterSafe pushes the boundary down into Postgres:
- Every firm-scoped table has row-level security enabled and forced, with a policy keyed on the firm making the request.
- The application connects as a role that cannot bypass row-level security and owns no tables. A table owner is exempt from its own policies, so the application is deliberately not the owner.
- The firm identity is set per request inside a transaction, so it cannot leak onto the next request that happens to reuse the same pooled connection.
- A query naming no firm returns nothing. An insert stamped with a different firm is rejected, not silently hidden.
- There is a second axis inside each firm. A read-only client login is pinned to one client practice, and that pin is derived from the role on the server rather than accepted from the request.
- A build-time check enumerates every file permitted to hold a privilege-escalating database handle, with a written justification for each. An unlisted one fails the build.
Sensitive fields are encrypted before they reach the database
- Social Security Numbers, DEA registration numbers, and two-factor secrets are encrypted with AES-256-GCM at the application layer. The database never sees the plaintext.
- They are excluded from API responses, logs, and exports by default. A deliberate reveal action is the only path to reading one.
- Every reveal writes an audit event recording who did it and when. It is visible to you in your own activity trail.
- A build-time check fails the build if a query outside the enumerated reveal paths so much as names one of those columns.
- All traffic is TLS encrypted in transit, with HSTS set for two years.
Authentication and sessions
- The access token is a gate carrying a single claim, the session identifier. Every authorization fact (your role, firm, plan, and account status) is read from the database on every request rather than trusted from a token. A permission change therefore takes effect on the next request, not whenever a token happens to expire.
- Access tokens last 5 minutes. Refresh tokens last 7 days, or 30 if you chose to stay signed in. Both are
httpOnly, so JavaScript cannot read them. - The refresh token is opaque and only its SHA-256 hash is stored. Refreshing rotates it, and replaying a rotated token revokes the entire session family, which is what turns a stolen token into a detected intrusion.
- Revocation is a column read by the same lookup that authorizes, so there is no separate blocklist that can fall out of sync.
- Authentication fails closed. An invalid session is rejected, an unreachable database is an error, and the second never degrades into being treated as the first.
- Optional two-factor authentication, with the secret encrypted at rest.
- Passwords are hashed, never stored or logged in any recoverable form.
Storage, backups, and availability
- Postgres, hosted on Supabase, with encryption at rest.
- Documents are stored in Cloudflare R2, reachable only through time-limited signed URLs rather than public links.
- A nightly encrypted backup of the whole database to separate object storage. Every night's copy is kept for a week, and one copy a week is kept for a month.
- Restores are actually tested rather than assumed. A verification routine performs a real backup and restore against a scratch database, because an untested backup is a hope.
- An orphan reconcile job keeps stored documents and database records in agreement, so a deleted record does not leave its file behind.
Application security
- A strict Content Security Policy, plus
X-Frame-Options: DENY,X-Content-Type-Options: nosniff, a restrictive Permissions-Policy, and HSTS. - Rate limiting on authentication and other sensitive endpoints.
- Input sanitisation and schema validation on every request body, with shared schemas so the client and server cannot disagree about what is valid.
- Role-based access control checked on the server for every request. A read-only client is restricted to GET across the entire router, not per handler.
- An activity trail recording significant actions inside your firm, visible to you.
- Payments run through Paddle as Merchant of Record. Card details never touch our servers.
Reporting a vulnerability
Email [email protected]. We will acknowledge within two business days and keep you updated.
We will not pursue legal action against anyone who reports a genuine issue in good faith, gives us reasonable time to fix it before disclosing, and does not access, modify, or destroy data belonging to anyone else while investigating. We do not currently pay bounties.
Questions we get asked
- Is RosterSafe SOC 2 certified?
- No. We have not completed a SOC 2 Type II audit and we are not going to imply otherwise. If your procurement process requires a current SOC 2 report before you can sign, we do not meet that bar today. Tell us before you sign up rather than after, so you do not waste your time.
- Will you sign a Business Associate Agreement?
- Not currently. RosterSafe holds credentialing data about clinicians, which is provider information rather than patient health information, and whether that makes us a HIPAA business associate is genuinely unsettled. We would rather tell you that than sign something we have not properly established we can stand behind.
- Can another firm see my data?
- No, and the guarantee is enforced by the database rather than by application code. Every firm-scoped table has row-level security enabled and forced, and the application connects as a role that is not permitted to bypass it. A query that does not name a firm returns nothing, and an insert stamped with a different firm is rejected outright rather than silently hidden.
- What happens to my data if I cancel?
- You can export your roster and records before you go. After you delete your firm, data is removed from live systems promptly, though it can persist in an encrypted backup until that backup ages out of the retention window. We do not keep your data to hold it hostage.
- How do I report a vulnerability?
- Email [email protected] with details and we will acknowledge within two business days. We will not pursue legal action against anyone who reports a genuine issue in good faith, gives us reasonable time to fix it, and does not access or destroy other people data in the process.
Contact
Security questions to [email protected]. See also the Privacy Policy, the Cookie Policy, and the Terms of Service. If you are evaluating RosterSafe, the pricing page has no sales gate either.