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:
| Role | Rank |
|---|---|
| Owner | 4 |
| Admin | 3 |
| Manager | 2 |
| Viewer | 1 |
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.
| Capability | Owner | Admin | Manager | Viewer |
|---|---|---|---|---|
| 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:
- Identify the calling user from their session.
- 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.
- Check the requested permission against the role resolved in step 2.
- 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.
- A denied attempt is itself logged to the audit trail as a
permission_deniedevent, 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.