Valta Docs

Team roles & permissions

Available now. Team invites and role management live at /dashboard/enterprise/workspace. Enforced server-side on every protected route via a single shared permission check — not duplicated per-route logic that can drift.

Roles

Four roles, ranked in this order — each higher role includes everything below it:

RoleRank
Owner4
Admin3
Manager2
Viewer1

An account with no team members is unaffected by any of this — its own user is simply treated as the Owner of its own workspace.

What each role can actually do

This is the real permission matrix — the exact table the server checks on every request, not marketing copy that can drift from it.

CapabilityOwnerAdminManagerViewer
View wallet balance
Move money out (withdraw / send / deposit)
Fund or create an agent wallet
View spending policies
Create or edit spending policies
View approvals
Decide an approval (approve/reject)
View agents
Create or edit agents
Freeze an agent
Delete an agent
View team members
Invite / remove team members
Connect an integration
Disconnect an integration
Manage API keys
View billing
Change plan / payment method
Transfer workspace ownership
View audit trail
Export audit trail

Deleting an agent is Owner/Admin only, not Manager — destructive, irreversible actions default to the stricter reading even where a capability is otherwise Manager-accessible.

How it's enforced

Every protected route follows the same shape, not ad-hoc role checks per file:

  1. Identify the calling user from their session.
  2. Resolve their real workspace — an invited Manager/Admin/Viewer operates on the workspace owner's data (wallet, agents, policies), not their own empty account. This wasn't always true: an earlier version of several routes used the calling session's own user ID directly, meaning an invited Manager deciding an approval would have looked up (and debited) their own wallet instead of the workspace's — fixed, and now the standard pattern everywhere.
  3. Check the requested permission against the role resolved in step 2.
  4. Execute the action against the workspace owner's real data — while still recording who actually acted (not just whose data was affected) on the resulting audit trail entry, so "the workspace's money moved" and "which team member moved it" are both always answerable.
  5. A denied attempt is itself logged to the audit trail as a permission_denied event, not silently dropped.

Inviting a team member

From /dashboard/enterprise/workspace, an Owner or Admin invites by email and assigns one of the four roles above. The invited member's own login is unaffected outside that workspace — they still have their own separate Valta account, just with delegated access to act on this workspace's resources at the role granted.

Next steps