Skip to main content
HARLY_URL is the canonical public origin. Use a bare origin without a path: https://hiring.example.com. Every secret must be independent — do not reuse values between variables.

Required runtime values

npx @harly/cli generates independent values and writes .env with mode 0600. On managed platforms, store all values as secret variables rather than plain configuration. Secrets for BETTER_AUTH_SECRET, AI_ENCRYPTION_KEY, STORAGE_UPLOAD_SECRET, CRON_SECRET, and HARLY_SETUP_SECRET must contain at least 32 bytes (or 32+ bytes when base64-decoded).

Storage

Local volume

Back up the uploads volume together with PostgreSQL. Do not use local storage on platforms with ephemeral filesystems (Render, Railway, Fly.io).

S3-compatible storage

S3_ENDPOINT and S3_PUBLIC_URL are optional for AWS but required for Cloudflare R2, MinIO, and other S3-compatible providers. All four core S3 variables (S3_BUCKET, S3_REGION, S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY) are required when STORAGE_PROVIDER=s3. Candidate files must live in a private bucket. Disable public access, object ACLs, anonymous GetObject, and public CDN origins. Harly serves resumes through an authenticated application route with Cache-Control: private, no-store; do not configure a public CDN path for workspaces/*/resumes/*.

Scheduler and metrics

The scheduler authenticates private cron routes using CRON_SECRET. Harly exposes a Prometheus-compatible metrics endpoint:
Never put either secret in a URL or query string. The scheduler handles the email outbox, domain-event replay, webhooks dispatch, interview calendar sync, mailbox sync, document expiry, retention enforcement, e-sign reconciliation, scheduled reports, and governed evaluation jobs.

Resource profiles

The CLI selects a resource profile based on the available free memory at install time. You can override any value in .env. Override individual limits in .env:

Optional integration credentials

Installation-level OAuth credentials enable each integration’s connect flow. All are optional. Workspace credentials are encrypted in PostgreSQL after an administrator connects an account. Slack delivery history is retained for 90 days by default. Operators may set SLACK_DELIVERY_RETENTION_DAYS between 30 and 730 days; the protected webhooks-dispatch cron purges completed and dead-lettered records outside that window. ID and secret must always be set together — configuring only one causes a startup validation error. See integrations overview for provider-specific redirect URIs and setup steps.

Security-sensitive settings

Set to true only for a controlled internal deployment where outbound webhooks must reach loopback or private addresses. In all other deployments, leave at the default — Harly blocks loopback, private, link-local, and cloud-metadata addresses on all outbound HTTP actions.