Security
Where Validate.QA runs, how we protect accounts and test credentials, and what the agent checks in your own app while it tests.
This page describes how Validate.QA runs today. Each statement is something we can point to in our code or our AWS setup.
Where it runs. Our servers, web apps, test runners and databases are on AWS.
Hosted on AWS. The application servers, web apps, test runners and databases run on Amazon Web Services in the US East (N. Virginia) region.
AWS's own certifications. AWS has its own compliance programs for the data centres and services we use, including SOC 2 reports and ISO/IEC 27001 certification. Those are AWS's, not ours. Validate.QA does not hold a formal compliance certification today.
Encrypted in transit. Traffic from the internet is encrypted with TLS 1.2 or 1.3 at our load balancer, and plain HTTP is redirected to HTTPS. Connections to the database require TLS, and our servers check the database's certificate and host name. Inside our AWS network, traffic between the load balancer and our containers is not encrypted.
Encrypted at rest. Databases and their backups, and the secrets our servers use, are encrypted at rest with AWS-managed keys.
Private databases. Databases are not reachable from the internet. They accept connections only from our own servers.
Backups. Databases are backed up automatically. Backups are kept for 7 days, and a database can be restored to any point within that period. Deletion protection is on.
Accounts and access. How sign-in, sessions and project access work.
Passwords. Passwords are hashed with bcrypt before they are stored.
Sessions and tokens. Browser sessions use HttpOnly, SameSite cookies tied to a server-side session that ends when you sign out. Changing or resetting a password signs out every session and revokes your personal API, runner and MCP tokens. API and runner tokens are stored only as hashes.
Project access. All customers share one platform. Every request is checked against your project membership, and data is filtered by project on the server.
Sign-in protection. Sign-in and AI endpoints are rate-limited. Sign-in to our staff admin area requires a one-time code sent by email on each new browser.
Your test credentials. Tests that sign in to your app need a login. This is how we handle it.
How they are stored. Test login details are saved as project test data, with passwords marked secret and masked in the app. The database that holds them is encrypted at rest.
How tests use them. Tests read them as environment variables when a run starts. When one of our AI agents signs in to your app, it is given only the name of the login variable, never its value: the runner types the value into the sign-in field itself, and only on your app's own sign-in page or on a sign-in host you list. This covers our own browser agent and our command-line AI agent runs, including repair, and the typed value is hidden from the page snapshots the agent reads.
What is scrubbed. Secret values of 8 characters or more, and common credential formats, are scrubbed from the run logs and results we store; shorter passwords are not, so use a longer one. Screenshots and videos show what the page shows, so use a dedicated test account rather than a real person's.
How test runs are isolated. Your tests run code against your app, so they run apart from our own systems.
Separate runners. Most cloud runs get their own short-lived container. Runs that share a machine run each test as a separate unprivileged user, with its own temporary folders and without our runner credentials. If that sandbox cannot start, the run fails instead of running unprotected. Test runners can reach any public internet address, since they test your public app.
No inbound connections. Test runners accept no inbound connections.
Checked URLs. Before a cloud run starts, and before our servers fetch a URL you give us, such as a webhook or a security-check target, we check that it does not point at a private, loopback or cloud-metadata address. Local runners may test localhost.
How we run it. Build, network and logging practices.
Secrets. Our application servers get their secrets from AWS SSM Parameter Store and Secrets Manager when they start, or from our database, where the application encrypts them (AES-256-GCM) before storing them. Secrets are not stored in our source code or container images.
Network. Our containers accept connections only from our load balancer and from each other. Our APIs send standard security headers, refuse signed-in changes sent from other websites, and cap request sizes.
Builds. Our server, web and shared-runner images are built in AWS CodeBuild, tagged with the commit ID in a registry that does not allow a tag to be overwritten, and scanned for known vulnerabilities when pushed. Third-party GitHub Actions are pinned to exact commits.
Logs and records. Server and database logs are kept in CloudWatch for 30 days and test-runner logs for 14 days, and alarms watch for server errors, unhealthy services and database load. We keep internal records when our staff open a customer workspace or change platform settings.
Your data. What we keep, for how long, and who else sees it.
Stored media. Screenshots, recordings and uploaded files are stored in Amazon S3, in the same US East region. The storage is private, encrypted at rest, and accepts only encrypted (TLS) connections. When a file is deleted, an earlier copy can remain recoverable for a while. Screenshots and recordings from test runs expire after 14 days by default; site-map screenshots and uploaded files are kept with the project until it is deleted.
Deleting a project. The workspace owner can delete a project, unless it is the owner's last project or another member's only project. The delete removes it and its data from our live database in one step, and then deletes its stored screenshots, videos, traces, recordings, discovery data, uploaded documents and repository snapshots in the background, retrying each folder up to three times, but we do not guarantee that every file is removed. We keep billing and payment records and the internal records of staff actions. A private test repository we created for the project in our GitHub organization, if you turned that on, is not deleted automatically. Backups made before the delete can still contain the project, and a deleted file can stay recoverable in storage for a while. If a file could not be deleted, or you need everything removed and confirmed, contact support. To delete an account, contact support.
Payments. Payments go through Stripe Checkout, so card details never reach our servers. We keep Stripe customer and subscription IDs, your plan status and billing contact details. Stripe webhooks are signature-checked.
AI providers. When AI features run, page structure, test code, logs and some screenshots are sent to the AI model providers listed in our privacy policy.
What the agent checks in your app. Findings start from the traffic captured during your own test runs, so they can include signed-in pages that a crawler does not reach.
Authentication and access. Endpoints that answer without the authentication they should require, and credentials that show up where they should not.
Sensitive data. Personal information, internal fields, and stack traces that appear in the responses the agent observed.
Cookies and transport. Session cookie flags, missing security headers, CORS settings, and caching of authenticated responses.
Some findings are then confirmed with a few follow-up HTTP requests from our servers to your app (at most 10 per finding). These can include POST, PUT and DELETE requests, so run security checks against a test environment. Findings are produced with AI, so treat each one as a candidate to review: each lists a severity, the affected endpoint, and the page where it appeared. Review it, confirm it, or dismiss a false positive. These checks complement a penetration test and do not replace one.
Report a security issue. Email support@validate.qa with the subject "Security".
Open Security · Get Started Free