cyberwoven / telemetry
Exposes a lightweight, API-key protected HTTP endpoint reporting basic information about installed modules.
Package info
bitbucket.org/cyberwoven/telemetry
Type:drupal-module
pkg:composer/cyberwoven/telemetry
Requires
- php: >=8.1
Requires (Dev)
None
Suggests
- drush/drush: For CLI key management via telemetry:set-key and telemetry:key-status
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-03 16:50:41 UTC
README
A standalone module. Exposes a single HTTP endpoint that reports whether a given module is installed and its version — read directly from Drupal's own module system, no SSH required.
Where this goes
Copy this whole telemetry/ directory into your custom modules
directory, e.g.:
modules/custom/telemetry/
Installing
drush en telemetry
Set up the API key (once per site)
You can do this either from the command line or from the UI — both go through the same underlying logic, so it doesn't matter which you use.
Command line:
drush telemetry:set-key
Generates a random key, stores it via Drupal's State API (not config — so it won't end up in an exported config file), and prints it once.
Admin UI:
Visit Configuration → System → Telemetry API key
(/admin/config/system/telemetry), gated behind the
administer telemetry api key permission. Click "Generate key" —
the new key is shown once, in the status message after submitting.
Either way: copy the key somewhere safe immediately. There's no way
to read it back out later — if you lose it, generate a new one and
update sites.yml (or wherever you're tracking it) to match. Generating
a new key immediately invalidates the old one.
To check whether a key is set without revealing it:
drush telemetry:key-status
Usage
GET /telemetry/check?module=webform
X-API-Key: <the key from above>
Success:
{
"module": "webform",
"status": "Enabled",
"version": "8.x-6.2"
}
status is one of:
"Enabled"— installed and turned on"Disabled"— present in the codebase but not installed"Not found"— no such module in the codebase at all
Missing/wrong API key → 401:
{ "error": "Unauthorized" }
No key configured on this site yet → 500:
{ "error": "No API key has been configured on this site. Run: drush telemetry:set-key, or visit /admin/config/system/telemetry." }
Missing/invalid module parameter → 400:
{ "error": "Missing or invalid \"module\" query parameter. Use lowercase letters, numbers, and underscores only." }
How it's put together
ApiKeyManager(src/ApiKeyManager.php) is the one place that generates, stores, and verifies the key. Both the drush command and the admin form call it — neither duplicates the logic.StatusControllerchecks the key viaApiKeyManager::verify()(constant-time comparison) before doing anything else, and fails closed (500) if no key has ever been set.SettingsFormis a normal Drupal form behind a real permission — follows the standard submit → redirect → GET flow, so the generated key only ever appears in a transient status message, never on a page that could be reloaded or cached with the key still showing.
Security notes
- Always call this over HTTPS in production — the API key travels in a plain header, so an HTTP connection would expose it in transit.
- The key is compared with
hash_equals()(constant-time), so a wrong guess can't be timed to leak information about the correct value. - The check endpoint's access is enforced entirely inside the controller
(
_access: 'TRUE'in routing), by design — it isn't meant to require a logged-in Drupal user, since it's called by an external script. The admin settings page is the opposite: a real permission-gated route, since that one's for you, logged in. - Rotate the key any time (CLI or UI) — no restart or deploy needed, it takes effect on the next request.
- Consider also restricting
/telemetry/checkby IP at the web server level (Apache/Nginx config) as a second layer, if that's easy to do on your hosting — defense in depth, not a replacement for the API key.