Skip to content

Support

Where to take a question, a bug or a security report - then what is supported, for how long, and what to do if your organisation cannot simply “run the latest”.

The routing, first, because GitHub surfaces this file to someone who is already mid-way through opening an issue. It matches .github/ISSUE_TEMPLATE/config.yml, which is what the New Issue page actually offers.

You have Go to
a question, an idea, or “is this supposed to work like this?” Discussions
tried it, and something to say about how it went - what worked, what didn’t, where you got stuck the feedback thread
something that looks like a bug the Bug report issue template
a redteam -compare run - a disagreement with AWS, or a clean run the Field report: engine vs AWS issue template
a feature or a change in behaviour to propose the Feature request issue template - and read the roadmap first, so we can agree on the shape before you write code
a security problem never a public issue - private reporting, see SECURITY.md

Questions go to Discussions rather than issues on purpose: an issue is a thing that gets closed, and “how do I model a shared VPC” is a thing other people search for later.

Four lines that turn most reports into something answerable on the first reply:

  1. The version - the image digest or tag, or git rev-parse HEAD if you built it.
  2. Which stack - make demo, Docker Compose, or Helm on a real cluster - and the graph backend (in-memory or Apache AGE), because several behaviours differ between them.
  3. What you expected and what happened, ideally as the request you sent and the response you got.
  4. The relevant log lines - the backend logs the reason it refused something far more often than the API response does. Scrub them first: they can name your assets.

The manual is the reference and answers most usage questions before they need asking.

Fixes land on the newest release. Nothing is backported.

Version Receives fixes
the newest tagged release, and main yes
every earlier tag no - upgrade to the newest

There is no long-term-support branch, and 1.0 did not create one: it froze the interface, not a maintenance window - see API stability.

One maintainer, and a cadence measured in days rather than quarters: six minor releases in the eight days after 1.0. Backporting security fixes onto a maintenance branch is a promise about future weeks of one person’s time, and this project would break it. A support window that exists on paper and fails on the day a CVE lands is worse than an honest “upgrade”, because the paper one gets written into somebody’s risk register as a control.

So the commitment is made where it can be kept: on how fast a fix appears, and on how cheap the upgrade is.

Measured from the moment a report is confirmed, to a public release carrying the fix:

Severity (CVSS) Target
Critical 7 days
High 30 days
Medium / Low the next release that suits it

Acknowledgement within 3 business days and triage within 7 are in SECURITY.md, along with how to report privately. These are targets a single maintainer can hold, not an SLA you can buy - if one slips, the advisory says so rather than the date quietly moving.

2. An upgrade that is specified rather than hoped for

Section titled “2. An upgrade that is specified rather than hoped for”

The reason “always run the latest” is a workable policy here is that upgrading is designed to be boring:

  • SemVer, with the stable surface enumerated. The GraphQL API, the ingest contract, the operational endpoints, the environment variables and the CLI only break in a major release. API stability lists them and the deprecation path.
  • The schema contract is machine-guarded. docs/api/schema.graphql is a snapshot and a test fails CI on any drift, so a breaking API change cannot arrive unnoticed in a patch.
  • A CHANGELOG per release, generated from Conventional Commits rather than written from memory, and an upgrade note for every release that needs you to do something - a new setting, a request that now fails. Most releases need neither.
  • No migration step. The backend creates and upgrades its own graph and governance schema on start-up. There is nothing to run between versions.
  • Rollback is a redeploy of the previous digest. One caveat worth knowing before you need it: a release rolled back onto a governance database that a newer release already migrated refuses to start rather than writing a schema it does not understand - it fails loudly instead of corrupting state, so take the backup in OPERATIONS §4 first.
  • The graph is derived state. In the worst case it is rebuilt by re-ingesting the feeds, so an upgrade gone wrong costs you history, not the map.

Every release publishes digest-addressable images and signed binaries with an SPDX SBOM and SLSA build provenance. Pin the digest, verify the signature before rollout, and your “approved version” is a thing with a hash rather than a moving tag - see SECURITY.md for the verification commands.

The practical recipe, in the order a release manager would want it:

  1. Pin by digest, not by latest and not by a floating major tag.
  2. Watch releases - on GitHub, Watch → Custom → Releases - so a new version is a notification rather than a discovery. Security releases are also published as GitHub advisories.
  3. Verify the cosign signature, the SBOM and the provenance attestation as a gate in your own pipeline, so an unverifiable artefact fails your process rather than mine.
  4. Read UPGRADING.md for the target version - the releases that need an action from you, and what it is - then the CHANGELOG for the rest. The CHANGELOG is generated from commit subjects and states what changed in a line; it is not where the operator instruction lives.
  5. Stage it, then roll forward with the backup already taken.
  6. Keep your configuration under your own change control. The environment variables are part of the stable surface, so your .env or Helm values are a reviewable artefact that survives upgrades.

If your process requires a fixed version for a period, pin the digest and treat each new release as a change to assess - but be explicit internally that an unpatched pin carries the risk, because no fix will be issued for it here.

  • There is no commercial support, no SLA and no paid tier. Nobody is on call.
  • Issues and pull requests are best-effort, answered when the maintainer has time. The only stated response times in this project are for security reports.

One maintainer is a real risk and pretending otherwise would be the same mistake as an unkeepable support window. What reduces it is that nothing about this project requires the maintainer to keep existing:

  • Apache-2.0, so a fork needs no permission.
  • No telemetry, no phone-home, no hosted component. Nothing you run depends on infrastructure anyone else operates.
  • The entire build and release path is in the repository - the workflows, the signing, the SBOM and provenance generation. A fork inherits a working pipeline: the release workflow derives its signing identity from whichever repository runs it, so a fork signs its own images without editing anything. What a fork does have to change is the published image namespace, which is written out in README.md, SECURITY.md, docs/MANUAL.md and the chart’s values.yaml, along with the verification commands that name it.

That is not a substitute for a second maintainer. It is what makes taking over possible rather than theoretical, and it is worth contributing to.