1.2.0 2026-03-21 — Multi-Tenant Authentication
Release Notes
⚠️ BREAKING CHANGES — This release introduces multi-tenant authentication.
Existing single-user configurations require migration (see below).
Breaking Changes
Metric.created_by removed — replaced by user_id + agent_id
The created_by field has been removed from Metric. It is replaced by:
user_id— the authenticated user identity (from static token or JWTsubclaim)agent_id— the MCP bridge session UUID (fromX-Detrix-Client-Idheader)
Migration: Re-add metrics after upgrading. Pre-migration metrics stored with
user_id = NULL are not accessible to non-Admin users (see note below).
Config: api.auth.bearer_token removed
The top-level bearer_token config key is no longer supported.
Before (v1.0):
[api.auth]
bearer_token = "my-secret-token"After (v1.1):
[api.auth]
mode = "simple"
[[api.auth.users]]
token = "my-secret-token"
user_id = "default"
role = "admin"Starting the daemon with no [api.auth] section auto-generates a secure token
(stored at ~/detrix/auth-token) — no config change needed for single-user setups.
Config: Connection.created_by renamed to user_id
The created_by field on the Connection entity has been renamed to user_id
for consistency with Metric.user_id. A database migration (003_connection_user_id.sql)
renames the column automatically on startup.
Security Fixes
- Constant-time token comparison — Bearer tokens are now compared using
subtle::ConstantTimeEqto prevent timing side-channel attacks. - Debug output token redaction —
StaticUser.tokenis redacted as
[REDACTED]inDebugoutput to prevent token leakage in logs/panics. - JWT
subclaim required — JWTs without asubclaim are now rejected
with HTTP 401 / gRPC Unauthenticated. Previously, missingsubwould silently
use"anonymous"asuser_id, potentially granting shared identity to all
un-identified callers.
Bug Fixes
- Bridge
disable_my_metricsused wrong field — The MCP bridge now correctly
identifies its own metrics usingagentId(the bridge's per-session UUID)
instead ofuserId. Previously, the bridge could accidentally miss metrics or
match other agents' metrics. - NULL
user_idstored as"system"— Metrics with no authenticated user
now storeuser_id = NULLin the database instead of the sentinel string
"system". This prevents scope mismatch when auth is later enabled. - Non-deterministic
find_by_locationordering —SELECT … LIMIT 1now
includesORDER BY created_at ASCto return a deterministic result. migrate_connection_idmock misseduser_idin conflict detection — The
in-memory mock now includesuser_idin the occupied-location set, matching
the real SQLiteUPDATE OR IGNOREbehavior.
Validation Improvements
- Duplicate bearer tokens in
[[api.auth.users]]are now rejected at startup. - Duplicate
user_idvalues in[[api.auth.users]]are now rejected at startup. - Token length is now limited to 512 characters.
- Starting with the old
bearer_token = "..."config now produces a clear error
message pointing to the migration guide, instead of a confusing startup failure. - Tenant ID hardening —
user_idandagent_idnow reject whitespace-only
strings, control characters, and the reserved__*__pattern (e.g.,__system__,
__admin__). Invalid values return HTTP 400 / gRPCINVALID_ARGUMENTwith
error code1008(INVALID_TENANT_ID).
Performance
- Pre-computed token hashes — SHA-256 hashes of static user tokens are computed
at construction time instead of on every auth request, eliminating per-request
allocation in the authentication hot path. - Zero-allocation public endpoint matching —
is_public_endpoint()no longer
allocates aStringper endpoint per request. - SQL-level group summaries —
list_group_summaries_scopedfor non-admin users
now uses a SQLGROUP BY … WHERE user_id = ?query instead of fetching all user
metrics into memory.
Infrastructure
DETRIX_FILE_SERVER_HOSTenv var — The MCP bridge--file-server-hostCLI
argument can now also be set via theDETRIX_FILE_SERVER_HOSTenvironment variable
(CLI argument takes priority).- Configurable attach failure window — The DAP attach/launch failure detection
timeout (default 500ms) can now be configured viaattach_failure_window_msin
[adapter]config. Useful for high-latency remote/Docker scenarios.
Notes
Pre-migration metrics are not visible to non-Admin users
Metrics stored before the multi-tenant upgrade have user_id = NULL in the
database. After the upgrade, only Admin-scoped callers can read these metrics.
Non-Admin users will not see them in list_metrics / get_metric results.
Resolution: Re-add the metrics after the upgrade. They will be associated
with the authenticated user and become visible normally.
This behavior is intentional by design — there is no safe way to
automatically assign ownership to an anonymous metric after the fact.
Install detrix 1.2.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/flashus/detrix/releases/download/v1.2.0/detrix-installer.sh | shInstall prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/flashus/detrix/releases/download/v1.2.0/detrix-installer.ps1 | iex"Install prebuilt binaries via Homebrew
brew install flashus/tap/detrixDownload detrix 1.2.0
| File | Platform | Checksum |
|---|---|---|
| detrix-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| detrix-x86_64-apple-darwin.tar.xz | Intel macOS | checksum |
| detrix-x86_64-pc-windows-msvc.zip | x64 Windows | checksum |
| detrix-x86_64-pc-windows-msvc.msi | x64 Windows | checksum |
| detrix-aarch64-unknown-linux-gnu.tar.xz | ARM64 Linux | checksum |
| detrix-x86_64-unknown-linux-gnu.tar.xz | x64 Linux | checksum |