Deployment: Invicti Platform on-premises
This is part 5 of 10 in the Helm installation series.
Previous: Pre-installation checklist | Next: Post-installation
Installation
This document explains how to deploy Invicti Platform on-premises using Helm.
If your cluster already has KEDA installed, this chart can use that existing KEDA installation.
To avoid deploying a second KEDA instance, disable the chart-managed KEDA component:
- In
values.yaml, setglobal.keda.enabled: false. - Or pass
--set global.keda.enabled=falsein your Helm install or upgrade command.
Before starting the installation, review the following documents to ensure your environment meets all requirements and that you have access to your Invicti license credentials:
Step 1: Registry authentication
Authenticate to the registry with the following command:
helm registry login platform-registry.invicti.com --username <your email address>
- Replace
<your email address>with your Invicti account email. - When prompted for a password, enter your valid Invicti Platform license key.
Invicti Platform is deployed using Helm, with charts distributed through the private registry at platform-registry.invicti.com. Access to this registry requires authentication.
The platform-registry.invicti.com registry follows the OCI standard and does not include a traditional Helm chart index. Charts must be pulled directly using OCI URLs.
Step 2: The values.yaml configuration options
Don't run any commands at this stage. This section focuses only on reviewing the configuration options and preparing your values.yaml file. Read through all configuration options in this section before creating your file.
After reviewing all sections, create your own values.yaml file and replace the placeholder values with your actual configuration. These configuration examples are provided in the next step:
The values.yaml file contains all the settings needed to deploy Invicti Platform. You'll create this file from scratch using the guidance in this section.
Mandatory settings
Every deployment requires these three settings:
email_address- your Invicti Platform email.license_key- your valid Invicti Platform license key.web_application_host- domain name for the platform. For exampleinvicti.example.com. Don't include thehttps://protocol - use only the domain name.
global:
email_address: your-email@example.com
license_key: your-license-key-here
app:
web_application_host: invicti.example.com # Your platform domain (no https://)
Jira OAuth integration settings
To enable Jira OAuth 2.0 integration, add the following configuration to your values.yaml file:
global:
integrations:
jira:
oauth20_client_id: "your-client-id"
oauth20_client_secret: "your-client-secret"
Replace your-client-id and your-client-secret with your actual Jira OAuth credentials.
HTTP proxy settings
If outbound traffic in your environment must route through a proxy server, add the following settings to your values.yaml under global:
global:
proxy:
http_proxy: "http://your-proxy-address:port"
https_proxy: "http://your-proxy-address:port"
no_proxy: ".svc.cluster.local,svc.cluster.local,localhost,127.0.0.1"
Field descriptions:
global.proxy.http_proxy- proxy URL for HTTP trafficglobal.proxy.https_proxy- proxy URL for HTTPS trafficglobal.proxy.no_proxy- comma-separated list of addresses that should bypass the proxy. Always include.svc.cluster.local,svc.cluster.local,localhost,127.0.0.1to prevent internal cluster traffic from being routed through the proxy.
External database connections do not follow the HTTP proxy settings.
Depending on your environment, you may also need to configure proxy settings at the OS level on your Linux host. Consult your system administrator to confirm whether this is required.
To skip proxy: simply omit the entire proxy section from your values.yaml.
Email notifications (SMTP) settings
Invicti Platform can send email notifications such as DAST scan updates, user invitations, password resets, and other alerts. While the platform functions without SMTP, email-based features are going to be unavailable. It's strongly recommended to configure SMTP in production environments.
Without SMTP configuration, features that rely on email, such as scan alerts, user invitations, and password resets, won't function. For example, you won't be able to use the "Forgot password" feature upon logging in.
To configure SMTP, include these settings in your values.yaml:
global:
smtp:
engine: "smtp"
host: "smtp.example.com" # SMTP server hostname
port: 25 # SMTP server port
mail: "noreply@example.com" # Sender email address
displayname: "Invicti Security" # Display name for outgoing email
username: "smtp-username" # SMTP authentication username
password: "smtp-password" # SMTP authentication password
security: "ssl" # Use "ssl" or "non-ssl"
Field descriptions:
global.smtp.engine- email engine: smtp or aws_sesglobal.smtp.hostandglobal.smtp.port- SMTP server hostname and portglobal.smtp.mail- Sender email address used in the "From" fieldglobal.smtp.displayname- Display name for outgoing emailglobal.smtp.usernameandglobal.smtp.password- SMTP authentication credentialsglobal.smtp.security- Connection type (ssl or non-ssl)
For AWS SES: set engine: aws_ses. You can omit host and port, but the cluster must include IAM roles that allow email sending.
To skip email notifications: simply omit the entire smtp section from your values.yaml.
Use your own PostgreSQL database
By default, Invicti Platform includes a built-in PostgreSQL database. If you want to use your own external PostgreSQL server instead, configure the following settings in your values.yaml file.
PostgreSQL 16 or later is required.
global:
data:
databaseUser: "postgres"
databasePassword: ""
databaseHost: "postgresql"
databasePort: "5432"
databaseCert: ""
databaseSslEnabled: false
Field descriptions:
global.data.databaseUser- PostgreSQL usernameglobal.data.databasePassword- PostgreSQL passwordglobal.data.databaseHost- hostname or IP address of your PostgreSQL serverglobal.data.databasePort- PostgreSQL port (default:5432)global.data.databaseCert- TLS certificate for the database connection (leave empty if not using TLS)global.data.databaseSslEnabled- set totrueto enable SSL/TLS for the database connection
TLS connection settings
The platform is served over HTTPS and TLS is enabled by default with NGINX. You have three options for TLS certificates:
Option 1: Using command-line flags
Recommended for sensitive data.
Provide your certificate files using Helm's --set-file flags when running the install or upgrade command:
--set-file global.app.ssl.fullchain=/path/to/cert.pem \
--set-file global.app.ssl.privkey=/path/to/key.pem
You can update the certificate later via a Helm upgrade using the same flags.
Option 2: Embedding in values.yaml
Alternatively, you can embed the certificate and private key directly in your values.yaml file by adding this SSL block under global.app:
ssl:
fullchain: |
-----BEGIN CERTIFICATE-----
<YOUR-CERTIFICATE-CONTENT>
-----END CERTIFICATE-----
privkey: |
-----BEGIN PRIVATE KEY-----
<YOUR-PRIVATE-KEY-CONTENT>
-----END PRIVATE KEY-----
- Use
|to create a literal block so the certificates are preserved exactly. - Indentation matters: the certificate lines must be indented 8 spaces (aligned under
fullchain:). - Include the full PEM blocks with
-----BEGIN CERTIFICATE-----and-----END CERTIFICATE-----markers, and the same for the private key.
Option 3: Use auto-generated self-signed certificate
Not recommended for production.
If you don't provide a certificate using Option 1 or Option 2, the platform automatically generates a self-signed certificate.
Self-signed certificates cause browser security warnings. This option is suitable for testing but should be replaced with a valid certificate for production use. You can replace it later using Option 1 or Option 2. If you choose not to use HTTPS, some features in the platform may not function correctly. HTTPS is required for complete platform capability.
If you use both Option 1 and Option 2, the --set-file flags (Option 1) take precedence and override any certificate specified in values.yaml.
Step 3: Create your values.yaml file and examples
Now that you understand all the configuration options, create your values.yaml file with your actual settings. Use examples from step 2 to help and guide you.
If you want to review the technical details of the chart, you can extract and inspect an Invicti prepared chart locally.
Inspect Invicti Helm chart
First, download the chart using this command:
helm pull oci://platform-registry.invicti.com/invicti-platform-helm-charts/onpremises
Once an archive file like onpremises-NN.NNN.NNNNNNNNNN.tgz is downloaded, extract it using this command:
tar xf onpremises-*.tgz
Keep this file in a secure location as it contains sensitive credentials including your license key and potentially SMTP passwords.
The extracted chart directory includes values-resources-recommended.yaml, a values file with recommended CPU and memory requests and limits for the platform's pods. See Step 4 for how to apply it during installation.
If you've already installed Invicti Platform and are modifying your configuration,
remember to apply changes by running the helm upgrade command. See the
Update using Helm documentation.
Example: Minimal configuration
This is an example of the minimal configuration with the mandatory settings only.
global:
email_address: your-email@example.com
license_key: your-license-key-here
app:
web_application_host: invicti.example.com # Your platform domain (no https://)
Example: Minimal and SMTP configuration
This example includes the SMTP configuration.
global:
email_address: your-email@example.com
license_key: your-license-key-here
app:
web_application_host: invicti.example.com # Your platform domain (no https://)
smtp:
engine: "smtp"
host: "smtp.example.com"
port: 25
mail: "noreply@example.com"
displayname: "Invicti Security"
username: "smtp-username"
password: "smtp-password"
security: "ssl"
Example: Full configuration
This example includes proxy, SMTP, embedded TLS certificate, and external database settings.
global:
email_address: your-email@example.com
license_key: your-license-key-here
app:
web_application_host: invicti.example.com # Your platform domain (no https://)
ssl:
fullchain: |
-----BEGIN CERTIFICATE-----
<YOUR-CERTIFICATE-CONTENT>
-----END CERTIFICATE-----
privkey: |
-----BEGIN PRIVATE KEY-----
<YOUR-PRIVATE-KEY-CONTENT>
-----END PRIVATE KEY-----
proxy:
http_proxy: "http://your-proxy-address:port"
https_proxy: "http://your-proxy-address:port"
no_proxy: ".svc.cluster.local,svc.cluster.local,localhost,127.0.0.1"
smtp:
engine: "smtp"
host: "smtp.example.com"
port: 25
mail: "noreply@example.com"
displayname: "Invicti Security"
username: "smtp-username"
password: "smtp-password"
security: "ssl"
data:
databaseUser: "postgres"
databasePassword: "your-db-password"
databaseHost: "your-db-host"
databasePort: "5432"
databaseCert: ""
databaseSslEnabled: false
After the initial installation, any changes to your values.yaml file must be applied by running the helm upgrade command. This applies to all configuration updates, including changes to web_application_host, SMTP settings, TLS certificates, or adding integrations.
Step 4: Install the Helm chart
Now it's time to install the Helm chart you customized in the previous section.
When you don't specify a version, Helm installs the latest available chart. To install a specific version, add --version 25.xxx.xxxxxxxxxxxx to the command.
The chart ships with values-resources-recommended.yaml, a values file that sets resource limits for the platform's pods. Without these values, pods install without resource requests, which can cause uneven pod distribution and resource contention - especially when the platform shares a cluster with other workloads.
These recommended values are designed for a high-availability multi-instance deployment. They are not suitable for a single-instance installation.
Apply this file by passing it to helm install as an extra --values flag, before your own values.yaml so that any per-pod overrides you've set take precedence:
helm install invicti-platform oci://platform-registry.invicti.com/invicti-platform-helm-charts/onpremises \
--namespace invicti \
--create-namespace \
--values ./onpremises/values-resources-recommended.yaml \
--values ./values.yaml \
--wait \
--timeout 30m
Adjust the path to values-resources-recommended.yaml to match where you extracted the chart. To inspect or tune the recommended values before applying them, see Inspect Invicti Helm chart in Step 3.
:::
To install the chart, run:
helm install invicti-platform ./onpremises \
--namespace invicti \
--create-namespace \
--values ./values.yaml \
--wait \
--timeout 30m
- Release name: invicti-platform
- Namespace: invicti (created automatically if missing)
- Configuration:
values.yamlprovides the deployment settings
Add --debug for more detailed output. This can help troubleshoot installation issues.
After the installation completes, continue with the post-installation steps to finalize your setup.
Using a custom image registry
If you pull Invicti images into your own private registry, you can configure the image source using global.image.registryAddress in your values.yaml.
global:
image:
path: "infrastructure"
proxy_remote_url: "https://custom-registry.example.com"
registryAddress: "custom-registry.example.com"
Some third-party subcharts do not inherit global.image.registryAddress and instead expose their own registry setting under the subchart key (the exact field name varies per upstream chart - imageRegistry, image.registry, etc.).
The authoritative list lives in the parent chart's values.yaml: any top-level key with a nested global.imageRegistry, global.image.registry, or similar field needs a matching override in your own values.yaml. For example:
<subchart-name>:
global:
image:
registry: <your-custom-registry>
Without this, pods from those subcharts are going to fall back to their upstream registry and fail with ImagePullBackOff on air-gapped clusters.
Deploying on OpenShift
The chart runs on OpenShift when you enable OpenShift support. The suggested configuration is to use ROSA (Red Hat OpenShift Service on AWS). The chart ships an OpenShift values overlay (values-openshift.yaml, inside the extracted chart - see Inspect Invicti Helm chart) that adjusts the platform's workloads to comply with OpenShift's Security Context Constraints (SCCs). Pass it in addition to your own values.yaml on every install and upgrade against an OpenShift cluster.
Always include the OpenShift overlay when deploying on OpenShift. Without it, the install fails because pods configured for a standard Kubernetes environment are rejected by the cluster's SCCs.
Custom SCC for the DAST scanner
The DAST scanner needs the KILL capability at runtime, which OpenShift's built-in restricted-v2 SCC removes. KILL is used by the scanner's watchdog process to manage subprocess lifecycle. To keep the scanner working without loosening the cluster's defaults, the chart deploys a minimal custom SCC that grants only KILL, and only to the scanner's service account. This happens automatically when OpenShift support is enabled; you don't need to configure anything.
The CHOWN and FOWNER capabilities are used only when building the scanner image, not at runtime. The custom SCC does not request them.
Because an SCC is a cluster-scoped resource, creating it requires cluster-admin privileges. If the person deploying the platform is not a cluster admin, use the Two-phase installation below so a cluster admin can install the SCC (along with the other cluster-scoped prerequisites) in a separate release.
Two-phase installation
Some components require cluster-scoped resources (such as CRDs, cluster roles, and on OpenShift the DAST scanner SCC) that only a cluster admin can create. Everything else the platform installs is scoped to the application namespace.
When the person deploying the platform is not a cluster admin - a common setup on OpenShift - you can split the installation into two releases in the same namespace:
- Phase 1 (prerequisites) - run by a cluster admin. Installs the cluster-scoped prerequisites. If any of these prerequisites (for example, KEDA) is already installed on the cluster, disable it in
values-prereqs.yamlso this release doesn't try to manage it again. - Phase 2 (application) - run by a namespace-scoped user. Installs the platform itself, with none of the cluster-scoped resources.
Both phases use the same extracted chart directory and the ready-made values files that ship inside it (values-prereqs.yaml for phase 1 and values-application.yaml for phase 2), which split the components between the two releases so they never contend for the same resources. On OpenShift, also pass the OpenShift overlay in both phases. Run phase 1 to completion before starting phase 2, and target the same namespace in both.
Supplementary permissions for a non-admin user
Phase 2 creates a few resources in the namespace (namespaced RBAC and the platform's custom resources) that a standard namespace-scoped role may not cover. Before a non-admin user runs phase 2, a cluster admin should grant them their usual namespace role plus one supplementary Role for those resources. On OpenShift, for example, this means the built-in edit role plus the supplementary Role.
The supplementary Role is deliberately kept:
- Confined to the single application namespace - it is a namespaced
Role, with no cluster-scoped or cross-namespace effect. - Scoped to the minimum - only the resource types phase 2 actually creates, with just the verbs Helm needs to install and upgrade them.
Next steps
With the Helm chart installed, verify all components are running and then configure network access:
→ Continue to Post-installation
Complete Helm installation series
- Part 1: Architecture
- Part 2: Prerequisites
- Part 3: Kubernetes requirements
- Part 4: Pre-installation checklist
- Part 5: Installation ← You are here
- Part 6: Post-installation
- Part 7: Trustlist configuration
- Part 8: Troubleshooting
- Part 9: Uninstallation
- Part 10: Update
Need help?
Invicti Support team is ready to provide you with technical help. Go to Help Center