This page covers the PartScheduler app, at app.partscheduler.com, where a shop’s jobs, customers and drawings live. It says what protects them today and, just as plainly, what is not in place.
The website, partscheduler.com, is separate and holds none of your shop’s data; its one form is the waiting list. Resend, the service we use for email, keeps the sign-ups, and a notice of each one comes to our support mailbox. Privacy covers what that form collects.
The short version
The database itself keeps every shop’s records apart, on every table. You sign in with an email and a password; our sign-in provider checks the password and stores it hashed, and the app’s own tables hold no passwords. Files sit in private storage and open through links that expire in five minutes. Supabase, our database provider, stores the database and the files in the United States and backs up the database daily, keeping each backup for 7 days, but uploaded files are not in those backups. We hold no security certification and have had no independent audit. Each section below says where it falls short, and a list near the end gathers the main gaps.
Where your data lives
The app runs on Vercel, and its server code runs in Vercel’s US East region. Supabase stores the database and uploaded files in the United States, in Amazon Web Services’ us-east-1 region.
Supabase also encrypts the database and the files at rest. That is Supabase’s own control, described in their security documentation, not one we run ourselves.
Several other services help run the app, such as the one that sends its email. Privacy lists each one and what it receives. We have not confirmed where each of them keeps data, so we do not claim that everything stays in the United States.
Keeping shops apart
Every shop’s records sit in one database, and the database itself keeps them apart, rather than leaving that to the screens alone:
- Every business record, such as a job, a part, a customer or a file, carries the ID of exactly one shop.
- Every table has row-level security switched on and enforced, so one shop’s account cannot read or change another shop’s rows.
- Our server decides which shop you see, from your account’s membership. Nothing your browser sends can change it, and each login belongs to exactly one shop.
- The database’s access level for anyone who is not signed in can read no table and run no database function.
- Your browser never talks to the database directly; every database read and write goes through our server. Files are the one exception: they travel straight between your browser and the storage service, through expiring links our server creates for one file at a time, after checking your shop.
Automated database tests of these rules, including tests that try to read one shop’s records from another, run on every change pushed to the app’s code. As How we build explains, they flag problems but do not hold a change back.
Signing in
You sign in with an email address and a password. That is the only way in. Your password passes through our server to Supabase Auth, our sign-in provider, which checks it and stores it hashed. The app’s own tables have no column for a password, and our code does not store one. Any password set inside the app must be at least 12 characters.
Once you are in, the app keeps your sign-in in one cookie. Page scripts cannot read it (HttpOnly), it travels only over HTTPS (Secure), and browsers hold it back from most requests that start on other websites (SameSite=Lax). The app signs it with a secret key that only our server code uses, so nobody can alter it without the app noticing. The cookie is not encrypted, though: anyone holding it can read what is inside, which is an account ID, a sign-in ID, a version number and timestamps, plus the login type for a station. It never holds your password.
- A person
- Signed out after no more than 12 hours without use, and after 7 days at most, however active.
- A shop-floor station
- Signed out after no more than 30 days without use, and after 90 days at most.
Our server checks the session again on every request, so a suspended or removed login stops working on its next request. A file link already handed out keeps working until it expires, at most five minutes later.
Signing out cancels that sign-in on our servers as well as in your browser, so a copy of the cookie stops working too. It ends only the sign-in you are using. There is no list of your signed-in devices and no way to sign out one device from another. Changing your password asks for your current one and signs out all your other devices. One limit: a separate service keeps the list of signed-out sessions, and if that service is down, a copied cookie from a signed-out session can keep working until it expires.
You reset a forgotten password through a one-time link sent by email, and finishing the reset signs the account out everywhere.
Our server limits sign-in attempts per network address and caps failed sign-ins across the whole service; it limits password-reset requests too. The sign-in and reset screens give the same answer whether or not an email address has an account.
Roles and sensitive changes
Everyone in a shop has one of five roles: owner, admin, scheduler, operator or viewer. The database enforces who may change what, and our server checks again before any change runs. A viewer cannot change any of the shop’s records. Roles limit what a person can change, not what they can see: everyone in a shop can see its jobs and boards.
Some changes make the owner or an admin type their own password again first: inviting someone, sending a PIN link, and creating a shop-floor station or setting its password. Only the owner can change a person’s role, and that asks for the owner’s password too.
Nobody can create an account on their own today. Logins come from us when a shop starts, or from an owner or admin inviting someone or setting up a shop-floor station. An invitation or PIN link carries a long random secret, and we keep only a one-way hash of it. Each link works once, can be withdrawn, and expires.
Shop-floor stations and PINs
A shared computer on the floor signs in as a station: a login of its own, which only an owner or admin can create. A station can never hold admin powers, and nobody can reset its password by email. If a station tablet goes missing, an owner or admin can change the station’s password, which signs it out everywhere.
At a station, a worker can enter their own 4-digit PIN, and some actions require one, so the job history shows who did the work rather than only which station. The app stores a PIN only as a one-way hash that it never reads back. Ten wrong PINs in 15 minutes pause the PIN prompt for every screen on that station login.
A PIN is not a sign-in: it can only narrow what a station may do, never widen it.
One gap to know about: suspending a person’s login does not stop their PIN working at stations. To stop the PIN, an owner or admin has to archive that person.
Files and drawings
Prints, CAD files, photos and purchase orders go into private storage. Each file’s storage path ties the file to its shop, and the storage rules allow access only to that shop.
A file opens through a download link that expires after five minutes. Our server creates the link only after checking that you belong to the file’s shop.
The app caps uploads at 100 MB a file and limits them to a fixed list of file types, judging each by the file’s name and the type your browser declares for it. The storage service checks the declared type again, but nothing looks inside the file. Only PDFs and common image types open in the browser; everything else downloads as a file. Through the app, nobody can change or erase a print, model or other file on a job or part; removing one archives it. A machine’s photo is the exception: replacing or removing it erases the old one.
Your own browser makes the CAD previews and runs the 3D viewer, with an engine served from our site, and your CAD files do not go to any outside conversion service.
In transit
The app is served only over HTTPS, so what passes between your browser and the app travels encrypted. A plain-HTTP request gets a redirect to HTTPS, and the app tells browsers to use nothing but HTTPS for it, a setting they keep for two years (HSTS).
What the app tells browsers
Every response from the app carries these instructions:
- No framing (X-Frame-Options)
- No other website can show the app inside a frame of its own, which blocks pages that try to trick you into clicking inside it unseen.
- No type guessing (X-Content-Type-Options)
- The browser treats each response from the app as the type the app declares for it, instead of guessing at it.
- Our domain only (Referrer-Policy)
- When you follow a link out of the app, the other site learns only our domain, not the page you were on, whose address can carry job and customer numbers.
- Device access off (Permissions-Policy)
- The app switches off camera, microphone, location, payment and USB access, so nothing running in it can ask for them.
Our server refuses a request that changes data when a browser sends it from another website.
Logs and error reports
A database error message can contain the values you typed. Our code removes those values before writing an error to our server logs or sending it to error tracking, and keeps them out of what it sends to your browser. Automated tests catch the usual ways of getting this wrong, but removing those values is a rule our code follows, not a hard barrier, so a bug could still let a value through. We have already found and closed one such gap.
The app reports errors to Sentry, an error-tracking service. Before sending a report, it strips cookies, sign-in headers, tokens in links, search text, database values and the text of what you clicked, and either drops what a request submitted or blanks out its sensitive fields. We set reports to leave out IP addresses, but reports from your browser go straight to Sentry, so Sentry sees the network address they come from, as any site your browser contacts does. Sentry’s screen recording (Session Replay) is off. A report still carries details of your browser and the address of the page, which can include internal record numbers. About one page load in ten also sends timing data.
The security log
The app keeps a log of account events: sign-ins and sign-outs, password changes and resets, invitations, role changes, and station and PIN changes. Each entry records when it happened, the IP address and the browser, but never passwords or tokens.
Nobody can edit or delete an entry through the app. Each person can see their own 20 most recent events on their account page. No screen shows the whole shop’s log, and the app has no way to export it. An owner can ask us for a copy.
The log leaves out failed sign-in attempts, and the app writes entries on a best-effort basis, so one can occasionally be missing.
Who at PartScheduler can see your data
PartScheduler staff look at a shop’s data only to give support, fix a problem, keep the service running, or when the shop asks us to.
For that work we can use administrator access to the database, which is not bound by the shop-by-shop rules above. That access is not yet recorded in your shop’s own security log, and nothing in the app lets you grant, limit or review it.
Backups and recovery
Supabase backs up the database every day and keeps each backup for 7 days; restoring one would lose everything entered after that backup, up to 24 hours of work. When a shop’s data is deleted, its copies in those backups age out within 7 days.
Those backups cover the database only. Supabase’s own documentation says they do not include uploaded files, and we keep no backup of those files ourselves. Keep your own copies of any prints and models you cannot do without.
We keep no backup of our own outside Supabase, and we have never rehearsed restoring from a backup.
Monitoring
Outside monitors check around the clock that the app and its sign-in pages are responding, but they would not catch an outage at our sign-in provider alone. There is no public status page and no uptime commitment.
How we build
We keep secret keys out of your browser: the app uses them only in its server code, and we also use them in our own administration scripts. Your browser receives a short, fixed list of settings that are not secret, and an automated test flags any addition to that list.
An automated scan checks every push to the app’s code, across its full history, for passwords or keys committed by mistake.
These checks, and the database tests above, flag problems but do not hold a change back. A change goes live when we push it, without waiting for the checks to finish or pass, and no second person has to review it first.
Our development and demo copy of the app runs on a separate database filled with invented companies and jobs, and the script that fills it refuses to run against production. Everything this site shows of the product uses invented data, never a real shop’s.
What is not in place
- Certification and outside review. No SOC 2 report or any other security certification. No independent penetration test or security audit; the reviews done so far were our own.
- Signing in. No multi-factor sign-in, such as a code from an authenticator app, and no check of passwords against lists of breached passwords. No list of signed-in devices, and no way to sign out one device from another.
- In the browser. No Content Security Policy, the browser instruction that limits what code a page may load.
- Backups. No backup outside our database provider, and no point-in-time recovery, which would allow restoring the database to any chosen moment instead of the last daily backup. No backup of uploaded files, and no rehearsed restore from a backup.
- Uploaded files. No malware scanning, and nothing inspects what is inside a file.
- How we work. No automated gate or required second review before a change goes live, and no written incident-response plan. Staff access to a shop’s data is not recorded in that shop’s security log.
- Export control. Not designed or certified for ITAR (the International Traffic in Arms Regulations) or CMMC (the Cybersecurity Maturity Model Certification). Do not upload export-controlled technical data; the Terms say exactly what that covers.
If one of these matters to your shop, ask us about it before you rely on PartScheduler.
What your shop can do
Some protections are in your hands, and with no multi-factor sign-in they matter more:
- Give each person a password they use nowhere else. The app does not check passwords against lists of breached ones.
- When someone leaves, archive them rather than only suspending their login, so their station PIN stops working too.
- If a station tablet goes missing, change that station’s password, which signs it out everywhere.
- A station stays signed in for up to 30 days without use, so keep station computers where only your own people can reach them.
- On a computer other people use, sign out when you finish.
Reporting a problem
If you think you have found a security problem, use the Get in touch button below and tell us what you saw. Questions about anything on this page go the same way.
If we learn that a shop’s data has been exposed, we tell that shop’s owner promptly and say what we know.
We checked this page on 2 October 2026 against the app’s code, its own operating records and read-only requests to the live app.