# Self-hosting Security

Self-hosting changes the trust boundary, not the sensitivity of the data. Provon can receive prompts,
responses, tool arguments, tool results, retrieved documents, user identifiers, provider
credentials, and repair context. Treat the deployment as part of the production agent data plane.

## Define The Boundary

Document these decisions before deployment:

| Question                                         | Decision to record                                         |
| ------------------------------------------------ | ---------------------------------------------------------- |
| Where can metadata, telemetry, and blobs reside? | Region, provider, account, encryption, and backup scope    |
| Which payloads may be retained?                  | Prompt, response, tool, retrieval, attachment, and logs    |
| Which systems may receive outbound data?         | Model providers, IdPs, connectors, email, and telemetry    |
| Who can administer the deployment?               | Infrastructure, organization, project, and secret roles    |
| How are workloads isolated?                      | Organization, project, environment, and API-key boundary   |
| How is an incident contained?                    | Key rotation, connector disablement, egress block, restore |

Use separate production and non-production stores, secrets, domains, API keys, OAuth applications,
and model-provider credentials.

## Network Security

### Inbound

- Terminate TLS before every public Workbench, API, Gateway, and OTLP surface.
- Keep Node bound to loopback or a private interface behind the ingress.
- Expose Cloudflare Jobs and telemetry warehouse surfaces only through platform triggers and Service
  Bindings.
- Apply request-size limits at the ingress that are at least compatible with
  `PROVON_OTLP_MAX_BYTES`.
- Preserve streaming and WebSocket upgrades only on paths that require them.
- Rate-limit login, API, Gateway, and OTLP paths by their distinct traffic characteristics.
- Restrict administrative access with network or identity-aware policy where practical.

### Forwarded Hosts

Provon can build callbacks and authentication URLs from forwarded host information. Enable
`PROVON_AUTH_TRUST_HOST=true` only when the trusted ingress overwrites:

```text
X-Forwarded-Proto
X-Forwarded-Host
X-Forwarded-Port
```

Do not append untrusted client values to these headers.

### Outbound

Create an allowlist for:

- configured model-provider endpoints;
- OAuth and SSO providers;
- Connector APIs;
- MotherDuck when selected;
- required package and Cloudflare endpoints during deployment.

An external model receives the request content sent to it. Keeping Provon inside a private network
does not change that provider boundary.

## Credential Classes

Keep these credentials separate:

| Credential           | Used by                                    | Storage rule                                |
| -------------------- | ------------------------------------------ | ------------------------------------------- |
| `AUTH_SECRET`        | Sessions and stored-secret encryption      | Secret manager plus protected recovery copy |
| User session         | Workbench browser                          | Secure, HTTP-only cookie policy             |
| Project API key      | Gateway, OTLP, and API clients             | Workload secret store                       |
| Provider credential  | Gateway upstream request                   | Encrypted project metadata                  |
| Connector credential | OAuth and external actions                 | Encrypted project metadata                  |
| Deployment API token | Cloud or infrastructure provisioning       | CI or operator secret store                 |
| Storage credential   | MotherDuck, R2 SQL, or Data Catalog access | Runtime-specific secret binding             |

Never reuse a project API key as a provider key or Connector token. Never put credentials in
workflow definitions, trace attributes, Issue bodies, or application logs.

## Encryption

Provon encrypts stored provider credentials, Connector secrets, and OAuth account tokens using key
material derived from `AUTH_SECRET`.

You still own:

- disk or volume encryption for Node storage;
- provider encryption for D1, R2, MotherDuck, and backups;
- TLS between clients, ingress, Provon, model providers, and connectors;
- secret-manager encryption and access policy;
- deletion of old exports, snapshots, and recovery copies.

Back up `AUTH_SECRET` separately from the encrypted metadata backup, with access controls that
require both materials for recovery. Losing the secret prevents credential recovery; exposing it
weakens every encrypted credential in that deployment.

## Identity And Sessions

- Prefer an organization-managed OIDC provider for production administration. Enable SAML only
  after the deployable runtime supplies a production schema validator.
- Keep provider email verification enabled.
- Leave dangerous account linking disabled unless the identity contract is explicit.
- Use exact `PROVON_WORKBENCH_ORIGINS`; do not use wildcard origins.
- Use a parent cookie domain only for intentional split subdomains.
- Never enable CSRF bypass or SAML schema-validation bypass in production.
- Remove users and organization memberships promptly when access changes.
- Test sign-out and session invalidation as part of the identity rollout.

Email/password sign-in remains an account path when social or enterprise providers are not the sole
configured policy. Include it in access reviews and incident procedures.

## Project API Keys

Use one project API key per application and environment. Grant only required capabilities:

- `gateway:invoke` for model traffic;
- telemetry ingest for exporters;
- telemetry or workspace read only for clients that query it;
- provider-management capabilities only for administrative automation.

Rotate workload keys independently from provider and Connector credentials. Because the secret is
shown only at creation, update the workload and verify the new key before revoking the old one.

## Provider And Endpoint Security

Provider credentials stay server-side; applications authenticate to Provon with project API keys.

For custom public OpenAI-compatible targets, Provon rejects credentials in URLs, query strings,
fragments, internal hostnames, and private or reserved IP literals. Keep DNS resolution policy and
egress controls at the infrastructure layer as well.

Use the Node `self/*` path for private local inference. Do not weaken public endpoint validation to
reach a private model.

## Evidence Privacy

Minimize evidence before relying on retention:

1. Send stable pseudonymous identifiers instead of names or email addresses.
2. Avoid secrets in span attributes, logs, prompts, and tool outputs.
3. Capture full bodies only when diagnosis requires them.
4. Apply source-side redaction before export.
5. Set project retention for telemetry and raw payloads.
6. Verify deletion in telemetry, blobs, exports, and external repair systems.

Filtered Gateway capture can reduce volume but may remove the causal context required for
conversation diagnosis. Choose capture based on the diagnostic contract, then control exposure with
redaction, authorization, and retention.

See [Tracing attributes](./tracing-attributes.md) and
[Production tracing](./tracing-production.md).

## Connector Security

- Create separate OAuth applications for login and project Connectors.
- Register exact callback URLs.
- Request only scopes needed by the action.
- Prefer repository-scoped fine-grained credentials where supported.
- Disable a Connector immediately when its external account is compromised.
- Keep repair Issue content free of credentials and unnecessary private payloads.
- Audit external systems because a Provon deletion does not delete copied Issue or message content.

## Cloudflare Boundary

For the Cloudflare runtime:

- use least-privilege deployment, R2 SQL, and Data Catalog tokens;
- keep secrets in Worker secret bindings, not Wrangler TOML;
- keep the telemetry warehouse inaccessible from public `workers.dev` routes;
- use Service Bindings for Worker-to-Worker calls;
- preserve Durable Object migration history;
- isolate production resources from preview and staging resources;
- review Cloudflare account roles and CI token permissions separately.

R2 Data Catalog writes require broader permissions than read-only R2 SQL queries. Use separate
tokens so a read surface cannot mutate the telemetry warehouse.

## Node Boundary

For the Node runtime:

- run as an unprivileged user;
- make data files readable only by the service identity and backup operator;
- do not mount the Docker socket;
- keep package installation and compilation out of the runtime container;
- patch the host, Node runtime, reverse proxy, and container base image;
- use one active Provon process for the local data directory;
- send `SIGTERM` and allow graceful shutdown before replacing the instance.

## Release Gate

- HTTPS and forwarded-host behavior are verified.
- Public origins and callback URLs are exact.
- `AUTH_SECRET` is stable, backed up, and consistent across surfaces.
- Production and non-production resources are isolated.
- Identity-provider email trust and account-linking policy are reviewed.
- Project API keys are least-privilege and workload-specific.
- Egress destinations are inventoried and restricted.
- Payload capture and retention match the data classification.
- Node files or Cloudflare resources have storage-level encryption and recovery controls.
- Provider, Connector, deployment, and storage tokens use separate scopes.
- Security logs and credential-rotation procedures have owners.

## Related Docs

- [Self-hosting configuration](./self-hosting-configuration.md)
- [Self-hosting operations](./self-hosting-operations.md)
- [Gateway governance](./gateway-governance.md)
- [Production Gateway](./gateway-production.md)
- [Connectors](./connectors.md)
