/DOCS · ON-PREM

Install CipherRun
inside your network.

A source-based installation guide for operators running CipherRun with PostgreSQL, including an npm cache workflow for restricted and air-gapped environments.

→ Start the install
STEP 1 / SUPPORTED SURFACE

Run the Node application and PostgreSQL.

This repository supports a plain Node.js + Express process backed by PostgreSQL. It does not include a Dockerfile or Compose definition, so this guide installs the checked-out application with npm and runs it as a managed Node process. Use Node.js 20 or newer and a reachable PostgreSQL database.

STEP 2 / INSTALL SEQUENCE

Prepare once online, then install offline.

  1. Obtain a source release that includes package.json and package-lock.json.
  2. On a network-connected staging host with the same operating system, architecture, and Node runtime platform as the target, populate a release-local npm cache:
    npm ci --cache .npm-cache
  3. Transfer the complete release and its .npm-cache directory into the restricted environment. The cache must contain every package referenced by package-lock.json.
  4. In the release directory on the restricted host, install from that cache:
    npm ci --offline --cache .npm-cache
  5. Configure the process environment, including DATABASE_URL. Use a service manager or deployment configuration; this app does not read a local .env file.
  6. Apply the database schema before routing traffic:
    npm run migrate
  7. Start the server:
    npm start
  8. From a host that can reach the service, verify the health endpoint:
    curl -fsS http://127.0.0.1:3000/health
Cache completeness matters. npm offline mode cannot fetch a missing package. If the install reports a cache miss, rebuild and transfer the cache from a connected staging host using the same lockfile and runtime platform.
STEP 3 / CONFIGURATION REFERENCE

Separate startup settings from optional features.

Only DATABASE_URL is required for the server to start. The rest of these settings enable authentication, integrations, outbound services, or hosted features.

SettingWhen to set it
DATABASE_URLRequired at startup. PostgreSQL connection string used by the app and migration runner.
PORTOptional. HTTP port; defaults to 3000.
NODE_ENVSet to production for deployment. Authentication cookies are marked secure unless the value is development.
JWT_SECRETSet an explicit high-entropy secret for session signing. The current code falls back to DATABASE_URL, but that is not a suitable production secret.
APP_URLSet to the local public origin when enabling magic-link email, so generated links return to this installation.
OPENAI_API_KEYOptional for LLM workflow steps. Without a key, the runner uses a heuristic fallback.
OPENAI_BASE_URLOptional LLM endpoint override. Defaults to https://api.openai.com/v1; point it at an approved reachable OpenAI-compatible endpoint, including an internal service.
SLACK_WEBHOOK_URLOptional. Enables Slack notifications when the configured webhook endpoint is reachable.
POSTMARK_API_KEYOptional for direct Postmark email features. Requires access to Postmark's API.
POSTMARK_FROMNot currently read from the environment in this repository. The magic-link sender currently uses hello@polsia.app.
POLSIA_API_KEYOptional for email sent through the Polsia proxy and for hosted billing. Those proxy calls require access to polsia.com.
STRIPE_SECRET_KEY, STRIPE_TEAM_PRICE_ID, STRIPE_BUSINESS_PRICE_ID, STRIPE_WEBHOOK_SECRETHosted billing settings. Checkout uses the Polsia billing proxy and requires POLSIA_API_KEY plus network access; billing is not part of a fully air-gapped baseline.
S1_WEBHOOK_SECRETConditional inbound SentinelOne webhook authentication. Configure it when authenticating incoming SentinelOne events.
POSTMARK_WEBHOOK_SECRETConditional inbound Postmark webhook authentication. Configure it when authenticating incoming Postmark events.
Outbound email is optional. Postmark-backed sends use POSTMARK_API_KEY; proxy-backed sends use POLSIA_API_KEY. Both require network access to their respective services and are not available in a fully air-gapped baseline.
STEP 4 / PERSISTENCE AND OPERATIONS

Keep durable state in PostgreSQL.

PostgreSQL stores application records and the _migrations migration history. Give the database durable storage, back it up on an operator-defined schedule, and test a restore. Run npm run migrate successfully before sending traffic to a new release.

STEP 5 / AIR-GAP LIMITS

Enable only integrations with reachable services.

Offline npm installation covers the Node dependencies; it does not make external integrations local. LLM calls, Slack, Postmark, Stripe billing through https://polsia.com, SentinelOne, and workflow enrichment or integration endpoints need their configured services to be reachable. In a restricted network, use approved internal endpoints where supported or leave those capabilities disabled.

Review the rest of the application for strict no-egress deployments. Existing shared layouts load Google Fonts, and /js/pixel.js loads Meta Pixel. This guide omits both requests; other application pages need a separate egress review.
STEP 6 / FIRST-RUN CHECKLIST

Confirm the installation before handoff.

The baseline stays small.

A Node.js process, PostgreSQL, an offline npm cache, and a controlled service environment are enough to install and operate the repository's local baseline. Add network-dependent capabilities only when their endpoints are available to your deployment.