Roles, quorum and the auditor view
Access Identities · Agents
| Identity | Kind | Partition | Authenticates with | Credential | Last used |
|---|---|---|---|---|---|
| orders-api | Application | prod | Workload identity | 15 min, renews | 3 s ago |
| ci-runner | Application | dev | Mutual TLS | 15 min, renews | 2 min ago |
| ledger-bot | AI agent · for team:finance | prod | Own identity | 10 min, renews | 40 s ago |
Keysdata-key-eu Actionsunwrap Limit200 / h · 173 used Approve above1,000 | |||||
| J. Park | Security officer | prod · payments | Passkey + site key | — | 09:12 |
| M. Lee | Auditor | all (read) | Passkey | — | yesterday |
Roost separates four roles the way bank HSMs do: Security Officer, Operator, User and Auditor. Physical keys control access and leave evidence; passkey seals carry authority.
| Method · Route | Purpose · subject | Effect · audit event |
|---|---|---|
POST /api/org/{slug}/roost/roles | roost.role · RoostRoleSubject(slug, "assign", role, connectedId, serial) | Assign SecurityOfficer / Operator / User to a member, for one box or all (serial null). Owner only. roost.role.assigned |
POST /api/org/{slug}/roost/roles/{id}/revoke | roost.role · RoostRoleSubject(slug, "revoke", role, connectedId, serial) | Revoke an assignment. roost.role.revoked |
PUT /api/org/{slug}/roost/quorum/{purpose} | roost.quorum.policy · RoostQuorumPolicySubject(slug, purpose, serial) | Set { role, m, n, keysRequired, axowlTicketRequired } for PowerOnOff, Move, Replace, Change, Sign or AuditExport. roost.quorum.policy_changed (carries the previous values) |
GET /api/org/{slug}/roost/audit-summary | — | Auditor view (below) |
Auditors are not assigned here: 400 USE_AUDITOR_QUORUM. They are appointed and removed by an Owner quorum through POST /api/org/{slug}/roost/auditors/{connectedId}/assign and …/revoke (see Bank-grade controls). Default policy, seeded for a new organization: power on/off, move, replace and change need 3 physical keys (customer 2 + Axowl 1), a 2-of-3 Security Officer seal and an Axowl ticket; AuditExport needs 1 Auditor.
Auditor view
GET /api/org/{slug}/roost/audit-summary returns { separationActive, callerIsAuditor, auditors[], chain { windowDays, count, sealedCount, signedCount, byType[], recent[] }, unacknowledgedRed, export { configured, updatedAt }, timePolicy { configured, updatedAt }, boxes[{ serial, ntpOk, driftMs, rtcOk, reportedAt, signatureVerified }], logFullPolicy }.
Once an Auditor is appointed, only Auditors can read it (and the organization's audit log, exports and verification); Owner and Roost Admins get 403. Before that, the Owner and Roost Admins can. chain.recent lists the last Roost audit records (roost.*) from the 3-day hot window with whether each carries a seal hash and a signature; verify any record with GET /api/v1/admin/audit/verify/{logId} (tampered: false when hash and signature hold). logFullPolicy is record-and-warn: a full in-enclosure log records and warns, it never blocks signing.