Security
Protecting your load data
is our top priority
Tracking touches customer names, lane rates, carrier relationships and driver phone numbers. This page is what we do about that, written so your IT team can check it rather than take it on trust.
- Hosting
- AWS, us-east-2
- Encryption at rest
- AES-256; database under a customer-managed key
- Encryption in transit
- TLS 1.2 / 1.3, HTTPS-only (HSTS)
- Sign-in
- Two-factor, plus Google / Microsoft SSO
- Tenant isolation
- Scoped on every query
- Database backups
- 30 days, point-in-time
Your data at rest
Encrypted everywhere it is stored, under keys whose policy we set.
AES-256 on the database, under our own key
The Aurora PostgreSQL cluster is encrypted with a customer-managed AWS KMS key rather than the AWS default, so key policy and rotation are ours to set.
Every object store is encrypted
PODs, load documents, message attachments, driver images and exported reports are written to S3 encrypted with AES-256 under AWS-managed keys. Public access is blocked on every bucket and again across the whole AWS account, so no bucket can be made public by mistake. Documents and attachments open only through short-lived signed links, issued after checking that the person asking belongs to the company that owns the file.
Thirty days of point-in-time recovery
Automated backups run continuously and are retained for 30 days in production, so the database can be restored to any moment inside that window. We test that: on 21 October 2026 the production database was restored from backup in 16 minutes and every integrity check passed, and the drill repeats every October. Deletion protection is on, so the cluster cannot be dropped by an errant apply.
No credentials in the code or the image
Every API key, database URL and third-party token comes from AWS Secrets Manager and is injected at task start. None is baked into a container image or kept in the source code.
Your data in motion
Nothing crosses a network in plaintext, and the parts that hold data are not on the internet.
TLS 1.2 or better, no exceptions
The load balancer and our content network accept TLS 1.2 and 1.3 only. Plain HTTP is answered with a redirect, never with content, and browsers are told to use HTTPS for every later visit (HSTS). Inside the network, every cache requires TLS and a password too.
The database has no public address
Aurora, the caches and every worker sit in private subnets with no route in from the internet. Traffic to AWS services leaves through VPC endpoints rather than the open network, and the one egress path is a managed NAT gateway.
Cloudflare in front of the app
Production traffic reaches the application through Cloudflare, which absorbs volumetric attacks before they reach anything we run.
Who can see what
Isolation and least privilege, enforced in the query rather than in the interface.
Every query is scoped to your company
Multi-tenancy is a filter on the data access itself, not a screen that hides rows, and automated tests check that isolation on every change. Every action that names a record (a TMS update, a message to a driver, a retry, a change to a user) first checks that the record belongs to your company, and refuses it otherwise.
Roles, and a portal that stays a portal
Every user has a role (Admin, Tracking User, Internal User or Customer User), and each sees and does different things. A customer (shipper) portal login can reach only the customer portal; every other page is closed to it. A demo login is blocked from writing at the request layer, so a walkthrough cannot change your data even by accident. Every user accepts the current Terms of Use before using TrackFlo, and the version they accepted is recorded.
Two-factor sign-in
Every user can turn on two-factor sign-in with an authenticator app, and a company can require it for the roles it chooses. It is always required for TrackFlo's own Super Admins.
Sign in with Google or Microsoft
A company can require sign-in through its own Google Workspace or Microsoft Entra ID for the roles it chooses, so its own MFA and conditional-access rules apply. Someone removed from your directory can no longer sign in to TrackFlo.
Accounts are activated from the invitee's own inbox
Knowing someone's email address is not enough to claim their invitation. A new user sets their password only after opening a one-time link sent to the invited address, so the account belongs to whoever controls that inbox.
Passwords are never stored
Only a salted hash is kept, and it is compared rather than decrypted. New passwords must be at least twelve characters and are checked against known breached passwords, and repeated wrong guesses pause password sign-in on that account for up to fifteen minutes.
Sessions live on the server, and end
Sessions are stored server-side and end sixteen hours after sign-in however active the user is; deactivating a user or a company ends their sessions straight away. The cookie is HttpOnly, Secure and SameSite, so it is never sent unencrypted, cannot be read by scripts, and is not sent along with requests from other sites.
The application itself
Text, webhooks and API calls from outside are treated as untrusted until they prove otherwise.
Outside text is shown as text
Every place that shows text from a TMS, a driver, an email or the AI escapes it first, so a note cannot run as code in a tracker's browser. A test fails the build if a new screen doesn't.
Every webhook proves where it came from
SMS, WhatsApp, AI voice, inbound email and Slack all reach us by webhook, and every one must carry its provider's signature or a shared secret. Anything without it is refused.
API keys that are scoped, hashed and expire
Every API key is bound to one company and one purpose, and is stored only as a SHA-256 hash, so the database holds nothing usable if it is ever read. Every key expires (one year at most), and API keys carry a rate limit.
Browser security headers
The app sends HSTS, X-Frame-Options, X-Content-Type-Options and Referrer-Policy headers. A Content Security Policy is being rolled out and is in monitoring mode today.
AI and your data
Pre-trained models used through their APIs, with a person in charge of what reaches your TMS.
Never trained on your data
TrackFlo uses third-party, pre-trained models through their APIs: OpenAI for reading messages and PODs, and Vapi for AI voice calls. We never train or fine-tune a model on customer data.
A signed DPA with OpenAI
TrackFlo has a signed Data Processing Agreement with OpenAI. Its data-sharing settings are off and our requests are not stored for reuse, though OpenAI may keep API data for up to 30 days for abuse monitoring.
A person approves by default
AI-extracted updates go to a person for review unless you opt a type of update into automatic approval, above a confidence threshold you choose. Stop updates, and anything that conflicts with existing data, always need a person. Auto-approval, AI scanning of PODs, each outreach rule and AI voice calls can each be turned off.
Every AI update can be traced
Each AI-derived update records the message it came from, its confidence, who or what approved it, and what was written to your TMS.
The model reads; it does not act
Model output must fit a fixed schema before it is used, the model cannot take actions on its own, and it only ever sees the one message and load it is working on. Driver and carrier text is kept out of the model's instructions, in marked blocks it is told to treat as data, never as instructions. A quote can become a TMS note only if it really appears in the message, tracking links must be http(s), and prompt-injection tests run on every change.
How we run it
The people and services that operate the platform get the access the job needs, and no more.
Three people, single sign-on, MFA every time
Three people can reach production. Staff reach AWS only through single sign-on with MFA at every sign-in, and no person has an IAM user or a personal access key. Organization guardrails stop anyone creating IAM users or turning off audit logging and threat detection, and access is reviewed quarterly.
No SSH into production
The one administrative host has no open inbound port at all. Engineers reach it through AWS Systems Manager, which authenticates every session against our AWS identities and logs it, and the host itself holds no application secrets and no administrative rights.
No root access to production
The production accounts have no root password and no root keys at all. The rare task that genuinely needs root is a brief, logged session issued centrally, not a credential anyone holds.
Every service gets only what it uses
Each part of the platform runs with its own narrowly scoped AWS role. The application can read and write documents but has no permission to delete them, and an integration's only storage permission is adding a POD.
Checked before it ships
GitHub requires two-factor for every member of our organization. Every production release passes about 5,950 automated tests and a dependency vulnerability audit, secret scanning and static analysis run on every pull request into production, and deploys use short-lived credentials.
A security review every month
On the 1st of every month an automated review checks the code and the AWS configuration against the OWASP Top 10 and AWS best practices. Findings carry fix-time targets: 7 days for Critical, 30 for High, 90 for Medium.
How we know
Detection that runs whether or not anyone is looking at it.
Continuous threat detection
GuardDuty watches account, network, workload and storage activity, AWS Config records every configuration change, IAM Access Analyzer checks for access granted outside the account, and Security Hub brings the findings together.
A complete audit trail
CloudTrail records every AWS API call, searchable for 365 days with an archived copy besides, so who changed what and when is an answerable question a year later. Network flow logs are kept for 90 days, load balancer logs for 30 and application logs for 365.
Dependencies and images kept current
Dependabot proposes dependency and base-image updates every week, and Amazon Inspector continuously scans the container images we run, so a vulnerability disclosed after a deploy still raises an alert.
Alerts go to people, not a dashboard
About thirty alarms (a root sign-in, a policy change, logging being turned off, database health and others) email the team as they fire. An integration that stops responding raises a failure the same way rather than going quiet.
Policies and retention
What is written down, and how long your data is kept.
Written down, and shared on request
A written Security Program, reviewed every October, and an Incident Response and Continuity Plan that commits to telling affected customers within 72 hours of confirming an incident that affects their data. Both, and an architecture and data-flow document with a diagram, are shared with security reviewers on request.
How long we keep it
Load update history is kept for 12 months. Load documents (PODs, BOLs, photos) and our copy of AI call recordings are kept for 365 days, temporary message attachments for 7 days, and database backups for 30 days.
Deleted when you leave
At contract end, on written request, we delete your data within 30 days and confirm it in writing. Backups age out within the following 30 days.
Sub-processors
The third parties that process customer data on our behalf, what each one does, and where.
Amazon Web Services
Hosting, database, file storage, geocoding and routing
US (us-east-2)
Cloudflare
DNS; proxies web traffic to the app
Global edge
Twilio
SMS, WhatsApp and phone lines for voice calls
US
Twilio SendGrid
Sending and receiving email
US
OpenAI
Classifying messages, extracting tracking data, identifying POD pages
US / global
Vapi (with OpenAI, Deepgram, Cloudflare)
AI voice calls to drivers
US / EU
Ferndesk
In-app help center and support chat
Vendor cloud
Attio
Customer-contact records for product-update emails
Google Cloud
Loops
Product-update emails
Vendor cloud
- Only if you turn them on: Google or Microsoft (single sign-on), Slack, and your own TMS and visibility providers.
- Analytics (Superset) is self-hosted inside TrackFlo's AWS account, so it is not a sub-processor.
- We tell customers at least 30 days before a new sub-processor receives their data.
Got a security questionnaire?
Send it to security@trackflo.tech. We fill them in ourselves, we answer what we can evidence, and where the answer is "not yet" we say "not yet" rather than finding a form of words. If a control you need is missing, you will hear that on the first call rather than in month three.
Our Security Program, Incident Response and Continuity Plan, and architecture and data-flow document are available to security reviewers on request.
See it against your own data
A founder-led demo, on your loads, with your questions about how any of this works.