Keymaker handles OVHcloud API credentials and can revoke keys. Security reports are welcome and taken seriously.
From 1.0, the latest minor release of the latest major version receives security fixes, as
the latest minor release did during 0.x. A release in 1.x changes nothing that the
compatibility promise covers, so moving to the latest one is always
safe. Upgrade to it before reporting, and mention the version you run (keymaker --version).
Report vulnerabilities privately, through GitHub's private vulnerability reporting:
https://github.com/kentrow/keymaker/security/advisories/new
Never open a public issue, discussion or pull request for a vulnerability.
Never send a real credential, not in a report, a log excerpt or a screenshot: no
application key, application secret, consumer key or ovh.conf content. If a report needs
one to be reproduced, describe the access rules it had instead. If a credential was exposed,
revoke it on OVHcloud first.
A useful report includes the version, how Keymaker runs (image, Compose, source), the steps to reproduce, the impact you expect, and any proof of concept that uses placeholder values.
Keymaker is maintained by one person, in their own time.
- Acknowledgement within 7 days.
- An assessment, and a fix or mitigation plan, as soon as the issue is understood, typically within 30 days.
- A GitHub security advisory published with the fix. Reporters are credited unless they ask not to be.
In scope: Keymaker itself, meaning the code in this repository, the container image published
at ghcr.io/kentrow/keymaker and its documented configuration.
Out of scope:
- The OVHcloud API, its authentication, the
createTokenpage and any other OVHcloud service. Report those to OVHcloud. - An attacker who already controls the machine running Keymaker or can read its configuration file.
- A key after it has been created and deployed elsewhere.
- Deployments that ignore the documented setup, for example publishing the port on a routable address.
The details, and how each point is implemented, are in docs/ARCHITECTURE.md.
- Local and single-user. Anyone who can reach the interface can act with the management
credential. The binary listens on
127.0.0.1by default. The image listens on0.0.0.0inside its network namespace, so the host-side port mapping must be bound to127.0.0.1. - Access token. A random token is generated at every start, printed once in the startup
address, and required on every route except
GET /healthz, whose body is a fixedok. - Page token. Every mutation requires a second token in a custom header, so a page from another origin, including another local service, cannot drive a revocation.
- Browser hardening. A strict content security policy without
unsafe-inlineorunsafe-eval, framing forbidden, no referrer, no resource loaded from outside the binary. - No persistence. Nothing is written to disk. The configuration file is read-only. Keys created through Keymaker are issued on the OVHcloud page, and their values never reach the process.
- Redacted logs. The application secret and the consumer key are removed from every log record by the logging pipeline itself.
- Revocation guards. The ordinary revocation and the bulk revocation refuse the credential Keymaker authenticates with, checked against the API at the moment of the call. It can only be ended on purpose, through its own way out, "Revoke and leave", which names no key. A single revocation requires the identifier to be typed. The bulk revocation only touches expired and refused keys, selected by the server.
- Address guard. The credential Keymaker authenticates with is only restricted to a list covering the address the process is seen from, looked up at the moment of the change. With the lookup switched off, it is not restricted from here at all.
- Closed outbound set. The OVHcloud API of the configured endpoint, and
api.ipify.orgonly when the reader asks for the public address or restricts the key Keymaker uses.KEYMAKER_IP_LOOKUP=offremoves that call. - Least privilege. The management key needs read rules on credentials and applications, and
optional delete rules. The rule that changes the addresses of a key is left out of the key
Keymaker suggests, since it can widen the reach of any key. Never grant it
/me/*or/*. - Hardened image. Distroless, non-root, meant to run with a read-only filesystem, no
capabilities and
no-new-privileges.
- Run the container as documented: port published on
127.0.0.1, configuration mounted read-only,--read-only,--cap-drop=ALL,--security-opt no-new-privileges. - Keep
ovh.confout of version control and readable by its owner only (chmod 600), and run the container as that owner with--userrather than widening the file permissions. - Give the management key an expiration, restrict it to your address, and leave out the delete rule if you only need the inventory.
- The startup log contains the access token. Treat that output as sensitive for as long as the process runs.