Last updated: September 5, 2026

1. The data is more sensitive than an inventory app sounds

Worth saying before you find it: for each site, ChemLevel holds the plant name and address, every chemical held and how much of it, chlorine cylinder counts and weights, current levels and usage history, confirmed delivery dates, delivery days and site hours, supplier contacts, and operator names.

Taken together — how much chlorine gas sits at a named, addressed plant and when the next truck arrives — that is the class of information covered by risk-and-resilience assessments under AWIA §2013, and exempt from public-records disclosure in many states precisely because it assists target selection.

Aggregating it is what the product is for; a forecast cannot be produced without it. The point is that it should be reviewed as operational security information rather than as ordinary business software data, and that your own classification and retention rules should be applied to it.

2. What is in place

Tenant isolation. Row-level security is enabled on every table without exception. Access is decided in the database rather than in the application, so a client-side mistake cannot expose another organization’s rows. Privileged operations run through procedures that assert membership of the site or organization before doing anything.

Multi-factor authentication (MFA). Available to every user through an authenticator app (TOTP), and presented in the app as “two-factor.” Sign-in asks for a code in addition to the password. Enrollment is per person and voluntary: there are no recovery codes, so a lost device requires an administrator at your own organization to clear the factor, and users are told this before they turn it on.

Passwords and account changes. Minimum twelve characters, checked in the application while typing and enforced again by the authentication service — length rather than composition rules, following NIST guidance. Changing an email address requires confirmation at both the old and new address. Changing a password requires the current password and a recent sign-in. Email one-time codes are eight digits and expire after ten minutes. New passwords are also checked against known-breached credential lists and refused if they appear in one, so a password already exposed in someone else’s data breach cannot be reused here.

Access from outside the United States. Both the application and this website refuse connections from IP addresses outside the US. Every customer and every operator is US-based, so this removes a large share of opportunistic scanning and credential-stuffing traffic before it reaches a login form at all. It is defense in depth rather than a boundary — anyone determined can route through a US address — so it sits alongside the controls above rather than in place of any of them. The restriction covers this page too, so a reviewer outside the US will not be able to reach it and should ask us for it directly. Staff who need access while traveling should contact us before they go — a corporate VPN that routes outside the country has the same effect as being abroad.

Automated abuse. Creating an account, signing in and requesting a password reset each require a Cloudflare Turnstile check, and the part that matters is where it is enforced: the authentication service verifies it, not this application. A script that posts straight to the authentication API without ever loading our code is refused before a password is examined at all — a check the app performed on its own would have inconvenienced only the people who were never the problem. In normal use an operator sees nothing: the challenge stays invisible unless the request looks automated, and appears as a single checkbox when it does. Account creation additionally requires a confirmed email address before an organization can exist at all, so an address nobody controls cannot become a tenant. The contact form on this website carries a separate trap field that a person cannot see, focus, or reach by keyboard and that a script fills in; anything that fills it is discarded.

Audit trail. Inserts, updates and deletes are recorded with the acting user, a timestamp, and the before-and-after values, scoped to your organization and readable only by your own members.

Role permissions. Authority is split along two independent lines, because in a utility they are usually two different people. Supervisors hold plant authority: chemicals, tanks, cylinder racks, reorder thresholds and Safety Data Sheets. Administrators hold account authority: invitations and removals, roles, who may see budgets, billing, and clearing a member’s multi-factor enrollment. Operators log readings, usage and maintenance.

The two are deliberately not a ladder. An administrator is not senior to a supervisor and holds no rights over a chemical — which is what lets a municipality give account control to its IT department without also giving it the chlorine rack. Either may be held without the other, and one person may hold both; in a single-plant organization that is the normal case and the default. Which plants a person can reach is restricted separately again — see below. Cost and budget figures are gated separately again, per person, and the data export honors the same gate rather than routing around it.

Site access. A third restriction, independent of both roles above: a member can be limited to particular plants. Someone scoped to one plant does not see the others at all — not their chemicals or readings, and not their names and addresses either, which for a multi-plant utility are part of the same operational-security picture as the inventory itself. By default nobody is scoped, so a single-plant organization never encounters this.

It applies to administrators as well, without exception. An administrator scoped to one plant still runs the whole account — invitations, roles, billing — but reads only their own plant's data and does not see the other plants at all, exactly like anybody else. Account authority is deliberately not a key to the plants. The consequence is accepted rather than worked around: an administrator restricted to one plant can only assign people to plants they can themselves reach. Creating a site is administrator-only, since adding one changes what the organization is billed, and renaming a site is restricted to sites that person can already reach.

No one may change their own role, their own account access, or their own site access, and neither the last administrator nor the last supervisor can be removed — an organization cannot lock itself out. All three are writable only through procedures that enforce those rules; the underlying columns are not writable directly, so the checks cannot be bypassed by a client. Site access is enforced in the same row-level security described above, so it applies to every route into the data rather than to the screens alone.

Supplier email. Purchase requests, where an operator chooses to send one, open as a pre-filled message in the operator’s own mail client; an order can equally be logged without emailing anyone. The order, the PO number and the delivery address travel from your plant to your supplier directly — they are never sent by, stored on, or routed through ChemLevel servers.

Order confirmations are read, not kept. Lab orders can be added by pasting a vendor’s confirmation or choosing the PDF they sent. The document is parsed on the device and discarded: the catalog number, quantity and price are written down, and nothing else is. There is no upload, no storage bucket and no server-side processing in that path, so there is no copy to delete and none in a backup — the guarantee holds because a copy is never made rather than because one is removed. This matters more than it may sound: a confirmation is a purchasing document carrying addresses, contact names, account numbers and terms that an inventory system has no use for.

Crash reporting. Deliberately narrow. Personally identifying data is off; console output and user-interaction breadcrumbs are removed before sending; request bodies and headers are dropped; the user is reduced to an opaque identifier and URLs are stripped of query strings.

Data portability. Any authorized user can export the organization’s complete records — sites, chemicals, tanks and racks, every reading, usage log, order and maintenance issue — as one file, stamped with who exported it and when. Intended for retention schedules, records requests, and leaving.

3. What it does not do yet

A security summary listing only strengths is not worth reading. These are the gaps a reviewer would find, stated plainly.

No independent audit. There is no SOC 2 report and no third-party penetration test. The practices described here are ours, not an auditor’s. If your procurement process requires attestation, ChemLevel does not currently meet it, and we would rather say so than let the question hang.

Vendor concentration. ChemLevel is a small operation. There is no escrow arrangement or continuity commitment in place. The mitigation available today is the export above: your records can be retrieved in full at any time without our involvement.

Forecasts are advisory. ChemLevel projects when to reorder. It is not a control system, it is not a compliance system of record, and it does not actuate anything. Operator judgment stays in the loop, and regulatory records should continue to be kept as your state requires.

4. Where it runs and who can reach it

Hosting region. The database is in AWS us-east-1, Northern Virginia. The application is served from Cleveland, Ohio (cle1). Both are within the United States, so a US-residency requirement is met without an exception.

Encryption. Encrypted at rest, and TLS on every connection. Outbound email — password resets, invitations, billing notices — requires TLS rather than negotiating it opportunistically, so a message carrying a one-time sign-in link is never handed to a receiving server in plain text. The trade-off is deliberate: a recipient whose mail server cannot negotiate TLS gets a delivery failure we can see rather than a silent downgrade we cannot.

Backups. Daily, retained for seven days.

Production access. Administrative access to the production database is limited to named personnel, protected by multi-factor authentication, and logged by the hosting provider. Row-level security separates your organization from other tenants; it does not separate it from that access, which is why it is held by as few people as possible. We will name them on request.

Retention after closure. An organization whose subscription lapses or is canceled enters a thirty-day grace period, during which its records remain intact and recoverable by resubscribing. After that a nightly job permanently deletes the organization and everything belonging to it. The grace period exists so that a lapsed card cannot cost a utility its records; export before it ends and nothing is lost either way. Individual user accounts are removed immediately on request.

5. Services we rely on

Supabase — managed PostgreSQL, authentication, and file storage. Holds the operational data described above.

Vercel — serves the web application. Does not hold plant data.

Sentry — crash and error diagnostics, scoped as described above.

Resend — account and billing email only. Not supplier orders.

Stripe — subscription billing. Card details are handled by Stripe and never reach ChemLevel.

Cloudflare — the Turnstile bot check on the sign-in, account creation and password-reset screens. It receives the technical signals needed to tell a person from a script, and no plant or account data.

Formspree — delivery of the contact form on this website. Not connected to the application and holds no plant data.

6. Reporting something

Security questions, suspected vulnerabilities, and incident reports go to security@chemlevel.com, acknowledged within one business day. A telephone contact for urgent matters is provided to customers on request.

Affected utilities are notified within 24 hours of an incident involving their data being confirmed, by email to the organization’s administrators and by telephone where a number is on file. The notice states what happened, what data was involved, when it occurred and was discovered, what has been done, and what the utility should do; a written follow-up goes out once the cause is established.

That 24-hour window is set deliberately inside the 72 hours a water system has to report a substantial cyber incident to CISA under CIRCIA. A vendor slower than its customer’s own reporting clock makes that obligation impossible to meet.

A fuller brief, including the specific detail behind each answer above, is available to utilities evaluating ChemLevel — ask at security@chemlevel.com.