Evaluator Installation
Evaluating Plexicus takes one command on a fresh Ubuntu VM — you will run it in Step 1 below, after copying the three files from your delivery package onto the VM. The installer sets up everything — Kubernetes (k3s), ingress, TLS, all secrets with per-install random passwords, the full Plexicus platform with bundled infrastructure (MongoDB, Redis, MinIO, PostgreSQL, Temporal), and a verified admin account. About 15 minutes later you log in and run your first scan.
Validated end-to-end on Ubuntu 24.04 LTS (amd64) with charts 1.2.19, 1.2.20, and the current 1.2.36 release. For production deployments follow the Self-Hosted Installation guide instead.
What you need
| Item | Details |
|---|---|
| A fresh VM | Ubuntu 24.04 LTS (amd64), 4 vCPU / 7 GB RAM / 40 GB disk, root SSH, ports 80/443 reachable from your workstation. Ports 80/443/6443 must also be free on the VM itself (the installer checks this locally before installing); 6443 is the Kubernetes API and does not need to be, and should not be, internet-reachable. Any cloud VM works (Hetzner CPX31, AWS t3.xlarge, GCP e2-standard-4, …). |
| Registry key | keys.json — a service-account key for the Plexicus image registry. |
| License | license.jwt — your evaluation license. |
| Settings file | plexicus-eval.env — the AI key Plexicus provides for your evaluation, plus any settings pre-set for you (chart version, domain). Point the installer at it with PLEXICUS_ENV_FILE. |
| AI key | Provided by Plexicus in your delivery package, inside plexicus-eval.env — powers finding enrichment, AI remediation, and AI SAST scanning. To use your own account instead, set PLEXICUS_AI_KEY explicitly; an explicit value always overrides the file. |
| SCM apps | Not needed to install. No GitHub, GitLab or Bitbucket app is required: your first scan runs through the built-in Sandbox connector. Register one later, only when you want to scan your own repositories — see Connect your own SCM. |
Request your delivery package at
engineering@plexicus.ai — keys.json,
license.jwt and plexicus-eval.env arrive together in one reply, usually
within a business day.
Run the installer on the VM
Copy the three files from your Plexicus delivery package — keys.json,
license.jwt, plexicus-eval.env — to the VM
(e.g. scp keys.json license.jwt plexicus-eval.env root@<vm-ip>:/root/),
then:
curl -fsSL https://docs.plexicus.ai/install.sh -o install.sh
sudo -E \
PLEXICUS_ENV_FILE=/root/plexicus-eval.env \
PLEXICUS_GAR_KEY_FILE=/root/keys.json \
PLEXICUS_LICENSE_FILE=/root/license.jwt \
bash install.sh
PLEXICUS_ENV_FILE is read before anything else the installer does, so every
PLEXICUS_* setting delivered in plexicus-eval.env — including
PLEXICUS_CHART_VERSION and PLEXICUS_DOMAIN — is what actually gets
installed. Run without the remaining variables to be prompted interactively for
whatever the file does not supply — the registry key, the license path and the
AI key are the only three inputs the installer will ever ask you for. The
installer is idempotent — re-running it after a failure or for an upgrade is
safe.
plexicus-eval.env carries the AI key Plexicus provides for your evaluation —
it powers finding enrichment, AI remediation, and AI SAST scanning. Bring your
own key by exporting PLEXICUS_AI_KEY when you run the installer: an
explicitly-passed value — including an explicitly empty one
(PLEXICUS_AI_KEY=, to skip the delivered key and be prompted instead) —
always wins over the one in the file. The installer
defaults to DeepInfra (https://api.deepinfra.com/v1/openai, model
deepseek-ai/DeepSeek-V4-Flash); override
PLEXICUS_AI_BASE_URL/PLEXICUS_AI_MODEL for a different provider.
The same precedence applies to every variable in the table below — the file is a set of defaults for your install, never an override of what you pass explicitly.
All options:
| Variable | Default | Purpose |
|---|---|---|
PLEXICUS_ENV_FILE | (none) | Path to plexicus-eval.env from your delivery package. Sourced first, so every PLEXICUS_* setting it contains applies — including PLEXICUS_CHART_VERSION and PLEXICUS_DOMAIN. Variables you export explicitly override it. The installer tightens the file to mode 600 (scp and unzip leave it at 644) |
PLEXICUS_GAR_KEY_FILE | (required) | Path to the registry service-account JSON |
PLEXICUS_LICENSE_FILE | (required) | Path to license.jwt |
PLEXICUS_AI_KEY | from plexicus-eval.env | DeepInfra (or other OpenAI-compatible) API key — powers AI enrichment, remediation, and AI SAST. Provided by Plexicus in your delivery package; set it explicitly to bring your own |
PLEXICUS_AI_BASE_URL | https://api.deepinfra.com/v1/openai | OpenAI-compatible endpoint |
PLEXICUS_AI_MODEL | deepseek-ai/DeepSeek-V4-Flash | Model id at that endpoint |
PLEXICUS_AI_SCAN_API_KEY | reuses PLEXICUS_AI_KEY | Chat LLM key for the AI SAST (SocratiCode) scan engine itself |
PLEXICUS_AI_SCAN_BASE_URL | reuses PLEXICUS_AI_BASE_URL | Endpoint for the AI SAST scan engine's chat calls |
PLEXICUS_AI_SCAN_MODEL | reuses PLEXICUS_AI_MODEL | Model id for the AI SAST scan engine's chat calls |
PLEXICUS_AI_SCAN_EMBEDDING_API_KEY | reuses PLEXICUS_AI_KEY; prompted when a custom provider is set | Key for the embedding endpoint used when indexing repositories |
PLEXICUS_AI_SCAN_EMBEDDING_BASE_URL | https://api.deepinfra.com/v1/openai | Endpoint for embedding calls |
PLEXICUS_GITHUB_CLIENT_ID | (optional) | Client id of your GitHub App or OAuth App |
PLEXICUS_GITHUB_CLIENT_SECRET | (optional) | Client secret of that App |
PLEXICUS_GITHUB_APP_ID | (optional) | Numeric GitHub App id — GitHub App flow only |
PLEXICUS_GITHUB_APP_INSTALLATION_URL | (optional) | https://github.com/apps/<slug>/installations/new |
PLEXICUS_GITHUB_APP_PRIVATE_KEY_FILE | (optional) | Path to the App's private key .pem |
PLEXICUS_GITLAB_CLIENT_ID | (optional) | Client id of your GitLab OAuth application (gitlab.com) |
PLEXICUS_GITLAB_CLIENT_SECRET | (optional) | Client secret of that application |
PLEXICUS_BITBUCKET_CLIENT_ID | (optional) | "Key" of your Bitbucket Cloud OAuth consumer |
PLEXICUS_BITBUCKET_CLIENT_SECRET | (optional) | "Secret" of that consumer |
PLEXICUS_DOMAIN | plexicus.local | Hostname to serve on (set a real DNS name, or plexicus.<vm-ip>.nip.io to skip /etc/hosts entirely) |
PLEXICUS_ADMIN_EMAIL | admin@example.com | First admin account |
PLEXICUS_ADMIN_PASSWORD | generated | First admin password |
PLEXICUS_CHART_VERSION | 1.2.36 | Chart version to install |
Set them only if you already have the apps registered and would rather have the connector configured at install time than add it in the UI afterwards. A connector is written to the chart only when both its client id and its secret are present — a half-filled one would render a "Connect" button that can only fail at token exchange, so the installer warns and skips it. Leaving all nine unset is the normal path; see Connect your own SCM.
When it finishes, the installer prints the URLs, the admin credentials, the
path of the evaluation CA certificate, and which SCM connectors (if any) it
configured. The script is ~740 lines of plain bash at
docs.plexicus.ai/install.sh. In order: Generated credentials live in What the installer does (read the script before piping to root — we would)
PLEXICUS_ENV_FILE is set, sources
plexicus-eval.env before resolving any constant (so the chart version and
domain it carries are the ones used), tightens the file to mode 600, and
restores any PLEXICUS_* variable you passed explicitly so it wins over the
file.CN and subjectAltName (Burp Suite and modern
browsers reject certificates without them). No cert-manager needed.1.2.32 from the OCI registry and installs
it with the bundled-infrastructure overlay (values-bundled-infra.yaml +
values-evaluation.yaml) plus an override file containing your generated
passwords and AI settings (/root/plexicus-eval/overrides.yaml).fastapi, frontend and worker, then checks
the frontend and api /health return HTTP 200 and the certificate CN.is_verified/role: admin directly in MongoDB. The evaluation overlay
declares smtp.deliveryMode: "disabled", so no mail is sent and nothing
fails silently — but a self-registration is never auto-verified in any
delivery mode, and the admin-mediated invite path needs an admin that does
not exist yet on a fresh cluster. Writing the flag is still the only way to
create the first account. Every user after that should be invited from
inside the platform, which hands you a verification link to pass on./root/plexicus-eval/credentials.env
(mode 600). Uninstall everything with /usr/local/bin/k3s-uninstall.sh.
Point your workstation at the VM
The platform serves https://plexicus.local and https://api.plexicus.local
(or your PLEXICUS_DOMAIN). On your laptop:
-
Add both names to
/etc/hosts(skip if you used a real DNS name ornip.io):echo "<vm-ip> plexicus.local api.plexicus.local" | sudo tee -a /etc/hosts -
Trust the evaluation CA so the browser — and Burp Suite, if you are pentesting the platform — accepts the TLS certificates:
scp root@<vm-ip>:/root/plexicus-eval/plexicus-eval-ca.crt .Then import it into your trust store:
-
macOS:
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain plexicus-eval-ca.crt -
Linux:
sudo cp plexicus-eval-ca.crt /usr/local/share/ca-certificates/ && sudo update-ca-certificates -
Windows (elevated prompt):
certutil -addstore -f Root plexicus-eval-ca.crt -
Firefox keeps its own trust store — import the file under Settings → Privacy & Security → Certificates → View Certificates → Import.
-
Burp Suite: Settings → TLS → CA certificates.
The leaf certificates carry a proper
CNandsubjectAltName, so proxying through Burp works without TLS errors. -
Log in and run your first scan
Open https://plexicus.local and log in with the admin credentials the
installer printed.
Use the Sandbox onboarding flow — it scans a pre-configured vulnerable repository through a synthetic SCM connector, so it needs no OAuth app and no SCM connection at all:
- Onboarding → Sandbox (or Applications → Add Repository → Sandbox).
- Select the
simplest-vulnerablerepository and start the scan. - Watch findings appear in the dashboard — the scan takes 2–4 minutes, and AI enrichment fills in remediation guidance as it completes.
That is the whole evaluation path. Scanning your own repositories is the optional next step.
Connect your own SCM (optional)
SCM connectors are added to a running deployment — this step happens after
installation, whenever you choose. There is no install-time deadline: configure
GitHub today, next week, or never. (The PLEXICUS_* install variables are just
a shortcut for the same configuration.)
Skip this unless you want to scan your own repositories. Nothing above depends on it, and an evaluator with no SCM connected is a working evaluator.
GitHub — automatic (recommended). On a deployment with no GitHub App configured, Settings → Integrations → GitHub offers Create GitHub App automatically: the platform drives GitHub's App Manifest flow, GitHub creates and configures the App for you, and the credentials are stored and applied to the running deployment — nothing to copy, no restart. One caveat: the generated App only gets webhooks when your domain is publicly resolvable — see SCM Connections.
Manual — GitLab, Bitbucket, or a hand-registered GitHub App. Register the
app with your provider, then add its client id and secret in the platform under
Settings → Source Control. You can also pre-configure a connector at
install time by passing the matching A full GitHub App rather than a plain OAuth App is worth the extra minute:
the platform has two separate GitHub OAuth flows — sign-in and the repo-scanning
connector — that each need their own callback registered, and the App flow
additionally enables webhooks and per-repository install/uninstall. On
github.com: Settings → Developer settings → GitHub Apps → New GitHub App: Callback URLs (add both — use Add Callback URL for the second one): (your Request user authorization (OAuth) during installation: checked. Webhook → Active: unchecked — GitHub cannot reach a Repository permissions: Contents and Metadata (read-only). Add Pull
requests (read & write) to test remediation pull requests. After creating the app: note the App ID and the app slug (from its
URL), generate a client secret, and generate a private key (a Install the app on your GitHub account or organization
( To wire it in at install time instead, copy the User Settings → Applications
on gitlab.com (a self-managed GitLab instance is connected separately,
per-connection, in the platform UI — this app registration only covers
gitlab.com): To connect a self-managed GitLab instead, skip these installer variables
entirely and follow
GitLab → Self-Hosted after the platform
is up: you register the application on your own instance and enter its URL,
client id and secret in the Plexicus UI. Workspace Settings → OAuth consumers → Add consumer:PLEXICUS_* variables from the table
above — the values and callback URLs are identical either way.GitHub — register a GitHub App
https://plexicus.local/api/callback/github (sign-in)https://api.plexicus.local/vulnerability-tool/callback/github (the repo-scanning connector — note the hyphen in vulnerability-tool)PLEXICUS_DOMAIN in place of plexicus.local if you changed it — the
browser follows these redirects, so a .local name from /etc/hosts
works fine).local name, so
push-triggered rescans are unavailable in this setup (manual and scheduled
scans work). Use a publicly resolvable PLEXICUS_DOMAIN (e.g.
plexicus.<vm-ip>.nip.io) if you want webhooks..pem
file downloads).https://github.com/apps/<slug>/installations/new) — that installation URL
is one of the values Plexicus asks for..pem to the VM and pass:sudo -E \
PLEXICUS_ENV_FILE=/root/plexicus-eval.env \
PLEXICUS_GAR_KEY_FILE=/root/keys.json \
PLEXICUS_LICENSE_FILE=/root/license.jwt \
PLEXICUS_GITHUB_CLIENT_ID=... \
PLEXICUS_GITHUB_CLIENT_SECRET=... \
PLEXICUS_GITHUB_APP_ID=123456 \
PLEXICUS_GITHUB_APP_INSTALLATION_URL=https://github.com/apps/<slug>/installations/new \
PLEXICUS_GITHUB_APP_PRIVATE_KEY_FILE=/root/github-app.pem \
bash install.shGitLab — register an OAuth application
https://plexicus.local/api/callback/gitlabapi,
read_api, read_user, read_repository, write_repository, openid,
profile, emailPLEXICUS_GITLAB_CLIENT_ID and PLEXICUS_GITLAB_CLIENT_SECRET.Bitbucket Cloud — register an OAuth consumer
https://plexicus.local/api/callback/bitbucket_cloudPLEXICUS_BITBUCKET_CLIENT_ID and PLEXICUS_BITBUCKET_CLIENT_SECRET.
Once a connector is configured, Applications → Add Repository lists your repositories.
Every other supported provider — GitHub Enterprise Server, self-managed GitLab, Gitea, Forgejo, Azure DevOps and TFVC — needs nothing at install time. Each of those connections carries its own credentials, entered in the UI under Connectors → SCM once the platform is running. The SCM Connection Reference lists the flow, callback URLs and scopes for all of them, and records that Bitbucket Server / Data Center is not supported.
Troubleshooting
The installer failed — where do I look?
The installer is verbose and dies with a specific error message. Re-running it is safe and resumes idempotently. The usual suspects:
ImagePullBackOffon Plexicus pods → wrong or expiredkeys.json, or a chart version older than1.2.19(chart1.2.19was the first release whose default images all resolved in the customer registry — the installer now defaults to1.2.32; pin1.2.32or later, since this installer no longer understands the single-filevalues-evaluator.yamloverlay chart1.2.19through1.2.31shipped).- Registration failed / login 500 →
kubectl -n plexicus logs deploy/fastapi; a crash-loopingtemporal-*pod during the first ~2 minutes is normal while the Temporal schema Job completes. - Pods
Pending→ check RAM:kubectl -n plexicus describe pod <pod>. 7 GB is the tested minimum.
Scans stay at "Scanning in progress" forever
The AI credentials are wrong. Verify the key, endpoint and model that the installer wired in:
kubectl -n plexicus logs deploy/worker | grep -i "api_key\|openai"
The api_key client option must be set (or HTTP 401 from the AI endpoint)
means the key/endpoint/model combination is invalid. Re-run the installer with the right
PLEXICUS_AI_BASE_URL and PLEXICUS_AI_MODEL.
AI Remediation cannot be created — the AI connection test fails (400)
The Create Remediation flow first tests the remediation AI connection
(POST /openai/connections/remediator/tests); a 400 there blocks the UI. Look
for the tell-tale pair in kubectl -n plexicus logs deploy/fastapi:
Response testing OpenAI: {"error":{...,"code":"invalid_api_key"}}
AI provider returned HTTP 401: User is not authorized to access this resource
If scans and enrichment work but this test 401s, the AI provider label
does not match the endpoint your key belongs to: the test endpoints dispatch
on the label with per-provider request URLs. Installs made with an installer
older than the current one hit exactly this. The current installer
derives the label from PLEXICUS_AI_BASE_URL automatically — re-download and
re-run it to fix an affected install:
curl -fsSL https://docs.plexicus.ai/install.sh -o install.sh
sudo -E PLEXICUS_ENV_FILE=/root/plexicus-eval.env PLEXICUS_GAR_KEY_FILE=... PLEXICUS_LICENSE_FILE=... bash install.sh
Create Remediation stays at "Creating…" and no fix ever appears
Installs made with an installer older than the current one are missing the post-install fixes for the remediation engine's network rules and the worker sizing, so remediation requests can never reach the engine. Re-download and re-run the installer — it is idempotent and applies the fixes without touching your data:
curl -fsSL https://docs.plexicus.ai/install.sh -o install.sh
sudo -E PLEXICUS_ENV_FILE=/root/plexicus-eval.env PLEXICUS_GAR_KEY_FILE=... PLEXICUS_LICENSE_FILE=... bash install.sh
If remediation still fails afterwards with the platform otherwise healthy, your evaluation license may predate the current feature set — request a refreshed license at engineering@plexicus.ai.
Connect GitHub fails with error_code=unknown (400 Bad Request on the callback)
The OAuth token exchange with GitHub is failing. Check, in order:
-
Client secret present? It must be non-empty in the fastapi Secret:
kubectl -n plexicus get secret plexicus-fastapi \
-o jsonpath='{.data.GITHUB_OAUTH_CLIENT_SECRET}' | base64 -d | wc -c0means no GitHub client secret was ever configured on this install. Add the connector under Settings → Source Control, or re-run the installer withPLEXICUS_GITHUB_CLIENT_ID/PLEXICUS_GITHUB_CLIENT_SECRETset (see Connect your own SCM). -
Callback URLs registered? The GitHub App needs both registered exactly:
https://<PLEXICUS_DOMAIN>/api/callback/github(sign-in) andhttps://api.<PLEXICUS_DOMAIN>/vulnerability-tool/callback/github(the repo-scanning connector — note the hyphen). A mismatch or a missing one makes GitHub reject the exchange (redirect_uri_mismatchinkubectl -n plexicus logs deploy/fastapi). -
Installs from before installer GitHub support (chart ≤ 1.2.32 era scripts) created the Secret keys under legacy names that chart 1.2.21+ no longer reads (
GITHUB_CLIENT_SECRET,GH_APP_PRIVATE_KEY). Re-running the current installer recreates them under the canonical names (GITHUB_OAUTH_CLIENT_SECRET,GITHUB_APP_PRIVATE_KEY).
Browser or Burp rejects the TLS certificate
Import /root/plexicus-eval/plexicus-eval-ca.crt as described in Step 2. If
you regenerated certificates, restart the ingress pods:
kubectl -n ingress-nginx rollout restart deploy.
Manual installation
Everything the installer does can be done by hand — the chart ships complete
documentation for the manual path (helm pull the chart and read
docs/getting-started.md), and the
Self-Hosted Installation guide covers the full
production procedure: external infrastructure, real DNS and certificates, OAuth
apps, SMTP, and hardening.