Security

How to report a problem, and what the design already assumes so you can tell the two apart.

On this page

Reporting a vulnerability

Do not open a public issue.

Use GitHub’s private reporting form, or email ovalenzuela@ainvirion.com with CRAne security in the subject if you would rather not use GitHub. Include the version — crane status prints it — what you did, what happened, and what you expected. A proof of concept is welcome and never required.

This is a single-maintainer project. Expect acknowledgement within five working days, best effort, no paid support and no response-time guarantee. Fixes ship in a new tagged release rather than as a patch to an old tag, so upgrading is the remediation path.

Coordinated disclosure, and credit in the advisory unless you would rather not be named.

Decisions that are not findings

Some behaviour looks like a vulnerability and is a documented choice. Report it anyway if you disagree — this is just the answer you will get.

Behaviour Why
One shared token, no accounts, no roles CRANE_API_TOKEN is the whole authentication story. ADR 0002 covers why, and what would have to change first
An unauthenticated mode exists For localhost only. A bare 0.0.0.0 bind is refused without either the token or an explicit override
The database is not encrypted at rest It is a plain SQLite file on purpose, openable with any SQLite browser. Controlling who can read the file is the host’s job
An unfixed base-image CVE The release gate fails on anything HIGH or above that has a fix. A finding Debian marks unfixed in every stable suite cannot be resolved by rebuilding, so it does not block a release — it gets named instead. Where the affected code is something CRAne never calls, it gets deleted rather than accepted: perl-base was removed from the image outright for that reason
Validators are not bundled Each runs as a separate process the worker invokes. A flaw in a validator belongs to that project; a flaw in how CRAne invokes it, or in what it does with the output, belongs here

In scope

Anything that reads or writes data it should not, escapes the intended process boundary, or leaks a credential:

  • Authentication or authorization bypass on any route, the API included.
  • Injection of any kind, template injection included, in the interface or in reports.
  • Path traversal through an imported document, an export path, or a run directory.
  • Credential exposure. CRANE_GITHUB_TOKEN is read from the environment at the moment of use and must never reach the database, a job’s parameters, a job event, an export, or a log line.
  • Anything that makes CRAne record an approval, a scope decision, or an exception that no human made. The line between an observed fact and a recorded decision is a security property here, not only a modelling one.

Hardening the deployment you run

The defaults are safe for a laptop. Four things matter once it is not one:

  1. Set CRANE_API_TOKEN. Everything in Configure about exposure applies the moment the port is reachable by anyone else.
  2. Publish the port to 127.0.0.1, not to every interface, unless a reverse proxy with TLS is doing the listening. There is no TLS inside the container.
  3. Treat data/ as the sensitive artifact. It is the whole inventory in one file. Back it up somewhere with the same access controls, not somewhere convenient.
  4. Scan the tag you are about to run, with docker scout cves or trivy, and rebuild or repull rather than pinning an old digest forever.

Licence

CRAne is Apache-2.0. The full text and the attribution notice travel inside the image:

docker run --rm --entrypoint cat ghcr.io/oscarvalenzuelab/crane:latest /app/LICENSE
docker run --rm --entrypoint cat ghcr.io/oscarvalenzuelab/crane:latest /app/NOTICE

Dependencies keep their own licences and are listed in NOTICE. The optional Postgres backend pulls in an LGPL-3.0 library; it is an extra and is not installed in the published images.


Back to top

CRAne. The database is one SQLite file and it is yours.

This site uses Just the Docs, a documentation theme for Jekyll.