Environment variables
Complete reference of the environment variables that configure a Qyra deployment
🛠 This page is for engineering teams self-hosting their own Qyra instance. If you want to configure any of these settings, please speak to the Qyra team or your Qyra administrators.
This is a reference to all environment variables that can be used to configure a Qyra deployment.
Postgres database
These variables configure the Postgres database Qyra uses to store its own application data (not your warehouse).
| Variable | Description |
|---|---|
PGHOST | (Required) Hostname of postgres server to store Qyra data |
PGPORT | (Required) Port of postgres server to store Qyra data |
PGUSER | (Required) Username of postgres user to access postgres server to store Qyra data |
PGPASSWORD | (Required) Password for PGUSER |
PGDATABASE | (Required) Database name inside postgres server to store Qyra data |
PGCONNECTIONURI | Connection URI for postgres server to store Qyra data in the format postgresql://user:password@host:port/db?params. This is an alternative to providing the previous PG variables. |
PGMAXCONNECTIONS | Maximum number of connections to the database |
PGMINCONNECTIONS | Minimum number of connections to the database |
ALLOW_MISSING_MIGRATIONS | When true, disables Knex's migration list validation so Qyra can start against a database that has migrations applied which don't exist as files on disk. Use this during rollbacks (e.g. v2 → v1) when the database stays on the newer version. Pending migrations (code ahead of DB) are still detected. (default=false) |
Qyra also accepts all standard postgres environment variables.
Server and networking
Core variables that control how the Qyra server runs, how it's reached, and how sessions and cookies behave.
| Variable | Description |
|---|---|
PORT | Port the Qyra backend listens on (default=8080) |
SITE_URL | Site url where Qyra is being hosted. It should include the protocol. E.g https://qyra.mycompany.com (default=http://localhost:8080) |
INTERNAL_QYRA_HOST | Internal Qyra host for the Headless browser to send requests when your Qyra instance is not accessible from the Internet. Needs to support https if SECURE_COOKIES=true (default=Same as SITE_URL) |
INTERNAL_QYRA_HOST_IGNORE_HTTPS_ERRORS | When true, skips TLS certificate validation on screenshot traffic going to INTERNAL_QYRA_HOST. Use this if you need to terminate TLS in front of Qyra on a fully internal hostname with a self-signed or otherwise untrusted certificate. Opt-in, default false. Security trade-off: disables TLS validation for that traffic, so only enable it when the network path is trusted (e.g. cluster-internal). See Run Qyra on a fully internal HTTPS network. |
STATIC_IP | Server static IP so users can add the IP to their warehouse allow-list. (default=http://localhost:8080) |
QYRA_SECRET | (Required) Secret key used to secure various tokens in Qyra. This must be fixed between deployments. If the secret changes, you won't have access to Qyra data. |
SECURE_COOKIES | Only allows cookies to be stored over a https connection. We use cookies to keep you logged in. This is recommended to be set to true in production. (default=false) |
COOKIES_MAX_AGE_HOURS | How many hours a user session exists before the user is automatically signed out. For example if 24, then the user will be automatically after 24 hours of inactivity. |
TRUST_PROXY | This tells the Qyra server that it can trust the X-Forwarded-Proto header it receives in requests. This is useful if you use SECURE_COOKIES=true behind a HTTPS terminated proxy that you can trust. (default=false) |
QYRA_MAX_PAYLOAD | Maximum HTTP request body size (default=5mb) |
QYRA_MODE | Mode for Qyra (default, demo, pr, etc.) (default=default) |
ALLOW_MULTIPLE_ORGS | If set to true, new users registering on Qyra will have their own organization, separated from others (default=false) |
Licensing
| Variable | Description |
|---|---|
QYRA_LICENSE_KEY | License key for Qyra Enterprise Edition. See enterprise features for details. Get your license key |
Query limits and behavior
Control how many rows a query can return, page sizes, exports, and chart-version retention.
| Variable | Description |
|---|---|
QYRA_QUERY_MAX_LIMIT | Query max rows limit (default=5000) |
QYRA_QUERY_DEFAULT_LIMIT | Default number of rows to return in a query (default=500) |
QYRA_QUERY_MAX_PAGE_SIZE | Maximum page size for paginated queries (default=2500) |
QYRA_QUERY_RETRY_ON_TRANSIENT_ERRORS | When true, the frontend automatically retries failed queries on transient errors (5xx server responses and network errors) up to 3 times with exponential backoff (1s, 2s, 4s). 4xx client errors are never retried. Useful for instances where warehouse connections occasionally drop or the backend is briefly overwhelmed. (default=false) |
QYRA_PIVOT_TABLE_MAX_COLUMN_LIMIT | Configure maximum number of columns in pivot table (default=200) |
QYRA_CSV_CELLS_LIMIT | Max cells on CSV file exports (default=100000) |
QYRA_DASHBOARD_MAX_TILES_PER_TAB | Maximum number of tiles allowed per tab on a dashboard (default=50) |
QYRA_DASHBOARD_MAX_TABS_PER_DASHBOARD | Maximum number of tabs allowed per dashboard (default=20) |
MAX_DOWNLOADS_AS_CODE | Maximum number of downloads as code (default=100) |
Scheduler
Variables that control the scheduler worker and background cleanup jobs.
| Variable | Description |
|---|---|
SCHEDULER_ENABLED | Enables/Disables the scheduler worker that triggers the scheduled deliveries. (default=true) |
SCHEDULER_CONCURRENCY | How many scheduled delivery jobs can be processed concurrently. (default=3) |
SCHEDULER_JOB_TIMEOUT | After how many milliseconds the job should be timeout so the scheduler worker can pick other jobs. (default=600000, 10 minutes) |
SCHEDULER_SCREENSHOT_TIMEOUT | Timeout in milliseconds for taking screenshots |
SCHEDULER_INCLUDE_TASKS | Comma-separated list of scheduler tasks to include |
SCHEDULER_EXCLUDE_TASKS | Comma-separated list of scheduler tasks to exclude |
SCHEDULER_POLL_INTERVAL | Polling interval in milliseconds for the scheduler worker to check for new jobs. |
QUERY_HISTORY_CLEANUP_ENABLED | Enables the background job that periodically deletes old query-history rows. (default=true) |
QUERY_HISTORY_CLEANUP_SCHEDULE | Cron expression controlling how often query history is cleaned up. |
Headless browser
Configure the headless browser used for screenshots and PDF exports.
| Variable | Description |
|---|---|
HEADLESS_BROWSER_HOST | Hostname for the headless browser |
HEADLESS_BROWSER_PORT | Port for the headless browser (default=3001) |
HEADLESS_BROWSER_MAX_SCREENSHOT_RETRIES | Maximum number of times the scheduler retries a failed screenshot before giving up. (default=5) |
HEADLESS_BROWSER_RETRY_BASE_DELAY_MS | Base delay in milliseconds for exponential-backoff retries on failed screenshots. (default=3000) |
HEADLESS_BROWSER_SCREENSHOT_TIMEOUT_MS | Maximum time in milliseconds Qyra waits for a dashboard's tiles and charts to report ready before taking a screenshot. Also applies to per-element operations during capture. Must not exceed the headless-browser container's own session timeout. (default=180000) |
USE_SECURE_BROWSER | Use secure WebSocket connections for headless browser (default=false) |
The headless-browser container has its own session timeout (for example, browserless v2's TIMEOUT, which defaults to 30 seconds). That value must be greater than or equal to HEADLESS_BROWSER_SCREENSHOT_TIMEOUT_MS, otherwise the browser will terminate the session before Qyra's readiness wait expires and the screenshot will fail. If you raise HEADLESS_BROWSER_SCREENSHOT_TIMEOUT_MS for dashboards that legitimately take longer than three minutes to render, raise the browser container's session timeout to match.
Personal access tokens
Variables that control PAT availability and lifetime.
| Variable | Description |
|---|---|
DISABLE_PAT | Disables Personal Access Tokens (default=false) |
PAT_ALLOWED_ORG_ROLES | Comma-separated list of organization roles allowed to use Personal Access Tokens (default=All roles) |
PAT_MAX_EXPIRATION_TIME_IN_DAYS | Maximum expiration time in days for Personal Access Tokens |
Timezone and localization
| Variable | Description |
|---|---|
QYRA_QUERY_TIMEZONE | Instance-wide default timezone applied to queries when a user/project has no override. |
QYRA_ENABLE_TIMEZONE_SUPPORT | Enables per-query timezone support. Defaults to true on Qyra Cloud, false self-hosted. |
QYRA_ENABLE_IMPROVED_EXCEL_DATES | When true, exports timestamps to Excel as native date cells instead of strings. (default=false) |
Soft delete
Configure whether deletions are soft (recoverable) and for how long.
| Variable | Description |
|---|---|
SOFT_DELETE_ENABLED | When true, deleting charts, dashboards, spaces, saved SQL, schedulers, and data apps marks them as soft-deleted instead of removing them immediately. Soft-deleted items can be restored or permanently deleted later. (default=false) |
SOFT_DELETE_RETENTION_DAYS | Number of days soft-deleted items are retained before becoming eligible for permanent cleanup. Only applies when SOFT_DELETE_ENABLED=true. (default=30) |
Custom metrics
| Variable | Description |
|---|---|
QYRA_CUSTOM_METRICS_CONFIG_PATH | Filesystem path to a YAML config defining instance-level custom metrics surfaced in the metrics catalog. Also accepted as CUSTOM_METRICS_CONFIG_PATH. |
UI customization
Replace default URLs and tweak in-product UI surfaces.
| Variable | Description |
|---|---|
SIGNUP_URL | Overrides the URL the login page links to for new sign-ups. Useful on instances that gate sign-up behind a custom flow. |
HELP_MENU_URL | Replaces the default help-menu link in the Qyra UI with your own support/runbook URL. |
HEADWAY_ENABLED | Enables the Headway changelogs widget in the Qyra menu (default=true) |
QYRA_DASHBOARD_DISABLE_SENTRY_TRACKING | When true, suppresses Sentry tracking on the embedded dashboard frame. (default=false) |
Feature toggles
Enable or disable individual product features across the instance.
| Variable | Description |
|---|---|
GROUPS_ENABLED | Enables/Disables groups functionality (default=false) |
CUSTOM_VISUALIZATIONS_ENABLED | Enables/Disables custom chart functionality (default=false) |
EXTENDED_USAGE_ANALYTICS | When true, adds "Dashboard views (top 20)" and "Chart views (top 20)" tables to the User Activity dashboard in Project Settings > Usage Analytics. (default=false) |
DISABLE_DASHBOARD_COMMENTS | Disables dashboard comments (default=false) |
ORGANIZATION_WAREHOUSE_CREDENTIALS_ENABLED | Enables organization warehouse settings (default=false) |
EDIT_YAML_IN_UI_ENABLED | Enables the in-UI YAML editor for tables and metrics. (default=false) |
ECHARTS_V6_ENABLED | Opt into the ECharts v6 renderer. (default=false) |
FUNNEL_BUILDER_ENABLED | Enables the funnel chart builder. (default=false) |
SAVE_CREDENTIALS_FORM_ENABLED | Enables the "save credentials" form so warehouse credentials can be stored per-user. (default=false) |
PARTIAL_COMPILATION_ENABLED has been removed and no longer controls server or CLI behavior. Project create, update, and refresh paths use partial compilation, and CLI compilation uses it by default. To report failures normally handled by partial compilation as errors in a supported CLI command, use --no-partial-compilation for that run.
Feature flags
Use these to force feature flags on or off across your deployment regardless of cloud-side targeting or per-organization overrides. Both variables accept a comma-separated list of feature-flag IDs (kebab-case strings — the flag IDs themselves, not env-var names). Useful for local dev flows where you want to toggle flags without touching targeting rules.
| Variable | Description |
|---|---|
QYRA_ENABLE_FEATURE_FLAGS | Comma-separated list of feature-flag IDs to force-enable for everyone in your instance. Example: embedding,user-impersonation,scim-token-management |
QYRA_DISABLE_FEATURE_FLAGS | Comma-separated list of feature-flag IDs to force-disable for everyone. Takes precedence over per-org overrides. Example: dashboard-comments-enabled |
Athena
| Variable | Description |
|---|---|
ATHENA_WAREHOUSE_IAM_ROLE_AUTH | Set to true to enable IAM role authentication for Athena warehouse connections. When enabled, users can choose between Access Keys and IAM Role auth in the connection form. IAM Role auth uses the AWS default credential chain (e.g. ECS task role, EC2 instance profile) instead of explicit access keys. Default: false. |
Snowflake
| Variable | Description |
|---|---|
SNOWFLAKE_WAREHOUSE_ERROR_MESSAGE | Custom error message displayed when users encounter Snowflake warehouse access errors. Use {warehouseName} as a placeholder for the actual warehouse name. Include \n in the value to insert line breaks in the rendered error. Example: You don't have access to warehouse {warehouseName}.\nPlease reach out to your admin. |
SNOWFLAKE_UNAUTHORIZED_ERROR_MESSAGE | Custom error message displayed when users encounter Snowflake authorization errors (e.g., "Object does not exist or not authorized"). Use {snowflakeTable} and {snowflakeSchema} as placeholders. Include \n in the value to insert line breaks in the rendered error. Example: You don't have access to the {snowflakeTable} table.\nPlease go to '{snowflakeSchema}' and request access. |
SMTP
This is a reference to all the SMTP environment variables that can be used to configure a Qyra email client.
| Variable | Description |
|---|---|
EMAIL_SMTP_HOST | (Required) Hostname of email server |
EMAIL_SMTP_PORT | Port of email server (default=587) |
EMAIL_SMTP_SECURE | Secure connection (default=true) |
EMAIL_SMTP_USER | (Required) Auth user |
EMAIL_SMTP_PASSWORD | Auth password [1] |
EMAIL_SMTP_ACCESS_TOKEN | Auth access token for Oauth2 authentication [1] |
EMAIL_SMTP_ALLOW_INVALID_CERT | Allow connection to TLS server with self-signed or invalid TLS certificate (default=false) |
EMAIL_SMTP_SENDER_EMAIL | (Required) The email address that sends emails |
EMAIL_SMTP_SENDER_NAME | The name of the email address that sends emails (default=Qyra) |
EMAIL_SMTP_IMAGE_INLINE_CID | Embed images directly into emails as CID attachments instead of referencing external URLs. Useful for deployments behind firewalls where email clients cannot reach internal image URLs (default=false) |
EMAIL_SMTP_USE_AUTH | Whether to authenticate with the SMTP server. Set to false for open relays inside a trusted network. (default=true) |
[1] EMAIL_SMTP_PASSWORD or EMAIL_SMTP_ACCESS_TOKEN needs to be provided
SSO
These variables enable you to control Single Sign On (SSO) functionality.
| Variable | Description |
|---|---|
AUTH_DISABLE_PASSWORD_AUTHENTICATION | If "true" disables signing in with plain passwords (default=false) |
AUTH_ENABLE_GROUP_SYNC | If "true" enables assigning SSO groups to Qyra groups (default=false) |
AUTH_ENABLE_OIDC_LINKING | Enables linking a new OIDC identity to an existing user if they already have another OIDC with the same email (default=false) |
AUTH_ENABLE_OIDC_TO_EMAIL_LINKING | Enables linking OIDC identity to an existing user by matching their full email address. Required when using SCIM with SSO (default=false) |
AUTH_GOOGLE_OAUTH2_CLIENT_ID | Required for Google SSO |
AUTH_GOOGLE_OAUTH2_CLIENT_SECRET | Required for Google SSO |
AUTH_OKTA_OAUTH_CLIENT_ID | Required for Okta SSO |
AUTH_OKTA_OAUTH_CLIENT_SECRET | Required for Okta SSO |
AUTH_OKTA_OAUTH_ISSUER | Required for Okta SSO |
AUTH_OKTA_DOMAIN | Required for Okta SSO |
AUTH_OKTA_AUTHORIZATION_SERVER_ID | Optional for Okta SSO with a custom authorization server |
AUTH_OKTA_EXTRA_SCOPES | Optional for Okta SSO scopes (e.g. groups) without a custom authorization server |
AUTH_ONE_LOGIN_OAUTH_CLIENT_ID | Required for One Login SSO |
AUTH_ONE_LOGIN_OAUTH_CLIENT_SECRET | Required for One Login SSO |
AUTH_ONE_LOGIN_OAUTH_ISSUER | Required for One Login SSO |
AUTH_AZURE_AD_OAUTH_CLIENT_ID | Required for Azure AD |
AUTH_AZURE_AD_OAUTH_CLIENT_SECRET | Required for Azure AD |
AUTH_AZURE_AD_OAUTH_TENANT_ID | Required for Azure AD |
AUTH_AZURE_AD_OIDC_METADATA_ENDPOINT | Optional for Azure AD |
AUTH_AZURE_AD_X509_CERT_PATH | Optional for Azure AD |
AUTH_AZURE_AD_X509_CERT | Optional for Azure AD |
AUTH_AZURE_AD_PRIVATE_KEY_PATH | Optional for Azure AD |
AUTH_AZURE_AD_PRIVATE_KEY | Optional for Azure AD |
DATABRICKS_OAUTH_CLIENT_ID | Client ID for Databricks OAuth |
DATABRICKS_OAUTH_CLIENT_SECRET | Client secret for Databricks OAuth (optional) |
DATABRICKS_OAUTH_AUTHORIZATION_ENDPOINT | Authorization endpoint URL for Databricks OAuth |
DATABRICKS_OAUTH_TOKEN_ENDPOINT | Token endpoint URL for Databricks OAuth |
AUTH_OIDC_CLIENT_ID | Required for the generic OIDC provider |
AUTH_OIDC_CLIENT_SECRET | Required for the generic OIDC provider |
AUTH_OIDC_METADATA_DOCUMENT_URL | OIDC discovery (.well-known/openid-configuration) URL for the generic OIDC provider |
AUTH_OIDC_X509_CERT | Optional X.509 public key certificate (PEM contents) for generic OIDC |
AUTH_OIDC_X509_CERT_PATH | Optional filesystem path to an X.509 public key certificate (PEM) for generic OIDC |
AUTH_OIDC_PRIVATE_KEY | Optional private key (PEM contents) for generic OIDC private_key_jwt |
AUTH_OIDC_PRIVATE_KEY_PATH | Optional filesystem path to a private key (PEM) for generic OIDC private_key_jwt |
AUTH_OIDC_AUTH_METHOD | OIDC client auth method (e.g. client_secret_basic, client_secret_post, private_key_jwt) (default=client_secret_basic) |
AUTH_OIDC_AUTH_SIGNING_ALG | Signing algorithm used for private_key_jwt (default=RS256) |
AUTH_OIDC_SCOPES | Space-separated list of additional scopes to request from the OIDC provider |
SNOWFLAKE_OAUTH_CLIENT_ID | Client ID for Snowflake OAuth (warehouse connection sign-in) |
SNOWFLAKE_OAUTH_CLIENT_SECRET | Client secret for Snowflake OAuth |
SNOWFLAKE_OAUTH_AUTHORIZATION_ENDPOINT | Authorization endpoint URL for Snowflake OAuth |
SNOWFLAKE_OAUTH_TOKEN_ENDPOINT | Token endpoint URL for Snowflake OAuth |
S3
These variables allow you to configure S3 Object Storage, which is required to self-host Qyra.
| Variable | Description |
|---|---|
S3_ENDPOINT | (Required) S3 endpoint for storing results |
S3_PUBLIC_ENDPOINT | Public-facing S3 endpoint used when generating signed download URLs returned to users. Defaults to S3_ENDPOINT. Set this when the bucket is reached internally on a different hostname than from the user's browser (e.g. a MinIO/cluster setup). |
S3_BUCKET | (Required) Name of the S3 bucket for storing files |
S3_REGION | (Required) Region where the S3 bucket is located |
S3_ACCESS_KEY | Access key for authenticating with the S3 bucket |
S3_SECRET_KEY | Secret key for authenticating with the S3 bucket |
S3_USE_CREDENTIALS_FROM | Configures the credential provider chain for AWS S3 authentication if access key and secret is not provided. Supports: env (environment variables), token_file (token file credentials), ini (initialization file credentials), ecs (container metadata credentials), ec2 (instance metadata credentials). Multiple values can be specified in order of preference. |
S3_EXPIRATION_TIME | Expiration time for scheduled deliveries files (default=259200, 3d) |
S3_FORCE_PATH_STYLE | Force path style addressing, needed for MinIO setup e.g. http://your.s3.domain/BUCKET/KEY instead of http://BUCKET.your.s3.domain/KEY (default=false) |
RESULTS_S3_ENDPOINT | S3 endpoint for the query results bucket (default=S3_ENDPOINT) |
RESULTS_S3_BUCKET | Name of the S3 bucket used for storing query results (default=S3_BUCKET) |
RESULTS_S3_REGION | Region where the S3 query storage bucket is located (default=S3_REGION) |
RESULTS_S3_ACCESS_KEY | Access key for authenticating with the S3 query storage bucket (default=S3_ACCESS_KEY) |
RESULTS_S3_SECRET_KEY | Secret key for authenticating with the S3 query storage bucket (default=S3_SECRET_KEY) |
RESULTS_S3_FORCE_PATH_STYLE | Force path style addressing for the query results bucket (default=S3_FORCE_PATH_STYLE) |
Persistent download URLs
When enabled, CSV and dashboard ZIP exports return a stable Qyra-hosted URL (e.g. https://qyra.example.com/api/v1/file/{id}) instead of a direct S3 signed URL. Each time this URL is accessed, Qyra generates a short-lived S3 signed URL and redirects to it — so the underlying URL never goes stale and download links survive IAM credential rotation.
The variables below act as instance-wide defaults. Organization admins can override them per organization (and per channel) from Settings → Organization → Exporting. See Configuring download link expiration.
Scheduled-delivery links longer than 7 days automatically switch to a persistent URL, even if PERSISTENT_DOWNLOAD_URLS_ENABLED is false. AWS presigned S3 URLs cannot live past 7 days, so this prevents links from silently breaking.
| Variable | Description |
|---|---|
PERSISTENT_DOWNLOAD_URLS_ENABLED | Enables persistent download URLs (default=false) |
PERSISTENT_DOWNLOAD_URL_EXPIRATION_SECONDS | How long the persistent URL remains accessible (default=259200, 3 days). When persistent URLs are enabled, S3_EXPIRATION_TIME is ignored and each redirect generates a signed URL that expires after 5 minutes. |
PERSISTENT_DOWNLOAD_URL_EXPIRATION_SECONDS_EMAIL | Override expiration for email download links. Falls back to PERSISTENT_DOWNLOAD_URL_EXPIRATION_SECONDS when not set. |
PERSISTENT_DOWNLOAD_URL_EXPIRATION_SECONDS_SLACK | Override expiration for Slack download links. Falls back to PERSISTENT_DOWNLOAD_URL_EXPIRATION_SECONDS when not set. |
PERSISTENT_DOWNLOAD_URL_EXPIRATION_SECONDS_MSTEAMS | Override expiration for MS Teams download links. Falls back to PERSISTENT_DOWNLOAD_URL_EXPIRATION_SECONDS when not set. |
Cache
Note that you will need an Enterprise License Key for this functionality.
| Variable | Description |
|---|---|
RESULTS_CACHE_ENABLED | Enables caching for chart results (default=false) |
AUTOCOMPLETE_CACHE_ENABLED | Enables caching for filter autocomplete results (default=false) |
CACHE_STALE_TIME_SECONDS | Defines how long cached results remain valid before being considered stale (default=86400, 24h) |
These variables are deprecated; use the RESULTS_S3_* versions instead.
| Variable | Description |
|---|---|
RESULTS_CACHE_S3_BUCKET | Deprecated - use RESULTS_S3_BUCKET (default=S3_BUCKET) |
RESULTS_CACHE_S3_REGION | Deprecated - use RESULTS_S3_REGION (default=S3_REGION) |
RESULTS_CACHE_S3_ACCESS_KEY | Deprecated - use RESULTS_S3_ACCESS_KEY (default=S3_ACCESS_KEY) |
RESULTS_CACHE_S3_SECRET_KEY | Deprecated - use RESULTS_S3_SECRET_KEY (default=S3_SECRET_KEY) |
Logging
| Variable | Description |
|---|---|
QYRA_LOG_LEVEL | The minimum level of log messages to show. DEBUG, AUDIT, HTTP, INFO, WARN ERROR (default=INFO) |
QYRA_LOG_FORMAT | The format of log messages. PLAIN, PRETTY, JSON (default=pretty) |
QYRA_LOG_OUTPUTS | The outputs to send log messages to (default=console) |
QYRA_LOG_CONSOLE_LEVEL | The minimum level of log messages to display on the console (default=QYRA_LOG_LEVEL) |
QYRA_LOG_CONSOLE_FORMAT | The format of log messages on the console (default=QYRA_LOG_FORMAT) |
QYRA_LOG_FILE_LEVEL | The minimum level of log messages to write to the log file (default=QYRA_LOG_LEVEL) |
QYRA_LOG_FILE_FORMAT | The format of log messages in the log file (default=QYRA_LOG_FORMAT) |
QYRA_LOG_FILE_PATH | The path to the log file. Requires QYRA_LOG_OUTPUTS to include file to enable file output. (default=./logs/all.log) |
QYRA_LOG_AUDIT_ACTOR_AS_STRING | When true, audit log events serialize the actor field to a JSON string instead of a nested object. Enable this if your log indexer (e.g. Elasticsearch) maps the actor field as text and would otherwise drop it. (default=false) |
Prometheus
| Variable | Description |
|---|---|
QYRA_PROMETHEUS_ENABLED | Enables/Disables Prometheus metrics endpoint (default=false) |
QYRA_PROMETHEUS_PORT | Port for Prometheus metrics endpoint (default=9090) |
QYRA_PROMETHEUS_PATH | Path for Prometheus metrics endpoint (default=/metrics) |
QYRA_PROMETHEUS_PREFIX | Prefix for metric names. |
QYRA_GC_DURATION_BUCKETS | Buckets for duration histogram in seconds. (default=0.001, 0.01, 0.1, 1, 2, 5) |
QYRA_EVENT_LOOP_MONITORING_PRECISION | Precision for event loop monitoring in milliseconds. Must be greater than zero. (default=10) |
QYRA_PROMETHEUS_LABELS | Labels to add to all metrics. Must be valid JSON |
QYRA_PROMETHEUS_EVENT_METRICS_ENABLED | Enables Prometheus counters for product events (e.g. chart views, downloads). (default=false) |
QYRA_PROMETHEUS_EXTENDED_METRICS_ENABLED | Enables extended Prometheus metrics including warehouse query timings. (default=false) |
QYRA_PROMETHEUS_ALL_QUERY_METRICS_ENABLED | Emits a Prometheus metric for every individual query (high cardinality). (default=false) |
QYRA_PROMETHEUS_HTTP_METRICS_ENABLED | Enables the OpenTelemetry http.server.request.duration histogram with semconv labels and route templates. (default=false) |
OpenTelemetry tracing
See Configure OpenTelemetry tracing for setup, exporter selection, and sampling behaviour.
| Variable | Description |
|---|---|
QYRA_OTEL_TRACES_ENABLED | Switches tracing to OpenTelemetry mode: spans are created by the OpenTelemetry SDK and Sentry receives errors only. When false, tracing runs through Sentry. (default=false) |
QYRA_OTEL_TRACES_SAMPLE_RATE | Trace sampling ratio from 0.0 to 1.0. Falls back to SENTRY_TRACES_SAMPLE_RATE (deprecated) when unset. (default=1) |
QYRA_OTEL_ALWAYS_SAMPLE_AI_TRACES | Set to false to stop always-sampling AI agent traces, so they follow the global sampling ratio instead. (default=true) |
QYRA_OTEL_DB_TRACES_ENABLED | Adds spans for application database (Postgres) queries to traces, including the SQL statement. Requires OpenTelemetry mode. (default=false) |
QYRA_OTEL_DB_TRACES_MAX_QUERY_LENGTH | Maximum length of the SQL statement recorded on database spans; longer statements are truncated. Must be a non-negative integer. (default=1022) |
OTEL_SDK_DISABLED | Standard OpenTelemetry kill switch. When true, OpenTelemetry mode is off even if QYRA_OTEL_TRACES_ENABLED=true. |
OTEL_TRACES_EXPORTER | Comma-separated exporters: otlp, console, zipkin, or none. Unsupported values are ignored with a startup warning; none overrides any other value. (default=otlp) |
OTEL_EXPORTER_OTLP_PROTOCOL | OTLP protocol: grpc, http/json, or http/protobuf. OTEL_EXPORTER_OTLP_TRACES_PROTOCOL takes precedence. Unsupported values fall back to the default. (default=http/protobuf) |
OTEL_EXPORTER_OTLP_ENDPOINT | Base URL of your OTLP collector. Handled by the OpenTelemetry Node SDK, along with OTEL_EXPORTER_OTLP_TRACES_ENDPOINT and OTEL_EXPORTER_OTLP_HEADERS. |
OTEL_SERVICE_NAME | Service name attached to exported spans. (default=qyra) |
OTEL_LOG_LEVEL | Enables OpenTelemetry SDK and exporter diagnostics at the given level (e.g. DEBUG). Qyra redacts credentials, tokens, and span payloads from diagnostic output. |
OTEL_TRACES_SAMPLER and OTEL_TRACES_SAMPLER_ARG are overridden by Qyra. Control sampling with QYRA_OTEL_TRACES_SAMPLE_RATE instead.
Security
| Variable | Description |
|---|---|
QYRA_CSP_REPORT_ONLY | Enables Content Security Policy (CSP) reporting only mode. This is recommended to be set to false in production. (default=true) |
QYRA_CSP_ALLOWED_DOMAINS | List of domains that are allowed to load resources from. Values must be separated by commas. |
QYRA_CSP_REPORT_URI | URI to send CSP violation reports to. |
QYRA_CORS_ENABLED | Enables Cross-Origin Resource Sharing (CORS). Set to false to disable CORS for the instance. (default=true) |
QYRA_CORS_ALLOWED_DOMAINS | Instance-level list of domains that are allowed to make cross-origin requests. Values must be separated by commas. |
Analytics & Event Tracking
RudderStack product telemetry is enabled by default on self-hosted deployments and points at https://analytics.qyraflow.com. For the full payload, disable and redirect options, and the security-review checklist, see Data flows and telemetry.
| Variable | Description |
|---|---|
RUDDERSTACK_WRITE_KEY | RudderStack key used to track events (by default Qyra's key is used). See redirect telemetry to your own RudderStack. |
RUDDERSTACK_DATA_PLANE_URL | RudderStack data plane URL to which events are tracked (by default Qyra's data plane is used) |
RUDDERSTACK_ANALYTICS_DISABLED | Set to true to stop the backend and browser from sending any RudderStack events. Takes precedence over RUDDERSTACK_WRITE_KEY and RUDDERSTACK_DATA_PLANE_URL. See disable outbound telemetry. |
AI Analyst
Enterprise-only. For setup steps (which provider to pick, how to point at an LLM gateway, how to enable verified answers), see AI agents. The tables below are the exhaustive variable reference.
| Variable | Description |
|---|---|
AI_COPILOT_ENABLED | Enables/Disables AI Analyst functionality (default=false) |
ASK_AI_BUTTON_ENABLED | Enables the "Ask AI" button in the interface for direct access to AI agents, when disabled agents can be acessed from /ai-agents route (default=false) |
AI_EMBEDDING_ENABLED | Enables AI embedding functionality for verified answers similarity matching (default=false) |
AI_DEFAULT_PROVIDER | Default AI provider to use (openai, azure, anthropic, openrouter, bedrock) (default=openai) |
AI_DEFAULT_EMBEDDING_PROVIDER | Default AI provider for embeddings (openai, bedrock, azure) (default=openai) |
AI_COPILOT_DEBUG_LOGGING_ENABLED | Enables debug logging for AI Copilot (default=false) |
AI_COPILOT_TELEMETRY_ENABLED | Enables telemetry for AI Copilot (default=false) |
AI_COPILOT_THREAD_DUMP_ENABLED | Enables the AI thread debug dump download action for organization AI admins (default=false) |
AI_COPILOT_REQUIRES_FEATURE_FLAG | Requires a feature flag to use AI Copilot (default=false) |
AI_COPILOT_MAX_QUERY_LIMIT | Maximum number of rows returned in AI-generated queries (default=500) |
AI_COPILOT_RUN_SQL_MAX_LIMIT | Maximum number of rows the AI Analyst run_sql tool can return. Falls back to AI_COPILOT_MAX_QUERY_LIMIT, then to 1000. |
AI_VERIFIED_ANSWER_SIMILARITY_THRESHOLD | Similarity threshold (0-1) for verified answer matching (default=0.6) |
AI_COPILOT_ALLOWED_PROJECT_UUID | Comma-separated list of project UUIDs allowed to use AI Copilot. When set, AI Copilot is disabled for all other projects. |
AI_ANALYTICS_PROJECT_UUID | UUID of the project used to render the internal AI usage analytics dashboard. |
AI_ANALYTICS_DASHBOARD_UUID | UUID of the dashboard used to render the internal AI usage analytics dashboard. |
AI_AGENT_MCP_ALLOW_PRIVATE_ADDRESSES | When true, allows AI agent MCP server URLs to point at private/internal network addresses (e.g. 127.0.0.1, RFC1918 ranges). Useful for self-hosted deployments where MCP servers run inside the same private network. Leave unset or false to enforce public-address-only validation (default=false). |
The AI Analyst supports multiple providers. Provide credentials for the provider set in AI_DEFAULT_PROVIDER. OpenAI and Anthropic are the most tested. For which provider to pick and end-to-end setup, see AI agents.
OpenAI Configuration
| Variable | Description |
|---|---|
OPENAI_API_KEY | (Required when using OpenAI) API key for OpenAI |
OPENAI_MODEL_NAME | OpenAI model name to use (default=gpt-5.2) |
OPENAI_EMBEDDING_MODEL | OpenAI embedding model for verified answers (default=text-embedding-3-small) |
OPENAI_BASE_URL | Optional base URL for OpenAI compatible API |
OPENAI_AVAILABLE_MODELS | Comma-separated list of models available in the model picker (default=All supported models) |
OPENAI_ZERO_DATA_RETENTION | Set to true if your OpenAI account or LLM gateway enforces Zero Data Retention (ZDR). (default=false) |
OPENAI_CUSTOM_HEADERS | JSON object of extra HTTP headers to send with every OpenAI request |
OPENAI_SUPPORTS_STREAMING | Set to false if the endpoint behind OPENAI_BASE_URL (e.g. an LLM gateway) doesn't support streaming (SSE) completions — Qyra will make non-streaming requests instead (default=true) |
Anthropic Configuration
| Variable | Description |
|---|---|
ANTHROPIC_API_KEY | (Required when using Anthropic) API key for Anthropic |
ANTHROPIC_MODEL_NAME | Anthropic model name to use (default=claude-sonnet-4-5) |
ANTHROPIC_BASE_URL | Optional HTTP(S) base URL for an Anthropic-compatible gateway. Configure the base before /v1; the configured ANTHROPIC_API_KEY is sent as a bearer token. |
ANTHROPIC_AVAILABLE_MODELS | Comma-separated list of models available in the model picker (default=All supported models) |
ANTHROPIC_CUSTOM_HEADERS | JSON object of extra HTTP headers to send with every Anthropic request |
ANTHROPIC_SUPPORTS_STREAMING | Set to false if your Anthropic endpoint or gateway doesn't support streaming (SSE) completions — Qyra will make non-streaming requests instead (default=true) |
Azure AI Configuration
| Variable | Description |
|---|---|
AZURE_AI_API_KEY | (Required when using Azure AI) API key for Azure AI |
AZURE_AI_ENDPOINT | (Required when using Azure AI) Endpoint for Azure AI |
AZURE_AI_API_VERSION | (Required when using Azure AI) API version for Azure AI |
AZURE_AI_DEPLOYMENT_NAME | (Required when using Azure AI) Deployment name for Azure AI |
AZURE_EMBEDDING_DEPLOYMENT_NAME | Deployment name for Azure embedding model (default=text-embedding-3-small) |
AZURE_USE_DEPLOYMENT_BASED_URLS | Use deployment-based URLs for Azure OpenAI API calls (default=true) |
AZURE_AI_DEPLOYMENT_SUPPORTS_REASONING | Set to true if your Azure deployment exposes a reasoning-capable model (e.g. o3). Enables reasoning-mode prompts. (default=false) |
AZURE_AI_CUSTOM_HEADERS | JSON object of extra HTTP headers to send with every Azure AI request |
AZURE_AI_SUPPORTS_STREAMING | Set to false if your Azure AI endpoint or gateway doesn't support streaming (SSE) completions — Qyra will make non-streaming requests instead (default=true) |
OpenRouter Configuration
| Variable | Description |
|---|---|
OPENROUTER_API_KEY | (Required when using OpenRouter) API key for OpenRouter |
OPENROUTER_MODEL_NAME | OpenRouter model name to use (default=openai/gpt-4.1-2025-04-14) |
OPENROUTER_SORT_ORDER | Provider sorting method (price, throughput, latency) (default=latency) |
OPENROUTER_ALLOWED_PROVIDERS | Comma-separated list of allowed providers (anthropic, openai, google) (default=openai) |
OPENROUTER_CUSTOM_HEADERS | JSON object of extra HTTP headers to send with every OpenRouter request |
OPENROUTER_SUPPORTS_STREAMING | Set to false if your OpenRouter endpoint or gateway doesn't support streaming (SSE) completions — Qyra will make non-streaming requests instead (default=true) |
AWS Bedrock Configuration
| Variable | Description |
|---|---|
BEDROCK_API_KEY | (Required if not using IAM credentials) API key for Bedrock (alternative to IAM credentials) |
BEDROCK_ACCESS_KEY_ID | (Required if not using API key) AWS access key ID for Bedrock |
BEDROCK_SECRET_ACCESS_KEY | (Required if using access key ID) AWS secret access key for Bedrock |
BEDROCK_SESSION_TOKEN | AWS session token (for temporary credentials) |
BEDROCK_USE_DEFAULT_CREDENTIALS | Set to true to use the standard AWS credential chain instead of an API key or static credentials. |
BEDROCK_REGION | (Required) AWS region for Bedrock |
BEDROCK_MODEL_NAME | Bedrock model name to use (default=claude-sonnet-4-5) |
BEDROCK_EMBEDDING_MODEL | Bedrock embedding model for verified answers (default=cohere.embed-english-v3) |
BEDROCK_BASE_URL | Optional HTTP(S) base URL for a Bedrock-compatible gateway. Routes backend Bedrock calls and Bedrock-backed Data app coding agents through the gateway. |
CLAUDE_CODE_SKIP_BEDROCK_AUTH | Set to true or 1 to omit AWS authentication from Claude Code when BEDROCK_BASE_URL points to a gateway that performs upstream authentication. The backend still requires a supported Bedrock credential mode. |
BEDROCK_AVAILABLE_MODELS | Comma-separated list of models available in the model picker (default=All supported models) |
BEDROCK_INFERENCE_PROFILE_PREFIX | Optional prefix prepended to Bedrock model IDs to target a cross-region inference profile (e.g. us, eu). Overrides the default region-based prefix derived from BEDROCK_REGION. |
BEDROCK_CUSTOM_HEADERS | JSON object of extra HTTP headers to send with every Bedrock request |
BEDROCK_SUPPORTS_STREAMING | Set to false if your Bedrock endpoint or gateway doesn't support streaming (SSE) completions — Qyra will make non-streaming requests instead (default=true) |
Supported Models
OpenAI: gpt-5.1, gpt-5.2 (default)
Anthropic: claude-sonnet-4-5, claude-haiku-4-5, claude-sonnet-4
AWS Bedrock: claude-sonnet-4-5, claude-haiku-4-5, claude-sonnet-4
Exact model snapshots are automatically assigned (e.g., gpt-5.1 → gpt-5.1-2025-11-13). For Bedrock, a region prefix is added on top of that based on BEDROCK_REGION (e.g., claude-sonnet-4-5 → us.anthropic.claude-sonnet-4-5-20250929-v1:0).
Slack Integration
These variables enable you to configure the Slack integration.
| Variable | Description |
|---|---|
SLACK_SIGNING_SECRET | Required for Slack integration |
SLACK_CLIENT_ID | Required for Slack integration |
SLACK_CLIENT_SECRET | Required for Slack integration |
SLACK_STATE_SECRET | Required for Slack integration (default=slack-state-secret) |
SLACK_APP_TOKEN | App token for Slack |
SLACK_PORT | Port for Slack integration (default=4351) |
SLACK_SOCKET_MODE | Enable socket mode for Slack (default=false) |
SLACK_CHANNELS_CACHED_TIME | Time in milliseconds to cache Slack channels (default=600000, 10 minutes) |
SLACK_SUPPORT_URL | URL for Slack support |
SLACK_MULTI_AGENT_CHANNEL_ENABLED | Enables multi-agent Slack channels for the whole instance (default=false) |
SLACK_LINK_SHARE_IMAGE_PREVIEW_ENABLED | Enables image previews when Qyra links are unfurled in Slack. (default=true) |
dbt
Configure how Qyra runs the dbt subprocess during project compilation.
| Variable | Description |
|---|---|
ALLOW_DBT_COMMANDS_ACCESS_TO_ENV_VARS | Comma-separated list of environment variable names from the Qyra server's environment to pass through to the dbt subprocess. Use this when your dbt project reads values with env_var() (for example in macros) that you want to source from the host machine instead of setting per-project in Qyra. By default the dbt subprocess does not inherit the server's environment. Only the names on this allowlist are forwarded. |
GitHub Integration
These variables enable you to configure Github integrations
| Variable | Description |
|---|---|
GITHUB_PRIVATE_KEY | (Required) GitHub private key for GitHub App authentication |
GITHUB_APP_ID | (Required) GitHub Application ID |
GITHUB_CLIENT_ID | (Required) GitHub OAuth client ID |
GITHUB_CLIENT_SECRET | (Required) GitHub OAuth client secret |
GITHUB_APP_NAME | (Required) Name of the GitHub App |
GITHUB_REDIRECT_DOMAIN | Domain for GitHub OAuth redirection |
GITHUB_WEBHOOK_SECRET | Secret used to verify incoming GitHub webhook signatures (e.g. for dbt PR previews) |
GitLab Integration
These variables enable you to configure the GitLab integration for dbt project sync.
| Variable | Description |
|---|---|
GITLAB_CLIENT_ID | OAuth client ID for the GitLab application |
GITLAB_CLIENT_SECRET | OAuth client secret for the GitLab application |
GITLAB_REDIRECT_DOMAIN | Domain used to build the GitLab OAuth callback URL. Defaults to the subdomain of SITE_URL. |
Microsoft Teams Integration
These variables enable you to configure Microsoft Teams integration.
| Variable | Description |
|---|---|
MICROSOFT_TEAMS_ENABLED | Enables Microsoft Teams integration (default=false) |
Google Cloud Platform
These variables enable you to configure Google Cloud Platform integration.
| Variable | Description |
|---|---|
GOOGLE_CLOUD_PROJECT_ID | Google Cloud Platform project ID |
GOOGLE_DRIVE_API_KEY | Google Drive API key |
AUTH_GOOGLE_ENABLED | Enables Google authentication (default=false) |
AUTH_ENABLE_GCLOUD_ADC | Enables Google Cloud Application Default Credentials (default=false) |
AUTH_GOOGLE_INCLUDE_BIGQUERY_SCOPE | When true, bundles the BigQuery scope into the Google login flow so BigQuery SSO users complete a single consent screen instead of two (default=false) |
Embedding
Enterprise-only. For setup steps and how the allow-list of iframe origins works, see embedding.
| Variable | Description |
|---|---|
EMBEDDING_ENABLED | Enables embedding functionality (default=false) |
EMBED_ALLOW_ALL_DASHBOARDS_BY_DEFAULT | When creating new embeds, allow all dashboards by default (default=false) |
EMBED_ALLOW_ALL_CHARTS_BY_DEFAULT | When creating new embeds, allow all charts by default (default=false) |
QYRA_IFRAME_EMBEDDING_DOMAINS | List of domains that are allowed to embed Qyra in an iframe. Values must be separated by commas. |
EMBED_EVENT_SYSTEM_ENABLED | Enables the embed event system that lets host pages subscribe to embedded-dashboard events. (default=false) |
EMBED_EVENT_SYSTEM_POST_MESSAGE_ENABLED | When true, the embed event system also dispatches events via window.postMessage to the parent frame. (default=false) |
EMBED_EVENT_RATE_LIMIT_MAX_EVENTS | Maximum number of embed events per rate-limit window. (default=10) |
EMBED_EVENT_RATE_LIMIT_WINDOW_MS | Embed event rate-limit window in milliseconds. (default=1000) |
Custom roles
Enterprise-only. See custom roles for setup.
| Variable | Description |
|---|---|
CUSTOM_ROLES_ENABLED | Enables creation of custom organization roles with configurable permission scopes beyond the default Admin, Developer, Editor, and Viewer roles. (default=false) |
Service account
Enterprise-only. See service accounts for setup.
| Variable | Description |
|---|---|
SERVICE_ACCOUNT_ENABLED | Enables service account functionality (default=false) |
SCIM
Enterprise-only. See SCIM for setup, including the required AUTH_ENABLE_OIDC_TO_EMAIL_LINKING companion when combining SCIM with SSO.
| Variable | Description |
|---|---|
SCIM_ENABLED | Enables SCIM (System for Cross-domain Identity Management) (default=false) |
Sentry
These variables enable you to configure Sentry for error tracking.
| Variable | Description |
|---|---|
SENTRY_DSN | Sentry DSN for both frontend and backend |
SENTRY_BE_DSN | Sentry DSN for backend only |
SENTRY_FE_DSN | Sentry DSN for frontend only |
SENTRY_BE_SECURITY_REPORT_URI | URI for Sentry backend security reports |
SENTRY_TRACES_SAMPLE_RATE | Sample rate for Sentry traces (0.0 to 1.0) (default=0.1) |
SENTRY_PROFILES_SAMPLE_RATE | Sample rate for Sentry profiles (0.0 to 1.0) (default=0.2) |
SENTRY_ANR_ENABLED | Enables Sentry Application Not Responding detection (default=false) |
SENTRY_ANR_CAPTURE_STACKTRACE | Captures stacktrace for ANR events (default=false) |
SENTRY_ANR_TIMEOUT | Timeout in milliseconds for ANR detection |
Intercom & Pylon
These variables enable you to configure Intercom and Pylon for customer support and feedback.
| Variable | Description |
|---|---|
INTERCOM_APP_ID | Intercom application ID |
INTERCOM_APP_BASE | Base URL for Intercom API (default=https://api-iam.intercom.io) |
PYLON_APP_ID | Pylon application ID |
PYLON_IDENTITY_VERIFICATION_SECRET | Secret for verifying Pylon identities |
Kubernetes
These variables enable you to configure Kubernetes integration.
| Variable | Description |
|---|---|
K8S_NODE_NAME | Name of the Kubernetes node |
K8S_POD_NAME | Name of the Kubernetes pod |
K8S_POD_NAMESPACE | Namespace of the Kubernetes pod |
QYRA_CLOUD_INSTANCE | Identifier for Qyra cloud instance |
Organization appearance
These variables allow you to customize the default appearance settings for your Qyra instance's organizations. This color palette will be set for all organizations in your instance. You can't choose another one while these env vars are set.
| Variable | Description |
|---|---|
OVERRIDE_COLOR_PALETTE_NAME | Name of the default color palette |
OVERRIDE_COLOR_PALETTE_COLORS | Comma-separated list of hex color codes for the default color palette (must be 20 colors) |
Pre-aggregates
Enterprise-only. For setup steps and the required pre-aggregate worker deployment, see pre-aggregates.
| Variable | Description |
|---|---|
PRE_AGGREGATES_ENABLED | Enables pre-aggregate query routing. Requires QYRA_LICENSE_KEY. (default=false) |
PRE_AGGREGATES_PARQUET_ENABLED | Materialize pre-aggregates as Parquet files instead of in-memory tables. (default=false) |
PRE_AGGREGATE_DUCKDB_QUERY_MEMORY_LIMIT | DuckDB memory limit for pre-aggregate queries (e.g. 4GB). |
PRE_AGGREGATE_RESULTS_S3_BUCKET | S3 bucket for pre-aggregate Parquet storage. Required when configuring pre-aggregate result storage. |
PRE_AGGREGATE_RESULTS_S3_REGION | Region for the pre-aggregate S3 bucket. Required when configuring pre-aggregate result storage. |
PRE_AGGREGATE_RESULTS_S3_ACCESS_KEY | Access key for the pre-aggregate S3 bucket. |
PRE_AGGREGATE_RESULTS_S3_SECRET_KEY | Secret key for the pre-aggregate S3 bucket. |
Data apps runtime
Enterprise-only. Sandboxes execute through E2B. For setup steps (coding-agent choice, model provider, S3 bucket, sandbox provider), see data apps.
| Variable | Description |
|---|---|
APPS_RUNTIME_ENABLED | Enables the data apps runtime. (default=false) |
APPS_CODING_AGENT | Coding agent used to generate Data apps: claude (default) or codex. Codex uses OPENAI_API_KEY unless AI_DEFAULT_PROVIDER=bedrock. |
APP_RUNTIME_QYRA_ORIGIN | Origin the sandbox uses to call back into Qyra. Defaults to SITE_URL. |
APP_RUNTIME_CDN_ORIGIN | Origin where built app bundles are served from (CDN in front of APPS_S3_BUCKET). |
APP_RUNTIME_PREVIEW_ORIGIN | Origin used to render app previews (typically a separate subdomain to isolate cookies). |
APP_RUNTIME_CSP_ALLOWED_ORIGINS | Comma-separated list of extra origins to add to the data apps CSP allow-list. |
APPS_S3_BUCKET | S3 bucket where built data app bundles are stored. Defaults to the main S3_BUCKET. |
APPS_S3_REGION | Region for the data apps S3 bucket. Defaults to S3_REGION. |
APPS_S3_ACCESS_KEY | Access key for the data apps S3 bucket. Defaults to S3_ACCESS_KEY. |
APPS_S3_SECRET_KEY | Secret key for the data apps S3 bucket. Defaults to S3_SECRET_KEY. |
E2B_API_KEY | API key for the E2B sandbox provider. |
E2B_TEMPLATE_NAME | E2B template used for general data app sandboxes. Defaults to Qyra's public template (qyra/qyra-data-app) so self-hosters work out of the box. Override to use your own template. |
E2B_TEMPLATE_TAG | E2B template tag. Defaults to the running Qyra version so the template matches the release. |
E2B_AI_WRITEBACK_TEMPLATE_NAME | E2B template used for AI writeback sandboxes. (default=qyra-ai-writeback) |
E2B_AI_WRITEBACK_TEMPLATE_TAG | E2B AI writeback template tag. Defaults to the running Qyra version. |
APPS_CODING_AGENT=codex supports GPT-5.6 Sol, Terra, and Luna, with Terra as the default. When AI_DEFAULT_PROVIDER=bedrock, Qyra runs those models through Amazon Bedrock instead of OpenAI directly. AI_DEFAULT_PROVIDER also controls AI Analyst; APPS_CODING_AGENT affects only Data apps.
Managed agent
Enterprise-only. Runs scheduled AI agent tasks on a cron. See the managed agent section on the AI agents setup page for context.
| Variable | Description |
|---|---|
MANAGED_AGENT_ANTHROPIC_API_KEY | Anthropic API key used by the managed agent. Falls back to ANTHROPIC_API_KEY only when ANTHROPIC_BASE_URL is not set; a dedicated key is required alongside an Anthropic gateway. |
MANAGED_AGENT_SKILL_IDS | Comma-separated list of skill IDs the managed agent is allowed to run. |
MANAGED_AGENT_SCHEDULE | Cron expression for the managed agent's recurring schedule. (default=0 0 * * *) |
MANAGED_AGENT_SESSION_TIMEOUT_MS | Maximum session duration in milliseconds before a managed agent run is terminated. (default=600000, 10 minutes) |
MCP
Enterprise-only. For setup steps, connecting AI assistants, and network requirements, see MCP.
| Variable | Description |
|---|---|
MCP_ENABLED | Enables the Qyra Model Context Protocol (MCP) server. Requires QYRA_LICENSE_KEY. (default=false) |
MCP_RUN_SQL_MAX_LIMIT | Maximum number of rows the MCP run_sql tool can return. Falls back to AI_COPILOT_MAX_QUERY_LIMIT, then 1000. |
Metrics SQL API
Postgres wire protocol endpoint for the semantic layer. See Metrics SQL API.
| Variable | Description |
|---|---|
PGWIRE_PORT | Port the Metrics SQL API server listens on, e.g. 5432. The server only starts when this is set. Requires QYRA_LICENSE_KEY. Disabled when unset (default). |
PGWIRE_SSL_CERT_PATH | Path to the PEM server certificate (leaf first, then chain) for the Metrics SQL API. Required when PGWIRE_PORT is set, unless TLS is explicitly disabled. The file is watched, so certificate renewals apply without a restart. |
PGWIRE_SSL_KEY_PATH | Path to the PEM private key for the Metrics SQL API certificate. Required alongside PGWIRE_SSL_CERT_PATH. |
PGWIRE_SSL_MODE | require (default) or disabled. With require, the server terminates TLS itself and rejects plaintext connections before any credentials are exchanged; Qyra refuses to start if PGWIRE_PORT is set without a certificate. Set disabled only on fully trusted networks or behind a Postgres-aware TLS-terminating proxy — tokens are sent in plaintext. |
NATS worker
Optional NATS-backed query workers. When enabled, Qyra routes query execution to dedicated NATS worker pods instead of running queries on the main API server. Enable at least one warehouse worker to process the routed queries.
| Variable | Description |
|---|---|
NATS_ENABLED | Routes query execution through NATS worker pods. Requires at least one warehouse worker to process the queries. (default=false) |
NATS_URL | NATS server connection URL. Required when NATS_ENABLED=true. |
NATS_WORKER_PORT | Port the NATS worker process listens on for healthchecks. |
Initialize instance Enterprise
When a new Qyra instance is created, and there are no orgs and projects. You can initialize a new org and project using ENV variables to simplify the deployment process. See the pricing page for what each plan includes. Only Databricks project types and GitHub dbt configuration are supported.
Initialization is skipped once an organization and project exist — on subsequent restarts, only the update instance call is made.
If you have multiple organizations or projects, the update call fails and the instance will not start. Remove the variables listed in Update instance to restart safely.
| Variable | Description |
|---|---|
LD_SETUP_ADMIN_NAME | Name of the admin user for initial setup (default=Admin User) |
LD_SETUP_ADMIN_EMAIL | (Required) Email of the admin user for initial setup |
LD_SETUP_ORGANIZATION_UUID | UUID of the organization to configure. Use when multiple organizations exist to target a specific one instead of requiring exactly one to exist. |
LD_SETUP_ORGANIZATION_EMAIL_DOMAIN | Comma-separated list of email domains for organization whitelisting |
LD_SETUP_ORGANIZATION_DEFAULT_ROLE | Default role for new organization members (default=viewer) |
LD_SETUP_ORGANIZATION_NAME | (Required) Name of the organization |
LD_SETUP_ADMIN_API_KEY | (Required) API key for the admin user, must start with ldpat_ prefix |
LD_SETUP_API_KEY_EXPIRATION | Number of days until API key expires (0 for no expiration) (default=30) |
LD_SETUP_SERVICE_ACCOUNT_TOKEN | (Required) A pre-set token for the service account, must start with ldsvc_ prefix |
LD_SETUP_SERVICE_ACCOUNT_EXPIRATION | Number of days until service account token expires (0 for no expiration) (default=30) |
LD_SETUP_PROJECT_UUID | UUID of the project to configure. Use when multiple projects exist to target a specific one instead of requiring exactly one to exist. |
LD_SETUP_PROJECT_NAME | (Required) Name of the project |
LD_SETUP_PROJECT_CATALOG | Catalog name for Databricks project |
LD_SETUP_PROJECT_SCHEMA | (Required) Schema/database name for the project |
LD_SETUP_PROJECT_HOST | (Required) Hostname for the Databricks server |
LD_SETUP_PROJECT_HTTP_PATH | (Required) HTTP path for Databricks connection |
LD_SETUP_PROJECT_PAT | (Required) Personal access token for Databricks |
LD_SETUP_START_OF_WEEK | Day to use as start of week (default=SUNDAY) |
LD_SETUP_PROJECT_COMPUTE | JSON string with Databricks compute configuration like {"name": "string", "httpPath": "string"} |
LD_SETUP_DBT_VERSION | Version of dbt to use (eg: v1.8) (default=latest) |
LD_SETUP_GITHUB_PAT | (Required) GitHub personal access token |
LD_SETUP_GITHUB_REPOSITORY | (Required) GitHub repository for dbt project |
LD_SETUP_GITHUB_BRANCH | (Required) GitHub branch for dbt project |
LD_SETUP_GITHUB_PATH | Subdirectory path within GitHub repository (default=/) |
LD_SETUP_EMBED_SECRET | Embed secret to provision on the initial project (used to sign embed JWTs). |
LD_SETUP_EMBED_ALLOW_ALL_DASHBOARDS | When true, allows all dashboards in the project to be embedded by default. (default=false) |
In order to login as the admin user using SSO, you must enable the following ENV variable too:
AUTH_ENABLE_OIDC_TO_EMAIL_LINKING=trueThis will alow you to link your SSO account with the email provided without using an invitation code.
This email will be trusted, and any user with an OIDC account with that email will access the admin user.
Update instance
On server start, we will check the following variables, and update some configuration of the organization or project. If multiple organizations or projects exist, you must set LD_SETUP_ORGANIZATION_UUID and/or LD_SETUP_PROJECT_UUID to target a specific one.
Update instance is only available on Qyra Enterprise plans.
For more information on our plans, visit our pricing page.
| Variable | Description |
|---|---|
LD_SETUP_ADMIN_EMAIL | (Required if LD_SETUP_ADMIN_API_KEY is present) Email of the admin to update its Personal access token |
LD_SETUP_ADMIN_API_KEY | API key for the admin user, must start with ldpat_ prefix |
LD_SETUP_ORGANIZATION_UUID | UUID of the organization to update. Required when multiple organizations exist. |
LD_SETUP_ORGANIZATION_EMAIL_DOMAIN | Comma-separated list of email domains for organization whitelisting |
LD_SETUP_ORGANIZATION_DEFAULT_ROLE | Default role for new organization members (default=viewer) |
LD_SETUP_PROJECT_UUID | UUID of the project to update. Required when multiple projects exist. |
LD_SETUP_PROJECT_HTTP_PATH | HTTP path for Databricks connection |
LD_SETUP_PROJECT_PAT | Personal access token for Databricks |
LD_SETUP_DBT_VERSION | Version of dbt to use (eg: v1.8) (default=latest) |
LD_SETUP_GITHUB_PAT | GitHub personal access token |
LD_SETUP_SERVICE_ACCOUNT_TOKEN | A pre-set token for the service account, must start with ldsvc_ prefix |
LD_SETUP_USER_ATTRIBUTES | JSON array declaring user attributes and group-value mappings to reconcile on every deploy. |
LD_SETUP_GROUP_PROJECT_ACCESS | JSON array declaring group → project role assignments to reconcile on every deploy. |
Initialize multiple projects
Set LD_SETUP_PROJECTS to a JSON array to provision multiple projects at once. This is a drop-in replacement for the single-project LD_SETUP_PROJECT_* variables described in Initialize instance — when LD_SETUP_PROJECTS is set, the legacy LD_SETUP_PROJECT_* and LD_SETUP_GITHUB_* variables are ignored.
On every boot, Qyra matches each entry to an existing project by its name: new names are created, existing names are updated in place.
Multi-project setup supports Databricks project types and GitHub dbt configuration.
Project names are the primary key. Renaming an entry creates a new project rather than renaming the existing one — charts and dashboards will stay on the old project.
Required companion variables
The admin, organization, and API key variables from Initialize instance still apply. LD_SETUP_ADMIN_EMAIL is required — without it, LD_SETUP_PROJECTS is ignored.
Schema
LD_SETUP_PROJECTS must be a JSON array. Each entry has the following shape:
| Field | Required | Description |
|---|---|---|
name | Yes | Project name. Must be non-empty and unique within the array. |
warehouseConnection | Yes | Object with a valid type and the fields required by that warehouse (see below). |
dbtConnection | Yes | Object with a valid type and the fields required by that dbt connection (below). |
dbtVersion | No | Version of dbt to use (eg: v1.8). Defaults to latest. |
embed | No | Embed config: { "secret": "...", "allowAllDashboards": true }. |
Databricks warehouse fields
| Field | Required | Description |
|---|---|---|
type | Yes | Must be "databricks". |
serverHostName | Yes | Databricks host, no protocol. Example: dbc-xxxx.cloud.databricks.com. |
httpPath | Yes | SQL warehouse HTTP path, e.g. /sql/1.0/warehouses/abc123. |
database | Yes | Schema name. (Historical naming — this is the dbt schema, not the Unity Catalog.) |
catalog | No | Unity Catalog name. |
authenticationType | No | One of personal_access_token (default), oauth_m2m, oauth_u2m. |
personalAccessToken | If authenticationType=personal_access_token | Databricks PAT (starts with dapi_). |
oauthClientId | If authenticationType=oauth_m2m | Databricks Service Principal client ID (a UUID). |
oauthClientSecret | If authenticationType=oauth_m2m | Databricks Service Principal client secret. |
compute | No | Array of extra SQL warehouses: [{ "name": "...", "httpPath": "..." }]. |
startOfWeek | No | Day to use as start of week (default=SUNDAY). |
dataTimezone | No | Project-level timezone override. |
GitHub dbt connection fields
| Field | Required | Description |
|---|---|---|
type | Yes | Must be "github". |
authorization_method | Yes | Use "personal_access_token". |
personal_access_token | Yes | GitHub personal access token. |
repository | Yes | Repository in org/repo format. |
branch | Yes | Branch name to pull the dbt project from. |
project_sub_path | Yes | Subdirectory path within the repo (use / for the root). |
selector | No | dbt selector name to limit which models are compiled. |
Example
export LD_SETUP_ADMIN_EMAIL="admin@example.com"
export LD_SETUP_PROJECTS='[
{
"name": "Sample Project Alpha",
"warehouseConnection": {
"type": "databricks",
"serverHostName": "alpha.cloud.databricks.com",
"httpPath": "/sql/1.0/warehouses/abc123",
"database": "alpha_db",
"personalAccessToken": "dapi_alpha_fake_token"
},
"dbtConnection": {
"type": "github",
"authorization_method": "personal_access_token",
"personal_access_token": "ghp_fake_alpha_token",
"repository": "myorg/alpha-repo",
"branch": "main",
"project_sub_path": "/"
}
},
{
"name": "Sample Project Beta",
"warehouseConnection": {
"type": "databricks",
"serverHostName": "beta.cloud.databricks.com",
"httpPath": "/sql/1.0/warehouses/def456",
"database": "beta_db",
"personalAccessToken": "dapi_beta_fake_token"
},
"dbtConnection": {
"type": "github",
"authorization_method": "personal_access_token",
"personal_access_token": "ghp_fake_beta_token",
"repository": "myorg/beta-repo",
"branch": "main",
"project_sub_path": "/"
}
}
]'Quote the whole value in single quotes in your shell so that $, backticks, and double quotes inside the JSON are not re-interpreted. When injecting via a secret manager or Kubernetes Secret, no escaping is needed — just paste the JSON as-is.
Databricks M2M OAuth example
Use a Databricks Service Principal when you want non-interactive, machine-to-machine authentication instead of a PAT. Qyra exchanges the client_id + client_secret for an access token automatically on the first compile and refreshes it as needed — no user interaction is required.
export LD_SETUP_ADMIN_EMAIL="admin@example.com"
export LD_SETUP_PROJECTS='[
{
"name": "Sales (Databricks M2M)",
"warehouseConnection": {
"type": "databricks",
"serverHostName": "dbc-xxxx.cloud.databricks.com",
"httpPath": "/sql/1.0/warehouses/abc123",
"catalog": "qyra_prod",
"database": "sales",
"authenticationType": "oauth_m2m",
"oauthClientId": "00000000-0000-0000-0000-000000000000",
"oauthClientSecret": "dose...secret..."
},
"dbtConnection": {
"type": "github",
"authorization_method": "personal_access_token",
"personal_access_token": "ghp_...",
"repository": "myorg/dbt-sales",
"branch": "main",
"project_sub_path": "/"
}
}
]'If you already have an M2M Service Principal configured for dbt, the field names are different. Map your dbt profile fields to Qyra's warehouseConnection like this:
profiles.yml (dbt) | LD_SETUP_PROJECTS (Qyra) |
|---|---|
host | serverHostName |
http_path | httpPath |
catalog | catalog |
schema | database |
auth_type: oauth | authenticationType: "oauth_m2m" |
client_id | oauthClientId |
client_secret | oauthClientSecret |
M2M is non-interactive by design — Qyra uses the OAuth client-credentials grant. No browser popup, no per-user sign-in. The Service Principal needs CAN USE on the SQL warehouse and the appropriate SELECT/USE CATALOG/USE SCHEMA grants on your data.
Validation
LD_SETUP_PROJECTS is parsed and validated at boot. Qyra will fail to start with a descriptive error if any of the following are true:
| Error | Cause |
|---|---|
Failed to parse LD_SETUP_PROJECTS | The value is not valid JSON. Check your shell quoting. |
Invalid LD_SETUP_PROJECTS: expected array | The top-level JSON is not an array. |
name: Project name cannot be empty | An entry has a missing or empty name. |
warehouseConnection: Required / dbtConnection: Required | An entry is missing one of the two connection blocks. |
Invalid warehouse type | warehouseConnection.type is not a supported warehouse. |
Invalid dbt connection type | dbtConnection.type is not a supported dbt connection. |
Duplicate project name "X" in LD_SETUP_PROJECTS | Two entries share the same name. |
Multiple projects found with name "X" | Two pre-existing projects in the DB share the same name — rename one in the UI before redeploying. |
Credentials in LD_SETUP_PROJECTS are the source of truth on every boot. If an admin rotates a PAT or OAuth secret in the UI, the next restart will overwrite it with the value from this variable. Keep the variable in sync with your secret manager, or omit a project from the array once you no longer want it managed via env.
Migrating from LD_SETUP_PROJECT_*
LD_SETUP_PROJECTS replaces the single-project LD_SETUP_PROJECT_NAME, LD_SETUP_PROJECT_HOST, LD_SETUP_PROJECT_HTTP_PATH, LD_SETUP_PROJECT_PAT, LD_SETUP_PROJECT_SCHEMA, LD_SETUP_PROJECT_CATALOG, LD_SETUP_PROJECT_COMPUTE, LD_SETUP_GITHUB_*, and LD_SETUP_DBT_VERSION variables. When both are set, LD_SETUP_PROJECTS takes precedence and the legacy variables are ignored.
To migrate:
- Move your existing project config into a JSON object (use the existing project's exact
nameso it is updated in place rather than recreated). - Set
LD_SETUP_PROJECTSto a single-element array containing that object. - Remove the legacy
LD_SETUP_PROJECT_*andLD_SETUP_GITHUB_*variables from your deployment.
Declare user attributes
Set LD_SETUP_USER_ATTRIBUTES to a JSON array to declare user attributes and their group-value mappings as instance config. Qyra reconciles the array on every deploy, so you no longer need a manual post-deploy API or CLI step to (re)apply attributes after a release.
User attribute setup is only available on Qyra Enterprise plans.
For more information on our plans, visit our pricing page.
On every boot, Qyra matches each entry to an existing user attribute by its name: new names are created, existing names are updated in place. Attributes that are not present in the array are left untouched — this reconcile is non-destructive and never deletes attributes you created in the UI.
Schema
Each entry in the array has the following shape:
| Field | Required | Description |
|---|---|---|
name | Yes | User attribute name. Must be non-empty and unique within the array. |
description | No | Human-readable description shown in Organization Settings → User Attributes. |
attributeDefault | No | Default value(s) applied to users who don't have an explicit value. Accepts an array of strings (e.g. ["US", "CA"]), a single string (normalized to a one-element array), or null for no default. Defaults to null. |
groups | No | Array of group mappings. Each mapping is {"{"{"}"} "group": "<group name>", "values": ["<string>", ...] {"}"} and assigns those values to every member of a group. The legacy single-value form {"{"{"}"} "group": "...", "value": "<string>" {"}"} is still accepted but deprecated. Defaults to []. |
Example
LD_SETUP_USER_ATTRIBUTES='[
{
"name": "region",
"description": "sales region access",
"attributeDefault": ["US", "CA"],
"groups": [
{ "group": "EMEA Analysts", "values": ["UK", "DE"] }
]
}
]'Group resolution
Group bindings are resolved by group name because group UUIDs aren't known at deploy time — groups provisioned via SCIM are created by your IdP, not by Qyra.
If a group name in groups doesn't match any existing group at the time the deploy runs (for example, because SCIM hasn't synced it yet), Qyra logs a warning and skips that mapping rather than failing the deploy. The mapping is retried on the next deploy, so once the group exists the binding reconciles automatically.
Per-user mappings
LD_SETUP_USER_ATTRIBUTES only supports group-based mappings. Per-user (by-email) values still need to be assigned through the UI or API.
Declare group → project access
Set LD_SETUP_GROUP_PROJECT_ACCESS to a JSON array to declare group → project role assignments as instance config. Qyra reconciles the array on every deploy, so you no longer need to re-apply group access through the UI or API after each release. This is the project-access equivalent of LD_SETUP_USER_ATTRIBUTES.
Group project access setup is only available on Qyra Enterprise plans and uses groups and (optionally) custom roles, which are Enterprise features.
For more information on our plans, visit our pricing page.
On every boot, Qyra matches each entry to a group and project, then either creates the access, updates it if the role differs, or leaves it untouched when it already matches. Group accesses that are not present in the array are left untouched — this reconcile is non-destructive and never removes access you assigned in the UI.
This is especially useful for instances that provision groups via SCIM: SCIM group UUIDs aren't known at deploy time, so this lets you declare role mappings by group name once and have them applied automatically as groups sync from your IdP.
Schema
Each entry in the array has the following shape:
| Field | Required | Description |
|---|---|---|
groupName | Yes | Name of the group to grant access to. Resolved by name so it is compatible with SCIM-synced groups. |
projectName | One of projectName/projectUuid | Name of the project to grant access to. |
projectUuid | One of projectName/projectUuid | UUID of the project to grant access to. Takes precedence if both projectName and projectUuid are provided. |
role | Yes | A system role (viewer, interactive_viewer, editor, developer, or admin) or the name of a custom role. |
Example
LD_SETUP_GROUP_PROJECT_ACCESS='[
{
"groupName": "Core Data Developer",
"projectName": "Production",
"role": "developer"
},
{
"groupName": "Data Analyst",
"projectUuid": "abc-123",
"role": "PII Analyst"
}
]'Group, project, and role resolution
- Groups are resolved by
groupNamebecause group UUIDs aren't known at deploy time when groups are provisioned via SCIM. - Projects are resolved by
projectUuidwhen set, otherwise byprojectName. - Roles are resolved as a system role first; if the value doesn't match a system role, Qyra looks up a custom role with that name.
If a group, project, or custom role can't be resolved at the time the deploy runs (for example, because SCIM hasn't synced the group yet), Qyra logs a warning and skips that entry rather than failing the deploy. The entry is retried on the next deploy, so once the group, project, or role exists the access reconciles automatically.
Malformed JSON or entries that fail schema validation (e.g. missing groupName, or neither projectName nor projectUuid) throw at boot time so configuration errors surface before the instance starts.