Integrate reviewed Docker-only host token guidance

Accept exact PI candidate with retained complete documentation proof; preserve authentication and scope distinctions without changing runtime authority.

Change-source: pulse-maintainer
This commit is contained in:
pulse-triage[bot]
2026-10-11 05:24:44 +01:00
3 changed files with 64 additions and 0 deletions
+16
View File
@@ -1112,6 +1112,22 @@ service is presenting the same token. Last-used metadata is not a token-use
audit and does not identify which consumer authenticated. These observations
do not prove that the running service is using that record.
**If the listed record has only Docker reporting:** `docker:report` permits
Docker/Podman telemetry, not the host module's lookup or OS, CPU and disk
reports. A normal host needs **Agent reporting** (`agent:report`) and
**Agent config fetch** (`agent:config:read`). Command execution and administrator
scope are not required. Once authentication succeeds, a missing reporting scope
returns 403 with `missing_scope`; Docker-only scope does not explain an earlier
401 or prove which credential the service presented.
The **Infrastructure → Install on a host → Generate token** flow includes both
host scopes automatically. **API Access → Create token** allows a manually
selected scope set. If the intended host record is Docker-only, retain which
screen generated it before choosing a repair; do not generate another token,
broaden its permissions, reinstall or probe the agent just to distinguish the
two flows. Inventory presence and `Never` alone establish neither successful
credential hand-off nor accepted reporting.
**If the intended record is absent:** separate server registration from the
agent's credential hand-off before another installation. On that same instance,
open **Settings → Infrastructure → Install on a host**, give one new install
@@ -1112,6 +1112,22 @@ service is presenting the same token. Last-used metadata is not a token-use
audit and does not identify which consumer authenticated. These observations
do not prove that the running service is using that record.
**If the listed record has only Docker reporting:** `docker:report` permits
Docker/Podman telemetry, not the host module's lookup or OS, CPU and disk
reports. A normal host needs **Agent reporting** (`agent:report`) and
**Agent config fetch** (`agent:config:read`). Command execution and administrator
scope are not required. Once authentication succeeds, a missing reporting scope
returns 403 with `missing_scope`; Docker-only scope does not explain an earlier
401 or prove which credential the service presented.
The **Infrastructure → Install on a host → Generate token** flow includes both
host scopes automatically. **API Access → Create token** allows a manually
selected scope set. If the intended host record is Docker-only, retain which
screen generated it before choosing a repair; do not generate another token,
broaden its permissions, reinstall or probe the agent just to distinguish the
two flows. Inventory presence and `Never` alone establish neither successful
credential hand-off nor accepted reporting.
**If the intended record is absent:** separate server registration from the
agent's credential hand-off before another installation. On that same instance,
open **Settings → Infrastructure → Install on a host**, give one new install
+32
View File
@@ -131,6 +131,38 @@ class AgentAuthDocsTest(unittest.TestCase):
"not, by itself, a reason to mint a replacement"):
self.assertIn(fact, text)
def test_docker_only_record_is_not_host_authority_or_a_401_diagnosis(self):
text = " ".join(section().split())
routes = (ROOT / "internal/api/router_routes_registration.go").read_text()
for endpoint, required in (("docker/report", "ScopeDockerReport"),
("agent/report", "ScopeAgentReport"),
("agent/lookup", "ScopeAgentReport")):
self.assertIn(
f'"/api/agents/{endpoint}", RequireAuth(r.config, '
f'RequireScope(config.{required},', routes,
)
labels = (ROOT / "frontend-modern/src/constants/apiScopes.ts").read_text()
for constant, value, label in (
("AGENT_REPORT_SCOPE", "agent:report", "Agent reporting"),
("AGENT_CONFIG_READ_SCOPE", "agent:config:read", "Agent config fetch"),
):
self.assertIn(f"export const {constant} = '{value}';", labels)
self.assertIn(f"value: {constant},\n label: '{label}'", labels)
self.assertIn(f"**{label}** (`{value}`)", text)
scopes = (ROOT / "internal/api/agenttokens/install.go").read_text()
host = scopes.split("func HostScopes(", 1)[1].split("\n}", 1)[0]
for required in ("ScopeAgentReport", "ScopeAgentConfigRead"):
self.assertIn(f"config.{required}", host)
self.assertNotIn("ScopeWildcard", host)
self.assertNotIn("ScopeSettingsWrite", host)
for fact in ("If the listed record has only Docker reporting", "`docker:report`",
"not the host module's lookup", "scope does not explain an earlier 401",
"Command execution and administrator scope are not required",
"includes both host scopes automatically", "manually selected scope set",
"retain which screen generated it", "do not generate another token",
"broaden its permissions, reinstall or probe the agent"):
self.assertIn(fact, text)
if __name__ == "__main__":
unittest.main()