mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat(coderd/database): add AI Gateway key auth lookup and last-used queries (#26505)
Adds DB methods`GetAIGatewayKeyIDByHashedSecret` and `UpdateAIGatewayKeyLastUsedAt`. `GetAIGatewayKeyIDByHashedSecret` - returns AI Gateway key ID by hashed secret value. `UpdateAIGatewayKeyLastUsedAt` - updates last used timestamp for given AI Gateway key. Used by standalone AI Gateway for authentication and keeping track of currently used keys.
This commit is contained in:
@@ -20,6 +20,7 @@ var (
|
||||
// - "ActionCreate" :: create an AI Gateway key
|
||||
// - "ActionDelete" :: delete an AI Gateway key
|
||||
// - "ActionRead" :: read AI Gateway keys
|
||||
// - "ActionUpdate" :: update an AI Gateway key
|
||||
ResourceAIGatewayKey = Object{
|
||||
Type: "ai_gateway_key",
|
||||
}
|
||||
|
||||
@@ -434,6 +434,7 @@ var RBACPermissions = map[string]PermissionDefinition{
|
||||
Actions: map[Action]ActionDefinition{
|
||||
ActionCreate: "create an AI Gateway key",
|
||||
ActionRead: "read AI Gateway keys",
|
||||
ActionUpdate: "update an AI Gateway key",
|
||||
ActionDelete: "delete an AI Gateway key",
|
||||
},
|
||||
},
|
||||
|
||||
@@ -409,12 +409,16 @@ func ReloadBuiltinRoles(opts *RoleOptions) {
|
||||
// Workspace is specifically handled based on the opts.NoOwnerWorkspaceExec.
|
||||
// Owners can inspect and delete personal skills for operability and
|
||||
// abuse handling, but cannot create or edit user-authored instructions.
|
||||
allPermsExcept(ResourceWorkspaceDormant, ResourcePrebuiltWorkspace, ResourceWorkspace, ResourceUserSecret, ResourceUserSkill, ResourceUsageEvent, ResourceBoundaryUsage, ResourceBoundaryLog, ResourceAiSeat),
|
||||
allPermsExcept(ResourceWorkspaceDormant, ResourcePrebuiltWorkspace, ResourceWorkspace, ResourceUserSecret, ResourceUserSkill, ResourceUsageEvent, ResourceBoundaryUsage, ResourceBoundaryLog, ResourceAiSeat, ResourceAIGatewayKey),
|
||||
// This adds back in the Workspace permissions.
|
||||
Permissions(map[string][]policy.Action{
|
||||
ResourceWorkspace.Type: ownerWorkspaceActions,
|
||||
ResourceWorkspaceDormant.Type: {policy.ActionRead, policy.ActionDelete, policy.ActionCreate, policy.ActionUpdate, policy.ActionWorkspaceStop, policy.ActionCreateAgent, policy.ActionDeleteAgent, policy.ActionUpdateAgent},
|
||||
ResourceUserSkill.Type: {policy.ActionRead, policy.ActionDelete},
|
||||
// Owners manage AI Gateway keys but cannot update them. The
|
||||
// update action records last-used liveness and is reserved
|
||||
// for the system actor authenticating Gateway replicas.
|
||||
ResourceAIGatewayKey.Type: {policy.ActionCreate, policy.ActionRead, policy.ActionDelete},
|
||||
// PrebuiltWorkspaces are a subset of Workspaces.
|
||||
// Explicitly setting PrebuiltWorkspace permissions for clarity.
|
||||
// Note: even without PrebuiltWorkspace permissions, access is still granted via Workspace permissions.
|
||||
|
||||
@@ -1311,6 +1311,25 @@ func TestRolePermissions(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
// Updating an AI Gateway key records last-used liveness when a
|
||||
// Gateway replica authenticates. It is reserved for the system
|
||||
// actor, so no user-facing role, including owner, is authorized.
|
||||
Name: "AIGatewayKeyUpdate",
|
||||
Actions: []policy.Action{policy.ActionUpdate},
|
||||
Resource: rbac.ResourceAIGatewayKey,
|
||||
AuthorizeMap: map[bool][]hasAuthSubjects{
|
||||
true: {},
|
||||
false: {
|
||||
owner,
|
||||
orgWorkspaceAccessUser, memberMe, agentsAccessUser,
|
||||
orgAdmin, otherOrgAdmin,
|
||||
orgAuditor, otherOrgAuditor,
|
||||
templateAdmin, orgTemplateAdmin, otherOrgTemplateAdmin,
|
||||
userAdmin, orgUserAdmin, otherOrgUserAdmin,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "BoundaryUsage",
|
||||
Actions: []policy.Action{policy.ActionRead, policy.ActionUpdate, policy.ActionDelete},
|
||||
|
||||
@@ -10,6 +10,7 @@ const (
|
||||
ScopeAiGatewayKeyCreate ScopeName = "ai_gateway_key:create"
|
||||
ScopeAiGatewayKeyDelete ScopeName = "ai_gateway_key:delete"
|
||||
ScopeAiGatewayKeyRead ScopeName = "ai_gateway_key:read"
|
||||
ScopeAiGatewayKeyUpdate ScopeName = "ai_gateway_key:update"
|
||||
ScopeAiModelPriceRead ScopeName = "ai_model_price:read"
|
||||
ScopeAiModelPriceUpdate ScopeName = "ai_model_price:update"
|
||||
ScopeAiProviderCreate ScopeName = "ai_provider:create"
|
||||
@@ -193,6 +194,7 @@ func (e ScopeName) Valid() bool {
|
||||
ScopeAiGatewayKeyCreate,
|
||||
ScopeAiGatewayKeyDelete,
|
||||
ScopeAiGatewayKeyRead,
|
||||
ScopeAiGatewayKeyUpdate,
|
||||
ScopeAiModelPriceRead,
|
||||
ScopeAiModelPriceUpdate,
|
||||
ScopeAiProviderCreate,
|
||||
@@ -377,6 +379,7 @@ func AllScopeNameValues() []ScopeName {
|
||||
ScopeAiGatewayKeyCreate,
|
||||
ScopeAiGatewayKeyDelete,
|
||||
ScopeAiGatewayKeyRead,
|
||||
ScopeAiGatewayKeyUpdate,
|
||||
ScopeAiModelPriceRead,
|
||||
ScopeAiModelPriceUpdate,
|
||||
ScopeAiProviderCreate,
|
||||
|
||||
Reference in New Issue
Block a user