-
Notifications
You must be signed in to change notification settings - Fork 888
feat: add workspace build start/stop to audit log #4744
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
cfe5dd0
5d094a2
c11befc
ac6e405
ec3e6bf
c0ffe78
7e09219
9cd9ea9
76438e1
eba75cf
97233a0
5946e8b
3200a10
1112a66
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
-- It's not possible to drop enum values from enum types, so the UP has "IF NOT | ||
-- EXISTS". |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
ALTER TYPE audit_action ADD VALUE IF NOT EXISTS 'start'; | ||
ALTER TYPE audit_action ADD VALUE IF NOT EXISTS 'stop'; | ||
|
||
ALTER TYPE resource_type ADD VALUE IF NOT EXISTS 'workspace_build'; |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ import ( | |
"golang.org/x/exp/slices" | ||
"golang.org/x/xerrors" | ||
|
||
"cdr.dev/slog" | ||
"github.com/coder/coder/coderd/audit" | ||
"github.com/coder/coder/coderd/database" | ||
"github.com/coder/coder/coderd/httpapi" | ||
|
@@ -278,28 +279,62 @@ func (api *API) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) { | |
return | ||
} | ||
|
||
// we only want to create audit logs for delete builds right now | ||
auditor := api.Auditor.Load() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not really related to your PR since this was already here so feel free to ignore but I wonder if the auditor should be set up before the authorization check so we can log unauthorized request attempts. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good eye! We have a separate ticket for this! |
||
|
||
// if user deletes a workspace, audit the workspace | ||
if action == rbac.ActionDelete { | ||
var ( | ||
auditor = api.Auditor.Load() | ||
aReq, commitAudit = audit.InitRequest[database.Workspace](rw, &audit.RequestParams{ | ||
Audit: *auditor, | ||
Log: api.Logger, | ||
Request: r, | ||
Action: database.AuditActionDelete, | ||
}) | ||
) | ||
aReq, commitAudit := audit.InitRequest[database.Workspace](rw, &audit.RequestParams{ | ||
Audit: *auditor, | ||
Log: api.Logger, | ||
Request: r, | ||
Action: database.AuditActionDelete, | ||
}) | ||
|
||
defer commitAudit() | ||
aReq.Old = workspace | ||
} | ||
|
||
if createBuild.TemplateVersionID == uuid.Nil { | ||
latestBuild, err := api.Database.GetLatestWorkspaceBuildByWorkspaceID(ctx, workspace.ID) | ||
latestBuild, latestBuildErr := api.Database.GetLatestWorkspaceBuildByWorkspaceID(ctx, workspace.ID) | ||
|
||
// if a user starts/stops a workspace, audit the workspace build | ||
if action == rbac.ActionUpdate { | ||
var auditAction database.AuditAction | ||
if createBuild.Transition == codersdk.WorkspaceTransitionStart { | ||
auditAction = database.AuditActionStart | ||
} else if createBuild.Transition == codersdk.WorkspaceTransitionStop { | ||
auditAction = database.AuditActionStop | ||
} else { | ||
auditAction = database.AuditActionWrite | ||
} | ||
|
||
// We pass the workspace name to the Auditor so that it | ||
// can form a friendly string for the user. | ||
workspaceResourceInfo := map[string]string{ | ||
"workspaceName": workspace.Name, | ||
} | ||
|
||
wriBytes, err := json.Marshal(workspaceResourceInfo) | ||
if err != nil { | ||
api.Logger.Error(ctx, "could not marshal workspace name", slog.Error(err)) | ||
} | ||
|
||
aReq, commitAudit := audit.InitRequest[database.WorkspaceBuild](rw, &audit.RequestParams{ | ||
Audit: *auditor, | ||
Log: api.Logger, | ||
Request: r, | ||
Action: auditAction, | ||
AdditionalFields: wriBytes, | ||
}) | ||
|
||
defer commitAudit() | ||
aReq.Old = latestBuild | ||
} | ||
|
||
if createBuild.TemplateVersionID == uuid.Nil { | ||
if latestBuildErr != nil { | ||
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ | ||
Message: "Internal error fetching the latest workspace build.", | ||
Detail: err.Error(), | ||
Detail: latestBuildErr.Error(), | ||
}) | ||
return | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would this error be worth surfacing (even just through the logger) or is it expected that this might sometimes not contain workspace info?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure!