mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-03 20:19:07 +02:00
[management] Self-scope usage and log reads; give usage_viewer the filter resources
The usage overview and access-log listings no longer deny callers without the account-wide grant: the filter is pinned to the caller (their own user id, group filters dropped), so every authenticated user reads their own usage and requests through the same endpoints the admin dashboard uses. The dedicated /agent-network/me/usage/overview endpoint is removed in favor of that fallback. usage_viewer gains read-only access to the resources the usage view's filters and columns resolve against: users, groups, peers, and the provider list (provider and model filter options).
This commit is contained in:
@@ -63,9 +63,10 @@ func TestAgentNetworkAdminRole(t *testing.T) {
|
||||
}
|
||||
|
||||
// TestUsageViewerRole pins the least-privilege cost role: read on the
|
||||
// aggregated usage overview and nothing else — no providers, no policies,
|
||||
// no request-level logs (which can contain captured prompts), nothing in
|
||||
// the rest of the account.
|
||||
// aggregated usage overview plus read-only on the resources its filters
|
||||
// and display columns resolve against (users, groups, peers, the provider
|
||||
// list) — no policies, no request-level logs (which can contain captured
|
||||
// prompts), nothing else in the account.
|
||||
func TestUsageViewerRole(t *testing.T) {
|
||||
manager := NewManager(nil)
|
||||
ctx := context.Background()
|
||||
@@ -73,23 +74,30 @@ func TestUsageViewerRole(t *testing.T) {
|
||||
role, ok := roles.RolesMap[types.UserRoleUsageViewer]
|
||||
require.True(t, ok, "usage_viewer must exist in RolesMap")
|
||||
|
||||
assert.True(t, manager.ValidateRoleModuleAccess(ctx, "account", role, modules.AgentNetworkUsage, operations.Read),
|
||||
"usage_viewer must read the usage overview")
|
||||
for _, op := range []operations.Operation{operations.Create, operations.Update, operations.Delete} {
|
||||
assert.False(t, manager.ValidateRoleModuleAccess(ctx, "account", role, modules.AgentNetworkUsage, op),
|
||||
"usage_viewer must not have %s on usage", op)
|
||||
readOnly := []modules.Module{
|
||||
modules.AgentNetworkUsage,
|
||||
modules.AgentNetworkProviders,
|
||||
modules.Users,
|
||||
modules.Groups,
|
||||
modules.Peers,
|
||||
}
|
||||
for _, m := range readOnly {
|
||||
assert.True(t, manager.ValidateRoleModuleAccess(ctx, "account", role, m, operations.Read),
|
||||
"usage_viewer must read %s for the usage view and its filters", m)
|
||||
for _, op := range []operations.Operation{operations.Create, operations.Update, operations.Delete} {
|
||||
assert.False(t, manager.ValidateRoleModuleAccess(ctx, "account", role, m, op),
|
||||
"usage_viewer must not have %s on %s", op, m)
|
||||
}
|
||||
}
|
||||
|
||||
denied := []modules.Module{
|
||||
modules.AgentNetwork,
|
||||
modules.AgentNetworkProviders,
|
||||
modules.AgentNetworkPolicies,
|
||||
modules.AgentNetworkGuardrails,
|
||||
modules.AgentNetworkBudgets,
|
||||
modules.AgentNetworkLogs,
|
||||
modules.AgentNetworkSettings,
|
||||
modules.Networks,
|
||||
modules.Users,
|
||||
modules.SetupKeys,
|
||||
}
|
||||
for _, m := range denied {
|
||||
|
||||
@@ -7,10 +7,12 @@ import (
|
||||
)
|
||||
|
||||
// UsageViewer is the regular User baseline plus read access to the
|
||||
// aggregated Agent Network usage and cost overview. It sees no provider
|
||||
// configuration, no policies, and no request-level access logs (which can
|
||||
// contain captured prompts): usage rows carry user and group display names
|
||||
// in the response itself, so no team-wide read access is needed.
|
||||
// aggregated Agent Network usage and cost overview, and read-only access
|
||||
// to the resources the usage filters and display columns resolve against:
|
||||
// users and groups (identity filters and name resolution), peers (agent
|
||||
// principals in the caller column), and the provider list (provider and
|
||||
// model filter options). It sees no policies and no request-level access
|
||||
// logs (which can contain captured prompts).
|
||||
var UsageViewer = RolePermissions{
|
||||
Role: types.UserRoleUsageViewer,
|
||||
AutoAllowNew: map[operations.Operation]bool{
|
||||
@@ -26,5 +28,29 @@ var UsageViewer = RolePermissions{
|
||||
operations.Update: false,
|
||||
operations.Delete: false,
|
||||
},
|
||||
modules.AgentNetworkProviders: {
|
||||
operations.Read: true,
|
||||
operations.Create: false,
|
||||
operations.Update: false,
|
||||
operations.Delete: false,
|
||||
},
|
||||
modules.Users: {
|
||||
operations.Read: true,
|
||||
operations.Create: false,
|
||||
operations.Update: false,
|
||||
operations.Delete: false,
|
||||
},
|
||||
modules.Groups: {
|
||||
operations.Read: true,
|
||||
operations.Create: false,
|
||||
operations.Update: false,
|
||||
operations.Delete: false,
|
||||
},
|
||||
modules.Peers: {
|
||||
operations.Read: true,
|
||||
operations.Create: false,
|
||||
operations.Update: false,
|
||||
operations.Delete: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user