Skip to content

Commit e4d2321

Browse files
committed
fix(daemon): fail closed when the auth hook is silent about tenant
An auth hook that ran but returned no tenantId opted the deployment into tenant attestation; falling back to the client's own claim (RPC body meta.tenantId, aux-route x-agent-device-tenant header) let a holder of one valid shared token impersonate any tenant on /rpc and on the diagnostics/ upload/download routes. resolveTrustedTenant() in the new src/daemon/server/tenant-trust.ts is now the single seam both surfaces go through and the only place that computes the resulting identity: hook attests -> use it; no hook configured -> keep today's client-declared behavior (loopback/dev unchanged); hook configured but silent with a client-declared tenant -> refuse (401) instead of trusting the claim, and no raw client-declared metadata survives into the dispatched request in that case either. Fixes #2095
1 parent 2e87347 commit e4d2321

8 files changed

Lines changed: 498 additions & 16 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22

33
## Unreleased
44

5+
- Security (daemon, remote/proxy HTTP only): when `AGENT_DEVICE_HTTP_AUTH_HOOK` is configured and a
6+
request's hook result does not attest a `tenantId`, the daemon no longer falls back to trusting a
7+
client-declared tenant — RPC body `meta.tenantId`, or the `x-agent-device-tenant` header on the
8+
upload/artifact-download/diagnostics routes. A request that also declares a tenant is now refused
9+
(401) instead of running as whichever tenant the caller claimed; a request that declares none
10+
proceeds unscoped, as before. This closes a shared-token impersonation path in multi-tenant
11+
deployments. Deployments with no hook configured (the local loopback CLI) are unaffected. A hook
12+
that needs per-request tenant scoping must attest `tenantId` in its own return value.
513
- Breaking (0.21): removed aggregate performance compatibility (`perf`, `perf sample`, `perf metrics`, the `metrics` alias, optionless `client.observability.perf()`, and SDK `area: 'metrics'`). Use `perf frames`, `perf memory sample`, `perf cpu profile start|stop|report`, or `perf trace start|stop`; removed CLI and raw daemon forms fail with this migration guidance.
614
- Breaking (0.21): removed legacy batch JSON steps with `positionals`/`flags`. Use `{"command":"...","input":{...}}`; rejected steps now include a concrete structured example.
715
- Breaking (0.21): removed the deprecated Node client `command.rotate` wrapper and its `RotateCommandOptions` / `RotateCommandResult` exports. Use `command.orientation`; the already-removed CLI `rotate` form keeps its targeted migration error.

src/__tests__/test-utils/env.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export function restoreEnv(key: string, previous: string | undefined): void {
2+
if (previous === undefined) delete process.env[key];
3+
else process.env[key] = previous;
4+
}

0 commit comments

Comments
 (0)