Device create was left off the ITAM surfaces because enrollment
returns a one-shot token. Add createDevice so automations can issue
PENDING devices with the enrollment payload.
Signed-off-by: Ludovic Vielle <ludovic@probo.com>
Devices were only available through GraphQL and the agent API. Add
list/get/revoke/delete/set-owner across MCP, prb, and n8n, with latest
postures nested on list and get responses.
Signed-off-by: Ludovic Vielle <ludovic@probo.com>
Delete and DeleteExpired omitted Scoper, breaking the
tenant-isolation pattern used elsewhere in coredata. Pass a
tenant scope from ExchangeEnrollmentToken and NewNoScope from
the ITAM GC so cross-tenant cleanup stays explicit.
Signed-off-by: Ludovic Vielle <ludovic@probo.com>
ITAM GraphQL actions were never registered in the shared OAuth2
scope registry, so bearer-token callers failed closed even when
role policies allowed them. Add v1:itam / v1:itam:read mappings,
register them in probod, and sync the CLI client scopes.
Signed-off-by: Ludovic Vielle <ludovic@probo.com>
Admins could only revoke devices, so never-enrolled and revoked
inventory rows piled up with no way to remove them. Soft-delete
is limited to REVOKED devices (revoke first), and ITAM GC now
hard-deletes PENDING/REVOKED orphans with no API key, postures,
or valid enrollment token—including user tombstones without
history.
Signed-off-by: Ludovic Vielle <ludovic@probo.com>
Pass/fail was the main device UI signal, but operators need
the agent's observed value. Expose a formatted value per
check, show current postures on the device page, and replace
the Postures tab with paginated report history grouped by
agent push time. Status stays in the model for later rulesets.
Signed-off-by: Ludovic Vielle <ludovic@probo.com>
viewer.enrolledDevices shared DeviceConnection with the admin
org list, so totalCount had to authorize with both
employee-device:list and device:list. Mirror
EmployeeDocumentConnection: a dedicated EmployeeDeviceConnection
without totalCount, and keep DeviceConnection.totalCount for
the org fleet only. Cover assumed-session device:get IDOR in e2e.
Signed-off-by: Ludovic Vielle <ludovic@probo.com>
The /enroll wait UI polled device state via node(), which
requires an assumed org session, so confirmation never
succeeded for unassumed viewers. Expose viewer.enrolledDevice
behind itam:employee-device:get (own-device, skip assumption)
and point the poller at it.
Signed-off-by: Ludovic Vielle <ludovic@probo.com>
Introduce device, posture, and enrollment-token entities with ITAM
service policies for agent-managed fleet inventory.
Signed-off-by: Ludovic Vielle <ludovic@probo.com>