Run it inside your own boundary
Self-hosted here means the datastores are yours, the artefacts are yours, the keys are yours, and the running stack makes no calls you did not configure.
how these are countedEvery figure above is reproducible from the source
- 8 services in the self-host stack
docker-compose.selfhost.yml — postgres, neo4j, redis, minio + init/migrate/app/web - 2 vCPU · 6 GB RAM · 10 GB disk documented minimum host for the full stack
SELF_HOSTING.md - $0 to self-host the Community edition, in production
LICENSING.md — Elastic License 2.0 - 0 bytes of your telemetry leave your account
docker-compose.selfhost.yml — every datastore runs in your stack - Elastic License 2.0 core license — source-available, no time conversion
LICENSE:1, LICENSING.md
Deploy it
One compose file, one host, eight services. The application runs read-only and brings its own persistence, so the only decisions you make are where it runs and what it can read.
# everything the stack needs is in the repository
git clone https://github.com/hanu-security/hanu
cd hanu
cp .env.selfhost.example .env.selfhost # datastore credentials, ports, KMS
docker compose -f docker-compose.selfhost.yml up -d
# then attach read-only cloud roles
aws iam create-role --role-name hanu-readonly \
--assume-role-policy-document file://trust.jsonThe application container needs no external service. An air-gapped install mirrors the images and any content bundle into the environment and runs the same compose file; nothing in the running stack reaches out, which is a property you can watch with your own network tooling before you tell an assessor about it.
SH-01Postgres — findings, tenants, audit log
SH-02Neo4j — the reachability graph
SH-03Redis — the work queue
SH-04MinIO — artefacts and exports
What it can read, and what it never needs
Cloud access is a read-only IAM role with an external ID, scoped to the accounts you list. The platform enumerates configuration and reads the audit trail; it does not modify resources, and it does not need a role that could.
| Surface | Access required | Write access? |
|---|---|---|
| AWS | SecurityAudit plus read-only access to the services you want covered | No |
| Azure | Reader at subscription scope, plus Security Reader | No |
| GCP | roles/viewer at project or folder scope | No |
| GitHub | Read on repository and actions metadata; check-run write only if you want PR feedback | Only for feedback |
| GitLab, CircleCI, Jenkins | Read on project and pipeline metadata; job step write for feedback | Only for feedback |
| Okta, Entra ID, Workspace | Read-only directory scope | No |
Where your data lives
Every datastore in the list above runs inside your namespace, VPC or cluster. Findings stay in your Postgres, the graph stays in your Neo4j, artefacts stay in your MinIO, and source credentials are sealed with a KMS key you own.
There is no relay, no telemetry endpoint and no licence-check callout in the image. That is a stronger statement than "we do not sell your data" and a weaker statement than "we cannot see it" — the correct claim is that the software has nowhere to send it, and that you can verify this by watching egress rather than by reading a policy.
Operating it
| Concern | How it works |
|---|---|
| Upgrades | Pull the new images and re-run compose. Schema migrations run as their own service before the application starts. |
| Backups | Ordinary Postgres, Neo4j and object-store backups. Nothing is held in a vendor-side account that has to be exported first. |
| Retention | Per-tenant audit log retention is configurable so it can match your longest audit obligation rather than a vendor default. |
| Detection content | Community edition receives detection content with each release. Growth adds a continuously-updated feed between releases. |
| Scaling | The stateless application and worker services scale horizontally; the datastores scale the way those datastores scale. |
| Observability | Standard container logs and metrics — no proprietary agent and no callback to a vendor console. |
Licensing, stated precisely
The core is under the Elastic License 2.0. It is source-available rather than OSI-approved open source, and the difference is worth describing rather than glossing.
- Permitted: use the software internally for any purpose, copy it, modify it, distribute it, and make it available within your organisation.
- Not permitted: providing the software to third parties as a hosted or managed service, circumventing licence-key functionality, or removing licensing and copyright notices.
- No time conversion. This is not a licence that becomes something else after three years, and it does not revert to a permissive licence on a schedule.
- No metering. Nothing counts seats, events per second, gigabytes ingested or hosts. Community costs $0 in production regardless of the size of the estate you point it at.
What self-hosting does not get you
A page that only lists advantages is an advertisement rather than a decision aid. The honest trade is this: you own the boundary and you own the operations.
- You run the datastores. Postgres, Neo4j, Redis and MinIO are yours to back up, upgrade, monitor and size. That is real work, and it is the price of the boundary.
- Community detection content arrives at release cadence. The continuously-updated feed between releases is a Growth capability. If new detection content within days of a campaign is a requirement, that is an edition decision and not a configuration one.
- No SOC 2 report for the self-hosted product. The managed edition has one. Self-hosted customers satisfy their own controls — the platform supplies the evidence engines and the audit trail that support doing so.
- No support SLA on Community. There is no contractual response time, no named engineer and no escalation path. Enterprise adds those.
- No SCIM, no Wiz, Jamf, Rapid7, Sumo Logic or Intune integration, and no Oracle Cloud support. These are absent in every edition, not gated by one.
- Hardening is yours. The image runs read-only and needs nothing outbound, but network policy, secret management and host hardening in your environment are your controls, not ours.
Questions
Can it really run with no outbound internet access at all?
What is the smallest host that works?
Does the Community edition expire or reduce after a period?
How do we get detection content updates without the paid feed?
Where do the credentials for our cloud accounts end up?
Can we run more than one environment from one install?
Run it in your own account
One Docker Compose stack, your datastores, read-only credentials into your clouds. The Community edition is free to run in production.