Your code stays in your GitHub Actions runner.
Paidwen splits the work in two. The engine runs in your GitHub Actions runner and executes your pull request. The servers of Paidwen start the verification, receive the results and post the verdict.
The verification runs in your own GitHub Actions runner.
Paidwen starts a workflow in your repository. GitHub gives each run a fresh machine and destroys the machine after the job. The machine checks out your code, builds your application and replays your journeys.
The Scale and Enterprise plans can also run the verification on your own runners, in your cloud or at a runner provider.
The servers of Paidwen receive results and never code.
The servers of Paidwen receive three kinds of data:
- The title, the description and the commit messages of the pull request.
- The paidwen.yml configuration read by the engine.
- The verdict, the result of each journey and the events of the run.
The servers of Paidwen never receive your source code, your videos, your screenshots or your model keys.
The GitHub App asks for five permissions and never for contents.
- Metadata, read.
- Pull requests, write, for one comment per pull request and to read its title, description and commits.
- Checks, write, for the Paidwen check.
- Actions, write, to start, cancel and read the verification runs.
- Merge queues, read.
The app has no Contents permission. Its Pull requests permission gives access to the diff of a pull request, and the servers of Paidwen never request it. The workflow job reads your repository inside the runner, with the GITHUB_TOKEN of your own workflow.
A pull request cannot change or impersonate its verification.
- Your workflow calls a reusable workflow published by Paidwen. Paidwen starts the run with
workflow_dispatchon your default branch, so the pull request cannot edit the workflow that verifies it. - The engine reads paidwen.yml from the base branch.
- The job runs in the GitHub environment named
paidwen, and Paidwen checks thejob_workflow_refclaim of the OIDC token of the job. - Before any code of the pull request runs, the runner exchanges the OIDC token for an upload token bound to the repository, the run, the attempt and the verification.
- The job reads contents and requests an OIDC token, and the checkout keeps no credentials.
No code of the pull request runs on the runner host.
The build, the migrations, the seed and the application run in containers started with an empty environment and an allow list. Each container has limits on CPU, memory and processes.
Paidwen never starts the compose file of the pull request as it is. The engine copies an allow list of keys and refuses privileged options, host bind mounts, build contexts outside the repository and unresolved variables.
The application runs on an internal network without internet access. A gateway lets through only the hosts listed in paidwen.yml.
The engine is signed and pinned.
The public action only bootstraps the engine. After the OIDC exchange, the runner downloads the versioned engine and refuses any version whose signature does not match the pinned public key. The private signing key never lives on the servers of Paidwen.
You can pin an engine version with settings.engine in paidwen.yml.
Secrets have fixed names, and forks get none.
Paidwen reads five secrets from the GitHub environment named paidwen, and the workflow forwards no other secret:
PAIDWEN_TEST_LOGINandPAIDWEN_TEST_PASSWORD, the test account of your journeys.PAIDWEN_STRIPE_TEST_KEY, your Stripe test key.PAIDWEN_ENV, the test values your application needs.PAIDWEN_MODEL_KEY, your own model key for the optional model layer.
Secrets enter the containers when the application starts, never during the build.
A pull request from a fork runs in the environment paidwen-fork, without any secret. The first pull request of a new contributor waits until a maintainer starts the verification.
No AI model reads your code.
The replay is a deterministic Playwright script. Without a model key, a failure is explained in one simple sentence built from the failed step, the action before it and what the page shows, with the screenshot and the moment in the video.
Your coding agent records a journey from one sentence on your machine, with npx paidwen mcp, and updates the target of a step when its pull request renames a control on purpose. This needs no key. The optional model layer uses your own key, PAIDWEN_MODEL_KEY, to do the same during the verification and to explain a break from the two pages. Your model sees the page reduced to its active elements and the text of the pull request, never your code. A journey passes only when its final deterministic checks pass, and a model never decides a pass alone.
The engine calls your model from the machine of your runner, and only the engine reads the key. Chromium and your application keep their network without internet, and no container of your application receives the key.
Runs that execute pull request code save no cache.
Only the baseline runs of your default branch save caches, under prefixed and capped keys.
Videos stay on GitHub.
The engine uploads the video as an artifact of your workflow run, kept 90 days. The verdict links to the artifact, and Paidwen stores no media.
The data of each customer is isolated in the database.
The database of Paidwen applies Postgres row level security to every customer, and isolation tests cover the policies.
The secrets of Paidwen live in an environment file that only its owner can read on the server. The signing key of the engine stays off the server.
You report a security issue by email.
Write to [email protected] with the steps that reproduce the issue.