Skip to content
WAHUKEZA

Run · Deploy, identity & trust

Your hardware or ours. Your own database either way.

Run it on-premises, as a tenant on Wahukeza-operated instances, or both, and change your mind later with an open-format export. On-premises, nothing comes back to us. Every package is an annual licence per installation or tenant with unlimited analysts.

Delivery

Three ways to run it. Your choice, and reversible.

On-premises

Your hardware, your database.

Docker Compose on a VM, or Kubernetes with the Helm chart for high availability. Nothing goes to us: no call-home, a licence verified offline, an AI provider of your choice or none.

Hosted tenant

Our instances, your own database.

A tenant on a Wahukeza-operated instance, with its own database per tenant. Trony Network acts as processor under the data processing agreement.

Combined

Both, where each fits.

Models can be combined, and changed later. Your data exports in open formats (STIX 2.1, CSV and JSON), so moving between them is a migration, not a rebuild.

On-premises

Two supported paths.

Docker Compose

One host, one file.

An nginx edge (TLS, the SPA, the API proxy), a one-shot migration init container, PostgreSQL 16, Redis, a pg_dump backup sidecar and an opt-in observability profile (Prometheus with shipped alert rules, Alertmanager, a provisioned Grafana dashboard, loopback-bound).

docker compose -f docker/docker-compose.prod.yml up -d

Kubernetes · Helm

Clustered, HA, multi-tenant.

API Deployment with an HPA, a pre-upgrade migrate Job, optional PgBouncer or CloudNativePG, an optional screenshot browser. Values reference and required secrets in the chart README.

helm upgrade --install cti deploy/helm/cti -f values.yaml

Needs: PostgreSQL 16, Redis 7, a container host or a namespace. The app never auto-migrates in production; the runner does, as an init container or a Job, and each tenant carries its own schema version and degraded state so a partial upgrade is never silent.

On-premises

Nothing goes to us.

No call-home and no telemetry to Wahukeza. The licence is verified offline. AI runs on a model you host, on Anthropic with your own key, or not at all.

The platform does fetch public data by default (CVE records and exploit scores, vendor advisories, the Public Suffix List, the Security wire, app-store search) and every external fetch can be switched off. Connectors to the feeds you choose fetch only what you configure.

Hosted tenant

Your own database, under a DPA.

A hosted tenant gets its own database on a Wahukeza-operated instance, which keeps its data separate and lets it be placed in a chosen region. Trony Network processes it as processor under the data processing agreement; the hosting region and sub-processors are set out there.

Licence

A signed file. Verified offline. Never a kill switch.

Every package is an annual licence per installation or tenant, with unlimited analysts: no per-user or per-seat charge. The licence is an ECDSA P-256 signed file the platform verifies offline; there is no call-home. When it expires, the platform falls back to the Community edition. It never takes the platform offline.

Packages and modules

# licence file + public key, both local

Licensing__LicenseFile=<path to the signed licence>

Licensing__PublicKey=<the public key it is verified against>

# what is in force: tenant licence → deployment licence → community

GET /api/license → what is granted, and its source

# expired or absent: community edition, platform keeps running

Identity and access

In every package, and in the Enterprise Identity module.

MFA, the built-in permission sets, scoped API keys and the audit log are in every package. Single sign-on, SCIM provisioning and custom permission sets are the Enterprise Identity module, in Advanced and Complete, or licensed on its own.

Every package

  • TOTP · recovery codes

    MFA

    Two-step login with a five-minute challenge token that satisfies no policy; seeds encrypted under a derived key; required for none, privileged users or all.

  • ReadOnly · Analyst · Admin · Operator

    Four built-in permission sets

    Over a closed vocabulary of 13 permissions. Operator exists on multi-tenant installations; the control-plane role is outside the tenant’s permission system entirely.

  • X-Api-Key

    Scoped API keys

    Hashed, revocable, expiring, rate-limited. Ten scopes, five of them isolated machine scopes (attack-surface:probe, appliance:agent, availability:report, fraud:lookup, scim:provision) that no admin key implies and that imply nothing.

  • hash chain · signed anchors

    Tamper-evident audit

    Every sensitive mutation with actor, time and tenant, hash-chained and closed daily by a signed anchor; a verifier, an audited export and an audit stream to your SIEM.

Enterprise Identity module

  • OIDC · PKCE

    SSO

    Any OpenID Connect provider; just-in-time provisioning; roles re-mapped on every login; the IdP token never reaches the browser; local login is never disabled.

  • /scim/v2

    SCIM 2.0

    Users and groups from Entra ID or Okta, with their two PATCH dialects reconciled; deactivate, never delete; provisioning runs on the isolated scim:provision scope no human can hold.

  • PermissionSet

    Custom permission sets

    Compose your own sets from the 13 permissions. A custom set can never exceed its author’s own permissions.

AI

Chosen at install. Local, your own key, or off.

AI is chosen at install: a local model (any OpenAI-compatible server: vLLM, Ollama, llama.cpp), Anthropic with your own key, or off. The stock configuration refuses to start on a hosted provider without a key, so nothing reaches an AI provider you did not configure. With AI off, everything except AI summaries and classification works; Ask returns retrieval-only answers with citations.

Visual screenshot comparison of lookalike pages needs the hosted provider. Triage-model state and AI evaluation runs are stored in the tenant’s own database.

What the AI modules do

# appsettings / environment

AI__Provider=local # or anthropic | none

AI__Local__BaseUrl=http://llm.internal:8000/v1

AI__Local__Model=<model name on your server>

# anthropic: Anthropic__ApiKey is required, or the API refuses to start

# none: AI actions hidden in the app; Ask answers retrieval-only, with citations

Data protection

Attacker IPs are personal data. The platform behaves accordingly.

Retention controls for captured credentials, payloads, sightings and tokens; a data-subject request screen with export and erasure and the refusal ground recorded; records of processing, a privacy notice, a DPA template, a legitimate-interest assessment and a breach-response runbook. All shipped with the platform.

  • DSAR screen

    Access and erasure over the compliance API, with the Art. 17(3) refusal prompt and an audit echo.

  • TLP enforced

    TLP:RED never leaves in a feed, a webhook or an export; dispatchers check it.

  • Masked PII

    Leaked credentials masked at rest and in the UI; admin-only; TLP:RED by default.

  • Retention job

    Purges captured credentials, payloads, old sightings and dead tokens on your schedule.

What a release contains

Signed with our key. Gated before it ships.

Version 0.1.0 shipped on 28 October 2026. Every release carries the API and proxy images for amd64 and arm64, the Helm chart, CycloneDX SBOMs per image and for the source tree, Trivy reports, the OpenAPI specification, the public key cosign.pub, SHA256SUMS over every file, and the documentation as an offline bundle.

Images, SBOM attestations and the chart are signed with the project’s own cosign key. Nothing is written to a public transparency log; the key is the trust root, and its fingerprint is on the security page.

Documentation ships with every release and mirrors on-premises or air-gapped. Ask for the current set.

  • Upgrade drill (N-1)

    The previous release migrates and seeds a database, the new release migrates it, then the previous release’s API reads through the upgraded schema. A migration that would break a rollback fails the release.

  • Restore drill

    Migrate, seed, dump, restore, compare row counts per table, check readiness, and migrate again expecting nothing to apply.

  • Forward-only migrations

    A migration that can go down, or drops or renames a column without a recorded contract, is refused. Rollback is redeploying the previous image.

  • Vulnerability gate

    Trivy scans each image; a CRITICAL finding fails the release, and the HIGH report is published with it.

  • Licence gate and SBOM

    A CycloneDX SBOM is produced and checked against the dependency licence policy; a denied licence fails the release.

  • End-to-end and docs

    End-to-end flows against a running stack, and a strict documentation build in which every link must resolve.

Operations

Observable and recoverable.

  • /metrics · OTel

    Observability

    Prometheus with cti_* business metrics and a feed-freshness dead-man’s switch; OpenTelemetry tracing; structured logs; health and readiness endpoints.

  • RPO / RTO

    Disaster recovery

    Stated recovery objectives per topology, encrypted off-site backup copies, per-tenant restore without stopping the platform, and a backup-freshness health check.

  • GET /api/system/version

    Know what runs

    The version comes from the release tag and nothing else; a running instance reports it, and so does the About dialog. Deploy by digest, not by tag.

Install it on a clean machine, timed.

We will run the Compose path with you from an empty host and stop the clock at the first sensor event.