# Security Security details for evaluating and operating a self-hosted PullApprove5 deployment. ## Network PullApprove5 serves HTTP on port 8000 and expects TLS to be terminated at your load balancer or reverse proxy. See [Proxy Configuration](/docs/self-hosted/operations/#proxy-configuration) in the operations guide. **Inbound:** Your `server` containers must be reachable by your Git hosting provider for webhook delivery. **Outbound:** PullApprove5 makes HTTPS connections to your Git hosting provider's API. Ensure your firewall allows egress to the relevant domains: - **GitHub / GitHub Enterprise** — `github.com` and `api.github.com`, or your GitHub Enterprise Server hostname - **GitLab** — `gitlab.com`, or your self-hosted GitLab hostname These are the only outbound connections PullApprove makes. There is no telemetry, license checking, or phone-home traffic. For air-gapped environments: PullApprove can run on a fully internal network as long as it can reach your Git provider (e.g., GitHub Enterprise Server or self-hosted GitLab on the same network). ### IP Allow Lists If your GitHub organization uses an [IP allow list](https://docs.github.com/en/organizations/keeping-your-organization-secure/managing-security-settings-for-your-organization/managing-allowed-ip-addresses-for-your-organization), add your PullApprove instance's outbound IP address(es) to the allow list. Otherwise, API calls from PullApprove to GitHub will be blocked. GitHub Apps also have their own **IP allow list** setting under **Optional features** in the app settings. If your organization uses IP allow lists, add your PullApprove instance's IP addresses here so they are automatically inherited when the app is installed. ![GitHub App IP allow list settings](/assets/docs/img/self-hosted-github-ip-allow-list.afa4170.png) ## Authentication User authentication is handled via your Git provider's OAuth. If your organization enforces SSO at the GitHub or GitLab level, PullApprove inherits that enforcement — users must pass your SSO before they can log in to PullApprove. Users only see data for repositories they have access to on the Git provider. Sessions expire after 2 weeks by default. To customize this, set the `PULLAPPROVE_SESSION_COOKIE_AGE` environment variable to the desired duration in seconds. Session data is stored in PostgreSQL and expired sessions are automatically cleaned up. **Note:** If you connect PullApprove to a self-hosted GitHub Enterprise Server or GitLab instance, login is inherently restricted to users on that instance. However, if you connect to github.com or gitlab.com, any user with an account on that platform could potentially log in if they discover your PullApprove URL. In that case, ensure your PullApprove instance is not publicly accessible, or use network-level controls to restrict access. If you need additional login restrictions, [contact us](https://www.pullapprove.com/support/). ## Application Security The Docker image runs as a non-root user (`app`) and is based on `python:3.13-slim-bookworm`. The image contains no build tools in the production stage. PullApprove ships with a strict Content Security Policy (CSP) that uses per-request nonces for inline scripts (`'strict-dynamic'`). If you use a WAF or reverse proxy, ensure it does not strip or override the `Content-Security-Policy` response header. ## Vulnerability Scanning The Docker image is scanned with [Trivy](https://trivy.dev/) for OS package and Python dependency vulnerabilities, as well as Dockerfile misconfigurations. The image is compatible with any container scanning tool your organization uses. ## Data Storage PullApprove5 stores the following data in PostgreSQL: - **Pull request metadata** — titles, branches, status, and API response data from your Git provider - **Code review configuration** — cached copies of your `CODEREVIEW.toml` files - **Processing results** — review state and scope evaluations for each pull request - **User accounts** — email addresses and OAuth connections for users who log in - **Organization and repository metadata** — names, settings, and provider identifiers - **Session data** — stored in PostgreSQL (no Redis or external session store required) PullApprove5 does not store source code, file contents, or diffs. Diffs are read during processing but never persisted.