Contents

Use

Fix pull requests

Fixes from your tools

Akesis adopts the security-update pull requests that Dependabot, Snyk and Renovate open. It trusts only pull requests from the same repository (never a fork), by the tool's own account, on the tool's branch naming. On Bitbucket and GitLab you choose the accounts Snyk and Renovate use. Look-alikes are ignored.

For each fix pull request, Akesis:

  1. Links it to the active findings it fixes (same package, upgraded to or past the fixed version).
  2. Checks provenance: that every upgraded package in the lockfile matches the hashes the registry publishes. This works for npm (package-lock.json), Python (Poetry, uv, PDM and Pipenv lockfiles, or requirements files with --hash, as pip-compile --generate-hashes writes them), Go (go.sum, checked against the Go checksum database, with the same signature and log-inclusion proof the go command uses), Rust (Cargo.lock, checked against crates.io), Ruby (Gemfile.lock checksums against rubygems.org; Bundler 2.6 and later record them once you run bundle lock --add-checksums) and PHP (composer.lock, whose pinned commit and download must be the ones Packagist lists; Packagist publishes no signatures). For npm, Python and Ruby, Akesis also checks signatures. npm's registry signature must verify. When a release publishes a signed record of how it was built (npm provenance, PyPI and RubyGems attestations), that record must verify and match the file; for a gem, Akesis downloads it to check. A release whose predecessor had such a record but which doesn't, or which was built from a different repository, never auto-merges: that's how a hijacked maintainer account usually shows. The comment on the PR says which repository built each package.
  3. Checks compatibility (npm): Akesis compares the lockfile with your default branch's and looks only at packages the fix adds or changes. If one of them needs a peer that isn't met, or another package's peer requirement on the upgraded one stops being met (say react-dom still wanting React 17 after React moves to 18), or one needs a newer Node.js than your project declares (in package.json engines, .nvmrc or .node-version), Akesis flags it and doesn't merge automatically. The comment lists each problem.
  4. Decides under the repository's policy, with the CI result, and comments on the pull request with its decision and why. The comment lists the other versions that fix the same vulnerabilities: the smallest fix, the newest in your current major version, and the newest overall, marked if it's a major upgrade. Akesis prefers the least disruptive fix. If a tool proposes a major upgrade (say lodash 4 → 5) when a 4.x release already fixes everything, Akesis doesn't merge it automatically and says which smaller version would do. The comment says plainly that passing tests don't prove a fix is correct.
  5. Merges only at T3, after re-checking everything (including any emergency stop) just before merging, pinned to the exact commit CI tested. It decides again whenever the commit, CI, policy or stop state changes.

Fixes your team rejected

When someone on your team closes a fix pull request without merging it, Akesis remembers. If a tool proposes the same fix again for that package, Akesis holds it at suggest-only and never merges it. The comment on the pull request says which earlier one you closed. Akesis won't open that fix itself either. "The same fix" means:

  • for an upgrade to a new major version (say lodash 4 → 5), any version on that jump;
  • otherwise, the same version.

A tool closing its own pull request, as Dependabot does when a newer version supersedes it, isn't a rejection.

Akesis proposes the fix again, saying why, only if the risk has materially changed since then:

  • the vulnerability is now known to be exploited (CISA KEV);
  • its severity went up;
  • it became reachable from your code;
  • its EPSS (the estimated chance it gets exploited) rose by 20 points or more;
  • a new vulnerability now applies.

The finding page lists the rejections Akesis remembers for its package. An engineering lead can forget one, with a reason, so the fix is proposed normally again. Rejections and forgetting are both in the audit log.

After a merge

  • Regression watch: for 24 hours after an automatic merge (each repository's policy can set 1 to 168 hours), a failing default branch, a firing monitoring alert, or a jump in Sentry errors (both below), flags the fix as a suspected regression and stops autonomy for that repository. The finding page says which signal it was.
  • Revert this fix (engineering leads and above, on the finding) opens a revert pull request on GitHub or Bitbucket, or a revert merge request on GitLab, for a person to merge. Bitbucket has no revert API, so there Akesis restores the files the fix changed to their state before the merge, and refuses if any of them changed since.
  • Merges, refusals, failures and reverts are all in the audit log, with the merge commit as the revert handle.

Monitoring alerts after a merge

CI can pass while production errors climb. So Akesis also listens to the alerts you already have: under Integrations → Monitoring, an admin creates an alert key, then points an error-rate or health alert at Akesis with the repository in the URL:

POST https://akesis.app/api/v1/signals/alert?repository=owner/name
Authorization: Bearer <alert key>

Tools that can't set headers can put the key in the path instead, /api/v1/signals/alert/<alert key>?repository=owner/name; Akesis keeps it out of its logs.

  • Understood: Prometheus Alertmanager and Grafana (webhook contact point), PagerDuty (v3 webhooks), Sentry (metric and issue alerts, through an internal integration), and a generic JSON body {"status": "firing", "title": "…", "url": "…"} for Datadog and anything else. The Integrations page has the setup for each, including the Datadog payload.
  • Only firing, critical alerts count. Warnings, recoveries and acknowledgements are recorded and ignored. Your alert's threshold decides what an error spike is.
  • Only inside the watch window. An alert flags every automatic merge in that repository still inside its regression watch, and does nothing otherwise.
  • It can only stop autonomy, never widen it, so a leaked key can't merge anything. Each key may send 120 alerts an hour; replacing it stops the old one at once.

Alertmanager can serve several repositories through one receiver: put an akesis_repository label on each alert instead of ?repository=.

Sentry error rates after a merge

If you use Sentry, Akesis can watch the errors itself, without an alert. Under Integrations → Monitoring, an admin connects the Sentry organization with an internal integration token (read access to Project, Issue & Event and Organization), then says which repository each Sentry project belongs to.

  • Every 15 minutes, for each automatic merge inside its repository's regression watch, Akesis compares the errors in that repository's Sentry projects since the merge with the same hours of day over the week before. It takes the median of those seven days, so one bad day doesn't set the bar, and only hours before the merge count as usual.
  • It flags the fix when errors are at least double the usual and at least 20 more, so a quiet project going from 1 error to 3 isn't a regression. The finding page shows the numbers and links to the project in Sentry.
  • Akesis only reads from Sentry. The token is checked with Sentry before it's saved, stored encrypted, and never shown again; data in Sentry's US or EU region both work.

Fixes Akesis opens itself (npm)

When no tool has opened a fix for an npm finding, Akesis can open its own. It's off until an engineering lead turns it on for a repository, with a reason, under Fix generation on the repository's autonomy page. No AI is involved, and no code leaves the repository.

  1. Akesis picks the smallest version that fixes the vulnerabilities, and the pull request says why and which newer versions would also fix them. It plans the smallest package.json change: raising a direct dependency's floor (^6.5.0 → ^6.5.3), or an overrides entry for a transitive copy. Changes it can't make safely are skipped with a reason.
  2. It pushes the change to a branch named akesis/fix-<package>-<version>.
  3. Your CI rebuilds the lockfile. Akesis reads only what the registry publishes and never installs packages or runs scripts, so a small workflow you add regenerates package-lock.json. The autonomy page shows it ready to copy: a GitHub Actions workflow, a Bitbucket Pipelines branch pipeline, or a GitLab CI job.
  4. Akesis opens the pull request only if the commits after its own came from that workflow and touch nothing but lockfiles.
  5. From there it's handled like any tool's fix: provenance, policy, CI, merge, watch.

At most three Akesis fixes are open per repository at a time, highest priority first. A fix someone closed isn't opened again for that version. An emergency stop pauses it.

Batching. Tick Batch low-risk fixes into one pull request to get one PR instead of several. Upgrades that stay within the same major version and share a lockfile go into one PR, which counts as one of the three. Major upgrades, which can break things, still get a PR each. Akesis checks every package in a batch against the npm registry, and the autonomy policy decides on the PR as a whole.