Skip to content

Add deviceagent (WIP)#1197

Draft
gearnode wants to merge 21 commits into
mainfrom
cursor/88f61fa7
Draft

Add deviceagent (WIP)#1197
gearnode wants to merge 21 commits into
mainfrom
cursor/88f61fa7

Conversation

@gearnode

@gearnode gearnode commented May 17, 2026

Copy link
Copy Markdown
Contributor

Summary by cubic

Adds device posture end-to-end with a browser-based enrollment flow using a probo:// deep link. Ships a macOS/Windows tray helper, REST endpoints, new device models, and Console pages; introduces an itam service, tracks the enrollment token, and removes the token list UI.

Tests +292 -0

  • Unit tests for enroll URL parsing, server URL normalization, and enrollment state marker.
  • Regions manifest test keeps Console URLs aligned with server constants.

Coredata +1156 -2

  • New entities and enums: Device, DevicePosture, DeviceEnrollmentToken, platform, posture status, ordering.
  • Migrations for device and posture tables; add devices.enrollment_token_id with index; make agent-run lease migration idempotent.
  • Entity registry updated; rename assigned-user field to OwnerID.

GraphQL API +807 -9

  • Agent REST API at /api/agent/v1 for heartbeat and posture (device API key auth).
  • Console GraphQL: device types, latest postures, organization device connections, and deviceEnrollmentStatus query.
  • Device auth context and server wiring; removed no-op CSRF bypass patterns for the agent API.

Service +2026 -751

  • pkg/deviceagent: API-key enrollment via enroll-url, first-boot heartbeat activation, and a macOS/Windows tray helper that opens /enroll; launchd and autostart helpers; enrollment marker.
  • New itam service for devices/tokens/posture with RBAC; wired into probod.
  • Updated pkg/llm model registry.

App: console +1736 -3

  • New /enroll page with org picker and one‑click deep‑link; polling for status.
  • Organization Devices list/detail with latest posture; Employee “Devices” tab with token creation and streamlined instructions.
  • Removed the enrollment token list; added sidebar link and routes.

Agents +19 -0

  • Release notes updated for CGO tray builds and platform behavior.

Other +784 -83

  • CI/release workflows: CGO tray builds for macOS/Windows; cross‑compile updates.
  • GNUmakefile: portable CPU detection; target‑OS‑driven CGO for probo-agent.
  • macOS installer: Swift URL‑handler app and revised scripts; Windows: register-protocol.ps1 for probo://; go.mod adds fyne.io/systray.

Written for commit 4fc0e83. Summary will update on new commits.

Review in cubic

Comment thread pkg/itam/service.go Fixed
Comment thread pkg/itam/service.go
// hashSecret hashes a token/api-key value the same way for storage and
// lookup. SHA-256 is sufficient: the secret is high-entropy random.
func hashSecret(secret string) []byte {
sum := sha256.Sum256([]byte(secret))
@gearnode gearnode requested a review from a team May 22, 2026 23:50
import { cookieBannerRoutes } from "./pages/organizations/cookie-banners/routes";
import { riskAssessmentRoutes } from "./pages/organizations/risk-assessments/routes";
import { riskRoutes } from "./pages/organizations/risks/routes";
import { deviceRoutes } from "./pages/organizations/devices/routes";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚫 [eslint (apps/console)] reported by reviewdog 🐶
./pages/organizations/devices/routes import should occur before import of ./pages/organizations/risk-assessments/routes import-x/order

gearnode added 17 commits June 8, 2026 15:34
Signed-off-by: Bryan Frimin <[email protected]>
Signed-off-by: Bryan Frimin <[email protected]>
Signed-off-by: Bryan Frimin <[email protected]>
Signed-off-by: Bryan Frimin <[email protected]>
Signed-off-by: Bryan Frimin <[email protected]>
Signed-off-by: Bryan Frimin <[email protected]>
Signed-off-by: Bryan Frimin <[email protected]>
Signed-off-by: Bryan Frimin <[email protected]>
Introduce probo-agent tray with region-aware enrollment prompts,
world-readable enrollment state, and elevated install handoff so
users enroll from the menu bar or system tray instead of the CLI.

Signed-off-by: Bryan Frimin <[email protected]>
Ship a SwiftUI probo-agent-enroll-ui helper bundled in the macOS
pkg, defer token entry to post-install tray launch, and polish
installer copy for the menu bar enrollment experience.

Signed-off-by: Bryan Frimin <[email protected]>
Mirror the macOS enrollment experience with a WinForms
probo-agent-enroll-ui helper, shared regions.json manifest, and
a Go test that keeps console URLs aligned with server_url.go.

Signed-off-by: Bryan Frimin <[email protected]>
Enable CGO tray builds on macOS and Windows runners, bundle
enrollment UI helpers in Windows release archives, and document
the new install and release paths in the changelog and contrib
guide.

Signed-off-by: Bryan Frimin <[email protected]>
Add an enrollment_token_id column to devices so an enrolled device can
be traced back to the token that provisioned it, and persist it on both
initial enrollment and re-enrollment.

Surface progress through a new deviceEnrollmentStatus query that reports
whether a token has only been created, has produced an enrolled device,
or has received its first posture activity. This lets the console drive a
browser-based enrollment flow that polls for completion.

Batch the device and enrollment-token authorization attribute lookups so
the node resolver can authorize devices directly, and add the supporting
coredata loaders.

Signed-off-by: Bryan Frimin <[email protected]>
Guard the lease_generation/lease_owner changes with IF NOT EXISTS and
IF EXISTS so the migration can be re-applied on databases that already
ran an earlier version of it, then drop the temporary default once the
column is populated.

Signed-off-by: Bryan Frimin <[email protected]>
Introduce an /enroll page where an employee picks their organization and
clicks a single button to hand off to the locally installed Probo agent
via a probo:// deep link, then watches enrollment progress in the browser.

Demote the manual token instructions to a collapsible section and point
the employee devices page at the new browser flow as the recommended
path, keeping CLI/MDM enrollment available for advanced setups.

Signed-off-by: Bryan Frimin <[email protected]>
Replace the standalone enrollment UI helpers (the Swift app and the
.NET/C# project) with a browser-driven flow. The console opens a
probo://enroll?server=...&token=... deep link that the agent handles
through a hidden enroll-url command, which starts the elevated install
on macOS and Windows.

Add ParseEnrollURL to validate the deep link, a macOS URL-handler app
bundle, and a register-protocol.ps1 script that registers the probo://
scheme for the current Windows user. The tray helper now opens /enroll
in the browser instead of collecting tokens locally, and systray becomes
a direct dependency.

Signed-off-by: Bryan Frimin <[email protected]>
Drive CGO from the target GOOS instead of the build host so the tray
binary cross-compiles correctly, and detect the CPU count portably on
macOS and other non-Linux hosts.

Drop the dotnet setup and enroll-ui build steps from the release
workflow now that the .NET helper is gone, shipping register-protocol.ps1
in Windows archives instead.

Signed-off-by: Bryan Frimin <[email protected]>
gearnode added 4 commits June 9, 2026 16:08
Go's CrossOriginProtection only denies an unsafe request when the
browser reports it as cross-origin via Sec-Fetch-Site, or, as a
fallback, when an Origin header is present and untrusted. The
probo-agent binary is a plain Go HTTP client that sends neither
header, so those requests are allowed by default and never reach
the cross-origin check.

The four agent-API bypass patterns therefore matched nothing and
only added confusion next to the OAuth2, SAML, and cookie-banner
bypasses that genuinely handle browser and external origins.

Signed-off-by: Bryan Frimin <[email protected]>
The employee devices page listed existing enrollment tokens, but the
list provided no real value: tokens are write-once secrets shown only at
creation time, and surfacing the stale metadata afterwards just added
noise and a revoke control nobody used.

Drop the deviceEnrollmentTokens field, its resolver, and the now-orphaned
connection types and service lookup. On the frontend, remove the token
table and the row component, and simplify the create form so it no longer
inserts into a Relay connection that no longer exists.

Signed-off-by: Bryan Frimin <[email protected]>
The device column and Go field tracked the identity tied to a device
under the misleading name AssignedUserIdentityID, which implied an
ongoing assignment relationship. Rename it to OwnerID (db owner_id),
including the partial index and all queries, so the name reflects the
device owner directly.

Signed-off-by: Bryan Frimin <[email protected]>
Signed-off-by: Bryan Frimin <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants