Enterprise On-Premises
SyntheticBrew Enterprise runs the SyntheticBrew agent platform in your on-premises or private infrastructure. Your organization controls the runtime, database, network, identity integration, observability, backups, and release schedule. SyntheticBrew provides versioned releases, compatibility guidance, and a support channel for the deployment.
Use this runbook after your organization has completed Enterprise onboarding and received release access. It covers the deployment inputs and operating responsibilities for your platform team.
1. Collect the deployment inputs
Section titled “1. Collect the deployment inputs”The customer delivery includes:
- credentials for SyntheticBrew’s private container registry;
- the approved Enterprise version and compatibility notes;
- the
license.jwtruntime credential and its matching verification configuration; - the migration artifact for that release;
- the customer Helm chart or values overlay when Kubernetes is in scope.
Store registry credentials and the license.jwt runtime credential in your secret manager. Do not commit them to a repository or bake them into an image.
Authenticate the host or CI runner to GHCR using a short-lived token with package-read access:
printf '%s' "$GHCR_TOKEN" | docker login ghcr.io -u "$GHCR_USER" --password-stdindocker pull "ghcr.io/syntheticinc/syntheticbrew-ee:${SYNTHETICBREW_VERSION}"Pin an explicit, approved version. Do not deploy latest, and use the same release family for SyntheticBrew, the migration artifact, the chart, and brewctl compatibility checks.
2. Prepare PostgreSQL and secrets
Section titled “2. Prepare PostgreSQL and secrets”Provide a supported PostgreSQL service with TLS, durable storage, connection limits sized for every replica, and a database/user dedicated to SyntheticBrew. Keep the DSN in a secret named for the deployment rather than in values files.
Required deployment inputs include:
DATABASE_URL, using a PostgreSQL/libpq connection URL;SYNTHETICBREW_LICENSE_PATH, pointing to the mountedlicense.jwt;SYNTHETICBREW_LICENSE_PUBLIC_KEY_HEX, provided during Enterprise onboarding;SYNTHETICBREW_PUBLIC_BASE_URL, the browser-visible HTTPS origin;- authentication and JWT verification settings appropriate to your identity provider;
SYNTHETICBREW_OAUTH_ISSUERwhen coding-agent OAuth is enabled;- persistent authentication keys for a single-instance local-auth deployment, or shared identity-provider and OAuth signing keys for a multi-instance deployment.
Local authentication is intended for one replica. For multiple replicas, use external authentication and provide the same JWT verification settings to every replica. All replicas must also use the same OAuth authorization-server signing key. A per-pod generated key makes authorization codes and refresh tokens fail when traffic moves between instances. Mount shared key material read-only and restrict filesystem permissions.
3. Run database migrations
Section titled “3. Run database migrations”Run the migration artifact supplied for the target Enterprise version before starting the new SyntheticBrew release. Use a dedicated migration job with the same database secret, one active executor, a bounded timeout, and logs retained for audit.
For an initial install:
- Back up the empty or prepared database state.
- Run the pinned migration artifact.
- Confirm the job completed successfully.
- Start Enterprise and check
/api/v1/health.
For upgrades, take and verify a database backup first. Read the release compatibility notes before applying a migration; do not assume a database migrated forward can be used by an older application image.
4. Deploy with Docker Compose
Section titled “4. Deploy with Docker Compose”The following shape shows the required boundaries. Replace the placeholder migration command with the exact artifact and invocation from your customer delivery.
services: postgres: image: postgres:16 restart: unless-stopped environment: POSTGRES_DB: syntheticbrew POSTGRES_USER: syntheticbrew POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password secrets: [postgres_password] volumes: - postgres-data:/var/lib/postgresql/data
migrations: image: ${SYNTHETICBREW_MIGRATIONS_IMAGE}:${SYNTHETICBREW_VERSION} depends_on: [postgres] environment: DATABASE_URL: ${DATABASE_URL} restart: "no"
syntheticbrew: image: ghcr.io/syntheticinc/syntheticbrew-ee:${SYNTHETICBREW_VERSION} entrypoint: ["syntheticbrew-ee", "--mode", "ee", "--port", "8443"] depends_on: migrations: condition: service_completed_successfully restart: unless-stopped environment: DATABASE_URL: ${DATABASE_URL} SYNTHETICBREW_LICENSE_PATH: /run/secrets/license.jwt SYNTHETICBREW_LICENSE_PUBLIC_KEY_HEX: ${SYNTHETICBREW_LICENSE_PUBLIC_KEY_HEX} SYNTHETICBREW_PUBLIC_BASE_URL: https://brew.example.com SYNTHETICBREW_OAUTH_ISSUER: https://brew.example.com SYNTHETICBREW_OAUTH_AS_KEY_PATH: /run/secrets/oauth-as.key secrets: - source: license_jwt target: license.jwt - source: oauth_as_key target: oauth-as.key ports: ["8443:8443"]
secrets: postgres_password: file: ./secrets/postgres-password license_jwt: file: ./secrets/license.jwt oauth_as_key: file: ./secrets/oauth-as.key
volumes: postgres-data:The private image’s delivery defaults may also support SyntheticBrew-operated environments, so the explicit --mode ee entrypoint is intentional for customer-managed Enterprise. Put a TLS reverse proxy or load balancer in front of port 8443 and restrict direct network access.
5. Deploy with Kubernetes and Helm
Section titled “5. Deploy with Kubernetes and Helm”Use the private chart or Enterprise values overlay supplied for the release. Configure at least:
image: repository: ghcr.io/syntheticinc/syntheticbrew-ee tag: "1.20.0" # example only; use the approved release
imagePullSecrets: - name: syntheticbrew-ghcr
postgresql: external: existingSecret: syntheticbrew-database existingSecretKey: DATABASE_URL
migrations: enabled: true image: repository: <migration-image-from-customer-delivery> tag: "1.20.0"
config: auth: mode: local # use external with the supplied identity-provider settings for multiple replicas oauth: issuer: https://brew.example.com asKeySecret: syntheticbrew-oauth-signing-keyCreate syntheticbrew-ghcr in every target namespace and attach it through imagePullSecrets. Keep license.jwt, its verification key, database credentials, OAuth signing keys, and identity-provider settings in Kubernetes Secrets. The chart supports an existing Secret containing DATABASE_URL, an OAuth signing-key Secret, and extraEnv, extraVolumes, and extraVolumeMounts for the runtime credential. Follow the secret names and mount paths in the release-specific values supplied to your organization.
Use the Enterprise chart or profile delivered with the release. It must both select the private image and start syntheticbrew-ee --mode ee; changing only image.repository and image.tag is not sufficient because the private image also supports SyntheticBrew-operated Cloud deployments. Render and review the manifests before applying:
helm template syntheticbrew <customer-chart> -f values-enterprise.yamlhelm upgrade --install syntheticbrew <customer-chart> \ --namespace syntheticbrew --create-namespace \ -f values-enterprise.yamlRun migrations as a pre-install/pre-upgrade job and wait for successful completion before the Deployment rolls. Use a PodDisruptionBudget, readiness probes, resource requests and limits, and topology rules appropriate to your availability target.
6. Configure access and public URLs
Section titled “6. Configure access and public URLs”Terminate HTTPS at your ingress or reverse proxy and forward the original host and scheme. SYNTHETICBREW_PUBLIC_BASE_URL must match the origin users reach; generated widget URLs depend on it. SYNTHETICBREW_OAUTH_ISSUER must match the externally reachable SyntheticBrew origin used by coding agents.
Route the Admin UI, API, OAuth discovery and callbacks, MCP endpoint, and widget assets through the same public origin unless your customer delivery explicitly defines a split-domain topology. Preserve streaming responses: disable proxy buffering for SSE paths, allow long-lived connections, and set idle timeouts above the longest supported agent turn. Forward Host, X-Forwarded-Host, X-Forwarded-Proto, and only the client-address headers approved by your security team.
At the edge:
- redirect HTTP to HTTPS and use certificates from your approved issuer;
- restrict direct access to the application port;
- allow the documented Knowledge upload size while keeping lower body limits on ordinary routes where possible;
- apply browser security headers without blocking widget origins you intentionally support;
- verify that SSE responses are not cached, buffered, or transformed.
Choose the authentication mode and JWT verification configuration agreed during deployment setup. Restrict Admin access through your identity provider and network policy. Use scoped API keys for automation and OAuth for interactive coding agents.
For multiple replicas:
- use external authentication rather than local authentication;
- share PostgreSQL and OAuth signing keys;
- make runtime-credential and configuration mounts identical;
- keep clocks synchronized;
- ensure every instance receives the same public URL and issuer;
- use rolling deployment settings that preserve capacity during upgrades.
Apply request-rate controls at the edge
Section titled “Apply request-rate controls at the edge”SyntheticBrew enforces configured usage allowances, but it does not provide a general per-IP HTTP rate limiter for every route. Apply abuse controls in your ingress, API gateway, or reverse proxy. Use separate policies for chat, administrative mutations, OAuth, MCP, and document uploads instead of one low global limit that breaks streaming or bundle operations.
Return 429 Too Many Requests with a useful Retry-After value, and key authenticated limits by a trustworthy identity when the gateway can validate it. Do not trust a caller-supplied forwarding header unless the request came through your own proxy. Test the policy with both short requests and a real SSE chat; the limiter must count the request without terminating a healthy stream.
7. Validate the installation
Section titled “7. Validate the installation”Check the process, runtime access, and dependencies separately:
curl --fail --silent --show-error https://brew.example.com/api/v1/healthcurl --fail --silent --show-error https://brew.example.com/.well-known/mcp/server-card.json/api/v1/health remains available when the runtime credential is rejected so operators can distinguish a live process from a deployment that cannot accept sessions. Validate an authenticated Admin session and a new chat session as functional checks. When Prometheus metrics are enabled for your deployment, scrape /metrics over a protected network path and alert on request failures, latency, database saturation, runtime-credential transitions, and pod restarts.
Send structured container logs to your central logging system. Never log API keys, authorization callbacks, license.jwt, database credentials, or OAuth signing keys.
Recommended alerts include:
- health or readiness failures;
- repeated 5xx responses and elevated chat failure rate;
- sustained request or model latency above your objective;
- PostgreSQL connection exhaustion, storage growth, replication lag, or backup failure;
- pod or container restart loops and resource saturation;
- open MCP circuit breakers and repeated transport failures;
- rejected or expiring runtime credentials;
- OAuth failures that occur only on one replica.
Use application metrics for trends and alerts, Tool Call Log for one agent action, Audit Log for configuration changes, and infrastructure logs for network, database, and process failures. No single view replaces the others.
8. Update the runtime credential
Section titled “8. Update the runtime credential”The Enterprise process watches license.jwt and revalidates it on a five-minute cycle. Replace the mounted file atomically; the process does not require a restart. Allow one polling interval, then verify a new session and review the credential transition in logs.
In Kubernetes, make sure the secret-volume update mechanism replaces the projected file visible to the pod. If your secret synchronizer uses an immutable mount, roll the Deployment after updating the secret.
9. Back up and restore
Section titled “9. Back up and restore”Back up PostgreSQL with point-in-time recovery suitable to your recovery objectives. Also retain versioned, encrypted copies of:
- declarative SyntheticBrew configuration and Knowledge Graph bundles;
- the current and previous
license.jwtdelivery; - OAuth and JWT signing keys;
- Helm values with secret values removed;
- the exact image digests and migration versions.
Practice restoration into an isolated environment. Restore database and signing keys together, deploy the matching application version, run only the migrations required for that version, and complete authenticated chat and MCP smoke tests.
Use the PostgreSQL backup mechanism supported by your database operator. A logical example is:
pg_dump --format=custom --file=syntheticbrew.dump "$DATABASE_URL"pg_restore --clean --if-exists --no-owner \ --dbname="$RESTORE_DATABASE_URL" syntheticbrew.dumpUse client tools compatible with the server version, encrypt the output, and avoid exposing a DSN in command history or process listings. For production recovery objectives, combine tested logical exports with the provider’s physical backup or point-in-time recovery service. A backup is not verified until a restore and application smoke test succeed.
10. Upgrade and rollback
Section titled “10. Upgrade and rollback”- Read the release notes and compatibility matrix.
- Record current image digests, chart values, migration version, and database version.
- Verify backups and restore procedures.
- Pull and scan the pinned target artifacts.
- Run migrations, then roll the application.
- Check health, Admin access, chat, MCP discovery, OAuth, widgets, and metrics.
Run the release checks through the same ingress and identity path used by real users. Include at least one schema delegation, one Knowledge query, one MCP tool call, an OAuth connection where the browser and coding agent are on different machines, and a widget request from an allowed origin.
Application rollback is safe only when the previous application version supports the migrated schema. If it does not, restore the pre-upgrade database backup as part of rollback. Never point an older release at a database schema outside its documented compatibility range.
Troubleshooting
Section titled “Troubleshooting”/metrics is unavailable: confirm metrics are enabled for the deployment and verify the license.jwt mount, then inspect runtime-credential watcher logs.
OAuth works on one pod only: all replicas are not using the same authorization-server signing key, issuer, or clock.
The image cannot be pulled: refresh the GHCR package-read credential and verify the pull secret exists in the workload namespace.
The migration job fails: stop the rollout, retain its logs, verify database connectivity and version compatibility, and contact Enterprise support before rerunning a partially applied migration.
Health is 200 but new sessions are refused: the process is available for diagnosis, but the license.jwt credential may be expired, invalid, or blocked. Inspect the credential transition and mounted file.