mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
feat: add ai_gateway_keys table and related RBAC (#25563)
Adds table to store keys that AI Gateway standalone replicas will use to authenticate into Coderd. Also adds RBAC and audit boilerplate.
This commit is contained in:
committed by
GitHub
parent
49c2142d2d
commit
f22d4e2cbb
@@ -15,6 +15,15 @@ var (
|
||||
Type: "*",
|
||||
}
|
||||
|
||||
// ResourceAIGatewayKey
|
||||
// Valid Actions
|
||||
// - "ActionCreate" :: create an AI Gateway key
|
||||
// - "ActionDelete" :: delete an AI Gateway key
|
||||
// - "ActionRead" :: read AI Gateway keys
|
||||
ResourceAIGatewayKey = Object{
|
||||
Type: "ai_gateway_key",
|
||||
}
|
||||
|
||||
// ResourceAiModelPrice
|
||||
// Valid Actions
|
||||
// - "ActionRead" :: read AI model prices
|
||||
@@ -479,6 +488,7 @@ var (
|
||||
func AllResources() []Objecter {
|
||||
return []Objecter{
|
||||
ResourceWildcard,
|
||||
ResourceAIGatewayKey,
|
||||
ResourceAiModelPrice,
|
||||
ResourceAIProvider,
|
||||
ResourceAiSeat,
|
||||
|
||||
@@ -429,6 +429,14 @@ var RBACPermissions = map[string]PermissionDefinition{
|
||||
ActionDelete: "delete boundary logs",
|
||||
},
|
||||
},
|
||||
"ai_gateway_key": {
|
||||
Name: "AIGatewayKey",
|
||||
Actions: map[Action]ActionDefinition{
|
||||
ActionCreate: "create an AI Gateway key",
|
||||
ActionRead: "read AI Gateway keys",
|
||||
ActionDelete: "delete an AI Gateway key",
|
||||
},
|
||||
},
|
||||
"boundary_usage": {
|
||||
Actions: map[Action]ActionDefinition{
|
||||
ActionRead: "read boundary usage statistics",
|
||||
|
||||
@@ -1204,6 +1204,24 @@ func TestRolePermissions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
// Only owners can manage AI Gateway keys. They hold
|
||||
// a hashed bearer secret used to authenticate Gateway
|
||||
// replicas to coderd. Keys are deployment-wide.
|
||||
Name: "AIGatewayKey",
|
||||
Actions: []policy.Action{policy.ActionCreate, policy.ActionRead, policy.ActionDelete},
|
||||
Resource: rbac.ResourceAIGatewayKey,
|
||||
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},
|
||||
|
||||
@@ -7,6 +7,9 @@ package rbac
|
||||
// declared in code, not here, to avoid duplication.
|
||||
|
||||
const (
|
||||
ScopeAiGatewayKeyCreate ScopeName = "ai_gateway_key:create"
|
||||
ScopeAiGatewayKeyDelete ScopeName = "ai_gateway_key:delete"
|
||||
ScopeAiGatewayKeyRead ScopeName = "ai_gateway_key:read"
|
||||
ScopeAiModelPriceRead ScopeName = "ai_model_price:read"
|
||||
ScopeAiModelPriceUpdate ScopeName = "ai_model_price:update"
|
||||
ScopeAiProviderCreate ScopeName = "ai_provider:create"
|
||||
@@ -187,6 +190,9 @@ func (e ScopeName) Valid() bool {
|
||||
case ScopeName("coder:all"),
|
||||
ScopeName("coder:application_connect"),
|
||||
ScopeName("no_user_data"),
|
||||
ScopeAiGatewayKeyCreate,
|
||||
ScopeAiGatewayKeyDelete,
|
||||
ScopeAiGatewayKeyRead,
|
||||
ScopeAiModelPriceRead,
|
||||
ScopeAiModelPriceUpdate,
|
||||
ScopeAiProviderCreate,
|
||||
@@ -368,6 +374,9 @@ func AllScopeNameValues() []ScopeName {
|
||||
ScopeName("coder:all"),
|
||||
ScopeName("coder:application_connect"),
|
||||
ScopeName("no_user_data"),
|
||||
ScopeAiGatewayKeyCreate,
|
||||
ScopeAiGatewayKeyDelete,
|
||||
ScopeAiGatewayKeyRead,
|
||||
ScopeAiModelPriceRead,
|
||||
ScopeAiModelPriceUpdate,
|
||||
ScopeAiProviderCreate,
|
||||
|
||||
Reference in New Issue
Block a user