mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: add ai_providers table, queries, dbauthz, audit, RBAC (#24892)
This commit is contained in:
@@ -23,6 +23,16 @@ var (
|
||||
Type: "ai_model_price",
|
||||
}
|
||||
|
||||
// ResourceAIProvider
|
||||
// Valid Actions
|
||||
// - "ActionCreate" :: create an AI provider
|
||||
// - "ActionDelete" :: delete an AI provider
|
||||
// - "ActionRead" :: read AI provider configuration
|
||||
// - "ActionUpdate" :: update an AI provider
|
||||
ResourceAIProvider = Object{
|
||||
Type: "ai_provider",
|
||||
}
|
||||
|
||||
// ResourceAiSeat
|
||||
// Valid Actions
|
||||
// - "ActionCreate" :: record AI seat usage
|
||||
@@ -450,6 +460,7 @@ func AllResources() []Objecter {
|
||||
return []Objecter{
|
||||
ResourceWildcard,
|
||||
ResourceAiModelPrice,
|
||||
ResourceAIProvider,
|
||||
ResourceAiSeat,
|
||||
ResourceAibridgeInterception,
|
||||
ResourceApiKey,
|
||||
|
||||
@@ -398,6 +398,15 @@ var RBACPermissions = map[string]PermissionDefinition{
|
||||
ActionUpdate: "update AI model prices",
|
||||
},
|
||||
},
|
||||
"ai_provider": {
|
||||
Name: "AIProvider",
|
||||
Actions: map[Action]ActionDefinition{
|
||||
ActionRead: "read AI provider configuration",
|
||||
ActionCreate: "create an AI provider",
|
||||
ActionUpdate: "update an AI provider",
|
||||
ActionDelete: "delete an AI provider",
|
||||
},
|
||||
},
|
||||
"ai_seat": {
|
||||
Actions: map[Action]ActionDefinition{
|
||||
ActionCreate: "record AI seat usage",
|
||||
|
||||
@@ -1105,6 +1105,25 @@ func TestRolePermissions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
// Only owners can manage AI providers. Provider
|
||||
// configuration is deployment-wide and includes secret
|
||||
// material (api_key, settings) so it is not exposed to
|
||||
// org admins or auditors.
|
||||
Name: "AIProviders",
|
||||
Actions: crud,
|
||||
Resource: rbac.ResourceAIProvider,
|
||||
AuthorizeMap: map[bool][]hasAuthSubjects{
|
||||
true: {owner},
|
||||
false: {
|
||||
memberMe, agentsAccessUser,
|
||||
orgAdmin, otherOrgAdmin,
|
||||
orgAuditor, otherOrgAuditor,
|
||||
templateAdmin, orgTemplateAdmin, otherOrgTemplateAdmin,
|
||||
userAdmin, orgUserAdmin, otherOrgUserAdmin,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "BoundaryUsage",
|
||||
Actions: []policy.Action{policy.ActionRead, policy.ActionUpdate, policy.ActionDelete},
|
||||
|
||||
@@ -9,6 +9,10 @@ package rbac
|
||||
const (
|
||||
ScopeAiModelPriceRead ScopeName = "ai_model_price:read"
|
||||
ScopeAiModelPriceUpdate ScopeName = "ai_model_price:update"
|
||||
ScopeAiProviderCreate ScopeName = "ai_provider:create"
|
||||
ScopeAiProviderDelete ScopeName = "ai_provider:delete"
|
||||
ScopeAiProviderRead ScopeName = "ai_provider:read"
|
||||
ScopeAiProviderUpdate ScopeName = "ai_provider:update"
|
||||
ScopeAiSeatCreate ScopeName = "ai_seat:create"
|
||||
ScopeAiSeatRead ScopeName = "ai_seat:read"
|
||||
ScopeAibridgeInterceptionCreate ScopeName = "aibridge_interception:create"
|
||||
@@ -177,6 +181,10 @@ func (e ScopeName) Valid() bool {
|
||||
ScopeName("no_user_data"),
|
||||
ScopeAiModelPriceRead,
|
||||
ScopeAiModelPriceUpdate,
|
||||
ScopeAiProviderCreate,
|
||||
ScopeAiProviderDelete,
|
||||
ScopeAiProviderRead,
|
||||
ScopeAiProviderUpdate,
|
||||
ScopeAiSeatCreate,
|
||||
ScopeAiSeatRead,
|
||||
ScopeAibridgeInterceptionCreate,
|
||||
@@ -346,6 +354,10 @@ func AllScopeNameValues() []ScopeName {
|
||||
ScopeName("no_user_data"),
|
||||
ScopeAiModelPriceRead,
|
||||
ScopeAiModelPriceUpdate,
|
||||
ScopeAiProviderCreate,
|
||||
ScopeAiProviderDelete,
|
||||
ScopeAiProviderRead,
|
||||
ScopeAiProviderUpdate,
|
||||
ScopeAiSeatCreate,
|
||||
ScopeAiSeatRead,
|
||||
ScopeAibridgeInterceptionCreate,
|
||||
|
||||
Reference in New Issue
Block a user