Prized docs

Teams.

What a shared workspace gets on top of one account: roles, policies that bind members, quiet hours, an audit log with a scheduled export, secrets scoped to boxes or members, and a live activity page.

A workspace is one account for a team. This page is what the team gets on top of it. Every rule here is off until the owner turns it on, and nothing here changes a workspace of one.

Roles

RoleCan
OwnerEverything: billing, the domain and invite link, roles, policies, quiet-hours exemptions, the audit export, removing members. No policy binds the owner; ownership never moves.
MemberEvery box, secret, snapshot and environment; reads the audit log, the activity page and the policies. Policies bind members.
ContractorA member fenced to the boxes they own. Policies bind contractors too.

The owner changes a role from Dashboard → Workspace → Members; each change is a member.role audit row. Demoting a member to contractor revokes the phone passwords and browser tickets they minted for boxes they do not own and closes their tunnels to those boxes.

A contractor sees and reaches only the boxes they created; another member's box reads as not found everywhere, and so do its snapshots: a contractor launches from, restores, forks and names templates of their own boxes' snapshots only, and a template name held by a snapshot they cannot see is not theirs to move (409 template_taken). They can list environments and upgrade their own boxes, but not create, edit or delete one (403 not_allowed). Their new boxes are always Restricted (safe for third parties), so none of your credentials reach them (Safe for third parties); an API create with "restricted": false is 403 policy_denied, rule contractor_restricted. The audit log, the members list, the policies and workspace secrets answer 403 not_allowed, and a secret reaches their box only when granted to it or to them.

A box belongs to the member who created it; boxes Prized creates for you belong to the owner (ownerUserId on the box object).

Policies

Dashboard → Workspace → Policies: the owner edits, members read, contractors see Your role does not include the workspace policies. Every rule is off by default and binds members and contractors, never the owner, except quiet hours, which pause every box.

RuleKeyRangeWhat it does
Spend per membermemberSpendCapUsd$1 to $1,000,000 a cycle, whole dollarsCaps what one member's boxes draw in a billing cycle. Checked on create, wake and resize.
Boxes per membermemberBoxLimit1 to 100Caps a member's live boxes (running or paused). Checked on create, fork and wake.
Largest size per membermemberMaxTierAny sizeThe biggest size a member may create or resize to.
Auto-pause floorautoPauseFloorMin30 minutes to 7 daysMembers' boxes must auto-pause within this long of going idle; longer or off is refused.
Quiet hoursquietHoursOne window a day, per weekdayPauses every running box inside the window; see Quiet hours.
Audit log retentionauditRetentionDays7 to 365 days, default 90How long audit rows are kept.

A refused action answers 403 policy_denied with rule and message; the CLI prints the message (exit 5), the dashboard shows it beside the control. The spend cycle is the month ending at your plan's period end, or the UTC calendar month without a plan; spend is attributed to the box's owner while the workspace pays one bill. The box limit refuses a wake only when the member is already over it. Under a floor, a new box with no auto-pause setting takes the floor, a box from before the floor is paused as if it had it, and a member's Auto-pause menu stops there.

GET /api/v1/workspace/policies reads the rules; changing them is dashboard-only and writes a policy.update row (API reference).

Quiet hours

A window each day in which every box in the workspace is paused, the owner's included: start and end as HH:MM, the weekdays it applies to, the weekdays that are quiet all day, and one IANA timezone. A window that ends before it starts crosses midnight and belongs to the day it started on.

  • A box woken inside the window stays up 15 minutes, then is paused again.
  • Exempting a box. The owner marks it Exempt under Quiet hours on its box page (PATCH /api/v1/boxes/{id} with {"quietHoursExempt": true}; anyone else is 403 not_owner).
  • In the log. Each pause is a box.pause row with reason quiet_hours.

A quiet-hours pause is exactly a pause: sleep rate from that moment, disk kept, processes per the size table.

Audit log

Dashboard → Workspace → Audit: who did what, on which box, when. Owners and members read it; contractors see Your role does not include the audit log. The page filters by member, box, kind and range, pages 100 rows at a time, downloads a CSV of up to 50,000 rows, and, for owners, holds the scheduled export (Dashboard: Audit).

Two origins

server: the control plane saw it. Box lifecycle and settings, CLI tokens, snapshots, environments, secrets, membership and roles, policies, close and reopen, the export settings, every user SSH certificate minted, and every browser terminal opened.

client, shown as reported: the CLI or the box told us. The control plane never sees a command run over ssh, a file copied, or a prompt started, so prized exec, prized cp, prized prompt, prized desktop and the box's edge API post a row afterwards. A reported row is a claim by a credential in your workspace, not an observation: an offline or older CLI posts none, and nothing checks it against what ran.

Every row names the member (actorUserId) and the credential that acted (actorTokenId); browser terminal and phone sessions are attributed to the member who opened them.

What is recorded

Server-observed kinds. Names and hosts, never values, contents, keys or tokens:

KindDetail
box.createtier, region, hostname, restricted, from (a snapshot or template)
box.wake, box.delete
box.pausereason: quiet_hours, auto_pause, pause_deadline, or none for a pause you asked for
box.resize, box.move_regionfrom, to
box.settingsThe keys changed
box.envcount
box.forkfrom, fromHostname, to, toHostname, tier, snapshotId, keepSnapshot
box.connectOne per SSH certificate minted, so every connection starts with one: keyId, and scope (terminal, monitor, mobile-ssh) for a browser or phone session
box.sessionA browser terminal opened: scope, ticketId
snapshot.createsnapshotId, name, kind, templateName
snapshot.delete, snapshot.template
environment.create, environment.update, environment.deleteUpdate carries change (the kind of edit) and key (the var, file, repo or toggle); never a value or a file body
secret.create, secret.update, secret.delete, secret.mount, secret.unmount, secret.grant, secret.revokeNames and hosts
member.addvia: first_contact, domain, invite
member.remove, member.leave, member.role, invite.rotate, invite.revoke
token.createname, tokenId
token.revoketokenId, or all: true with count
policy.updatekeys
audit.exportaction (set or clear), host
workspace.settings, workspace.retention, workspace.reopen
workspace.closepurgeAfter, boxesSuspended, membersRemoved, cliTokensRevoked

Client-reported kinds. Never stdout, stderr, file contents, the prompt beyond its first line, or a VNC password:

KindDetailReported by
execcommand (up to 512 characters), cwd, detached, processIdprized exec when it runs something; POST /exec
file.upload, file.downloadpath, bytes, files, inline, directoryprized cp after a copy that moved something; the edge's file routes
promptfirstLine, provider, runId, queuedprized prompt; POST /prompts
desktop.startmode, profileprized desktop and prized browser (not --stop); the dashboard's Desktop tab

From the CLI and the API

Terminal
prized team log                                   # the last 24 hours
prized team log --since 7d --kind exec,prompt --member ana@acme.com

prized team log prints TIME, MEMBER, KIND, BOX, DETAIL and ORIGIN (CLI: Team). GET /api/v1/audit takes the same filters and pages by before and limit; format=csv streams up to 50,000 rows with the columns id,at,kind,origin,actor_kind,actor_user_id,actor_token_id,box_id,detail (API reference).

Scheduled export

Owners set a destination in the Export section of the Audit page: a URL and a write-only secret, with a status line showing the last delivery and the last error.

  • The destination. An https URL of up to 2,048 characters with no credentials or fragment, on a public host, and a secret of 16 to 256 characters, encrypted at rest and never shown again. Private, loopback and link-local addresses are refused when you save the destination and again before every delivery. The copy is yours, at your endpoint; there is no hosted destination.
  • Each delivery. Once an hour, one POST per batch: the JSON body {"v": 1, "workspaceId": "...", "events": [...]}, oldest first, up to 500 events per batch and 20 batches per pass; headers Content-Type: application/json, X-Prized-Signature: sha256=<hex HMAC-SHA256 of the body under your secret>, X-Prized-Event-Id-From and X-Prized-Event-Id-To. Ten seconds per request; redirects are never followed.
  • Acknowledging. Any 2xx advances the cursor; anything else lands on the status line and the same batch is sent again next hour: at-least-once, in order, so dedupe on id. Delivery starts with the rows newer than the moment you saved the destination.
Terminal
openssl dgst -sha256 -hmac "$SECRET" body.json   # must equal the X-Prized-Signature hex

Setting or clearing the destination is itself an audit.export row.

Retention

Rows are kept 90 days by default; the owner sets 7 to 365 days under Policies. A row outlives the token, the member and the box it names, and goes when the workspace is erased (Data retention). Zero data retention does not shorten the window; with it on, the exec, file.upload, file.download and prompt rows keep no detail (the page shows no detail kept (zero data retention)).

Scoped secrets

A secret is workspace-wide until you grant it to someone.

  • No grants: every box may mount it, except a contractor's.
  • The first grant narrows it to the boxes named and the boxes owned by the members named; removing the last grant makes it workspace-wide again. A contractor's box gets nothing it was not granted, to the box or to its owner. A secret created with an Available to choice (or with grants on the API) is born with those grants, and a connector's secret is born granted to the box you connected it to.
  • Revoking is quick: the box loses the value within 15 seconds, and the mount shows no longer granted until you unmount it.

Grant from the dashboard (Available to on the new-secret form, Details on a row), the CLI (prized secrets grant NAME --box BOX or --member EMAIL; CLI: Secrets), or the API (POST /api/v1/secrets/{id}/grants; a mount the box may not have is 403 secret_not_granted; API reference).

Usage

One use is one HTTPS request to an allowlisted host in which the broker swapped the placeholder for the value, counted whatever the upstream answered; a refused plain-HTTP request, a host outside the allowlist, or a request without the placeholder is not counted. Recorded: the placeholder, the host, the count, and the first and last time; never a path, header, body or value. Counts are a floor, because the box reports them in batches and a restart can lose the last one. Read them under Details on the Secrets page, with prized secrets usage NAME, or from GET /api/v1/secrets/{id}/usage.

Team activity

Dashboard → Workspace → Activity shows what the team is doing right now: running boxes with their owner, idle time, attached sessions, last prompt and exec, and spend; members with their boxes, sessions, last active time and spend; and the newest 50 audit rows (Dashboard: Activity). Contractors see their own boxes only.

  • Attached session: a device connected to a box (the CLI, a browser terminal, or a phone), counted while its tunnel is open and for at most 12 hours. It says a device is attached, never what is typed or shown.
  • Last prompt, last exec: from reported rows, so an older CLI leaves them blank.
  • Today: since UTC midnight. Cycle: the plan's period, or the UTC calendar month without a plan.
  • Spend: metered compute attributed to the box that drew it, in whole UTC-hour buckets. Attribution, not billing: the workspace pays one bill.

prized team status prints the same as two tables and a one-line summary; --json prints the object GET /api/v1/team/status answers (CLI: Team, API reference).

What is not covered

  • What happens inside an ssh session. Only the connect is recorded (box.connect), never the commands typed in it; reported rows are the client's claim, not a check.
  • Tokens that belong to nobody. A CLI token from before workspaces existed is bound by no per-member policy and its rows name no member; only the owner can retire it (CLI tokens).

Something unclear or out of date?

On this page