diff --git a/coderd/audit/diff.go b/coderd/audit/diff.go
index 56ac9f88ccaae..b8139bb63b290 100644
--- a/coderd/audit/diff.go
+++ b/coderd/audit/diff.go
@@ -31,9 +31,7 @@ type Auditable interface {
database.NotificationTemplate |
idpsync.OrganizationSyncSettings |
idpsync.GroupSyncSettings |
- idpsync.RoleSyncSettings |
- database.WorkspaceAgent |
- database.WorkspaceApp
+ idpsync.RoleSyncSettings
}
// Map is a map of changed fields in an audited resource. It maps field names to
diff --git a/coderd/audit/request.go b/coderd/audit/request.go
index ae6a57e6c2775..a973bdb915e3c 100644
--- a/coderd/audit/request.go
+++ b/coderd/audit/request.go
@@ -131,10 +131,6 @@ func ResourceTarget[T Auditable](tgt T) string {
return "Organization Group Sync"
case idpsync.RoleSyncSettings:
return "Organization Role Sync"
- case database.WorkspaceAgent:
- return typed.Name
- case database.WorkspaceApp:
- return typed.Slug
default:
panic(fmt.Sprintf("unknown resource %T for ResourceTarget", tgt))
}
@@ -197,10 +193,6 @@ func ResourceID[T Auditable](tgt T) uuid.UUID {
return noID // Org field on audit log has org id
case idpsync.RoleSyncSettings:
return noID // Org field on audit log has org id
- case database.WorkspaceAgent:
- return typed.ID
- case database.WorkspaceApp:
- return typed.ID
default:
panic(fmt.Sprintf("unknown resource %T for ResourceID", tgt))
}
@@ -254,10 +246,6 @@ func ResourceType[T Auditable](tgt T) database.ResourceType {
return database.ResourceTypeIdpSyncSettingsRole
case idpsync.GroupSyncSettings:
return database.ResourceTypeIdpSyncSettingsGroup
- case database.WorkspaceAgent:
- return database.ResourceTypeWorkspaceAgent
- case database.WorkspaceApp:
- return database.ResourceTypeWorkspaceApp
default:
panic(fmt.Sprintf("unknown resource %T for ResourceType", typed))
}
@@ -314,10 +302,6 @@ func ResourceRequiresOrgID[T Auditable]() bool {
return true
case idpsync.RoleSyncSettings:
return true
- case database.WorkspaceAgent:
- return true
- case database.WorkspaceApp:
- return true
default:
panic(fmt.Sprintf("unknown resource %T for ResourceRequiresOrgID", tgt))
}
diff --git a/coderd/audit_test.go b/coderd/audit_test.go
index e6fa985038155..13dbc9ccd8406 100644
--- a/coderd/audit_test.go
+++ b/coderd/audit_test.go
@@ -15,6 +15,7 @@ import (
"github.com/coder/coder/v2/coderd/audit"
"github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/coderd/database"
+ "github.com/coder/coder/v2/coderd/database/dbgen"
"github.com/coder/coder/v2/coderd/rbac"
"github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/provisioner/echo"
@@ -531,3 +532,112 @@ func completeWithAgentAndApp() *echo.Responses {
},
}
}
+
+// TestDeprecatedConnEvents tests the deprecated connection and disconnection
+// events in the audit logs. These events are no longer created, but need to be
+// returned by the API.
+func TestDeprecatedConnEvents(t *testing.T) {
+ t.Parallel()
+ var (
+ ctx = context.Background()
+ client, _, api = coderdtest.NewWithAPI(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
+ user = coderdtest.CreateFirstUser(t, client)
+ version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, completeWithAgentAndApp())
+ template = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
+ )
+
+ coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
+ workspace := coderdtest.CreateWorkspace(t, client, template.ID)
+ workspace.LatestBuild = coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID)
+
+ type additionalFields struct {
+ audit.AdditionalFields
+ ConnectionType string `json:"connection_type"`
+ }
+
+ sshFields := additionalFields{
+ AdditionalFields: audit.AdditionalFields{
+ WorkspaceName: workspace.Name,
+ BuildNumber: "999",
+ BuildReason: "initiator",
+ WorkspaceOwner: workspace.OwnerName,
+ WorkspaceID: workspace.ID,
+ },
+ ConnectionType: "SSH",
+ }
+
+ sshFieldsBytes, err := json.Marshal(sshFields)
+ require.NoError(t, err)
+
+ appFields := audit.AdditionalFields{
+ WorkspaceName: workspace.Name,
+ // Deliberately empty
+ BuildNumber: "",
+ BuildReason: "",
+ WorkspaceOwner: workspace.OwnerName,
+ WorkspaceID: workspace.ID,
+ }
+
+ appFieldsBytes, err := json.Marshal(appFields)
+ require.NoError(t, err)
+
+ dbgen.AuditLog(t, api.Database, database.AuditLog{
+ OrganizationID: user.OrganizationID,
+ Action: database.AuditActionConnect,
+ ResourceType: database.ResourceTypeWorkspaceAgent,
+ ResourceID: workspace.LatestBuild.Resources[0].Agents[0].ID,
+ ResourceTarget: workspace.LatestBuild.Resources[0].Agents[0].Name,
+ Time: time.Date(2022, 8, 15, 14, 30, 45, 100, time.UTC), // 2022-8-15 14:30:45
+ AdditionalFields: sshFieldsBytes,
+ })
+
+ dbgen.AuditLog(t, api.Database, database.AuditLog{
+ OrganizationID: user.OrganizationID,
+ Action: database.AuditActionDisconnect,
+ ResourceType: database.ResourceTypeWorkspaceAgent,
+ ResourceID: workspace.LatestBuild.Resources[0].Agents[0].ID,
+ ResourceTarget: workspace.LatestBuild.Resources[0].Agents[0].Name,
+ Time: time.Date(2022, 8, 15, 14, 35, 0o0, 100, time.UTC), // 2022-8-15 14:35:00
+ AdditionalFields: sshFieldsBytes,
+ })
+
+ dbgen.AuditLog(t, api.Database, database.AuditLog{
+ OrganizationID: user.OrganizationID,
+ UserID: user.UserID,
+ Action: database.AuditActionOpen,
+ ResourceType: database.ResourceTypeWorkspaceApp,
+ ResourceID: workspace.LatestBuild.Resources[0].Agents[0].Apps[0].ID,
+ ResourceTarget: workspace.LatestBuild.Resources[0].Agents[0].Apps[0].Slug,
+ Time: time.Date(2022, 8, 15, 14, 30, 45, 100, time.UTC), // 2022-8-15 14:30:45
+ AdditionalFields: appFieldsBytes,
+ })
+
+ connLog, err := client.AuditLogs(ctx, codersdk.AuditLogsRequest{
+ SearchQuery: "action:connect",
+ })
+ require.NoError(t, err)
+ require.Len(t, connLog.AuditLogs, 1)
+ var sshOutFields additionalFields
+ err = json.Unmarshal(connLog.AuditLogs[0].AdditionalFields, &sshOutFields)
+ require.NoError(t, err)
+ require.Equal(t, sshFields, sshOutFields)
+
+ dcLog, err := client.AuditLogs(ctx, codersdk.AuditLogsRequest{
+ SearchQuery: "action:disconnect",
+ })
+ require.NoError(t, err)
+ require.Len(t, dcLog.AuditLogs, 1)
+ err = json.Unmarshal(dcLog.AuditLogs[0].AdditionalFields, &sshOutFields)
+ require.NoError(t, err)
+ require.Equal(t, sshFields, sshOutFields)
+
+ openLog, err := client.AuditLogs(ctx, codersdk.AuditLogsRequest{
+ SearchQuery: "action:open",
+ })
+ require.NoError(t, err)
+ require.Len(t, openLog.AuditLogs, 1)
+ var appOutFields audit.AdditionalFields
+ err = json.Unmarshal(openLog.AuditLogs[0].AdditionalFields, &appOutFields)
+ require.NoError(t, err)
+ require.Equal(t, appFields, appOutFields)
+}
diff --git a/coderd/database/dbgen/dbgen.go b/coderd/database/dbgen/dbgen.go
index 9720050a43cb1..d5693afe98826 100644
--- a/coderd/database/dbgen/dbgen.go
+++ b/coderd/database/dbgen/dbgen.go
@@ -65,7 +65,7 @@ func AuditLog(t testing.TB, db database.Store, seed database.AuditLog) database.
Action: takeFirst(seed.Action, database.AuditActionCreate),
Diff: takeFirstSlice(seed.Diff, []byte("{}")),
StatusCode: takeFirst(seed.StatusCode, 200),
- AdditionalFields: takeFirstSlice(seed.Diff, []byte("{}")),
+ AdditionalFields: takeFirstSlice(seed.AdditionalFields, []byte("{}")),
RequestID: takeFirst(seed.RequestID, uuid.New()),
ResourceIcon: takeFirst(seed.ResourceIcon, ""),
})
diff --git a/docs/admin/security/audit-logs.md b/docs/admin/security/audit-logs.md
index af033d02df2d5..4d66260fb2f7c 100644
--- a/docs/admin/security/audit-logs.md
+++ b/docs/admin/security/audit-logs.md
@@ -30,8 +30,6 @@ We track the following resources:
| Template
write, delete |
Field | Tracked |
| active_version_id | true |
activity_bump | true |
allow_user_autostart | true |
allow_user_autostop | true |
allow_user_cancel_workspace_jobs | true |
autostart_block_days_of_week | true |
autostop_requirement_days_of_week | true |
autostop_requirement_weeks | true |
created_at | false |
created_by | true |
created_by_avatar_url | false |
created_by_name | false |
created_by_username | false |
default_ttl | true |
deleted | false |
deprecated | true |
description | true |
display_name | true |
failure_ttl | true |
group_acl | true |
icon | true |
id | true |
max_port_sharing_level | true |
name | true |
organization_display_name | false |
organization_icon | false |
organization_id | false |
organization_name | false |
provisioner | true |
require_active_version | true |
time_til_dormant | true |
time_til_dormant_autodelete | true |
updated_at | false |
use_classic_parameter_flow | true |
user_acl | true |
|
| TemplateVersion
create, write | Field | Tracked |
| archived | true |
created_at | false |
created_by | true |
created_by_avatar_url | false |
created_by_name | false |
created_by_username | false |
external_auth_providers | false |
has_ai_task | false |
id | true |
job_id | false |
message | false |
name | true |
organization_id | false |
readme | true |
source_example_id | false |
template_id | true |
updated_at | false |
|
| User
create, write, delete | Field | Tracked |
| avatar_url | false |
created_at | false |
deleted | true |
email | true |
github_com_user_id | false |
hashed_one_time_passcode | false |
hashed_password | true |
id | true |
is_system | true |
last_seen_at | false |
login_type | true |
name | true |
one_time_passcode_expires_at | true |
quiet_hours_schedule | true |
rbac_roles | true |
status | true |
updated_at | false |
username | true |
|
-| WorkspaceAgent
connect, disconnect | Field | Tracked |
| api_key_scope | false |
api_version | false |
architecture | false |
auth_instance_id | false |
auth_token | false |
connection_timeout_seconds | false |
created_at | false |
deleted | false |
directory | false |
disconnected_at | false |
display_apps | false |
display_order | false |
environment_variables | false |
expanded_directory | false |
first_connected_at | false |
id | false |
instance_metadata | false |
last_connected_at | false |
last_connected_replica_id | false |
lifecycle_state | false |
logs_length | false |
logs_overflowed | false |
motd_file | false |
name | false |
operating_system | false |
parent_id | false |
ready_at | false |
resource_id | false |
resource_metadata | false |
started_at | false |
subsystems | false |
troubleshooting_url | false |
updated_at | false |
version | false |
|
-| WorkspaceApp
open, close | Field | Tracked |
| agent_id | false |
command | false |
created_at | false |
display_group | false |
display_name | false |
display_order | false |
external | false |
health | false |
healthcheck_interval | false |
healthcheck_threshold | false |
healthcheck_url | false |
hidden | false |
icon | false |
id | false |
open_in | false |
sharing_level | false |
slug | false |
subdomain | false |
url | false |
|
| WorkspaceBuild
start, stop | Field | Tracked |
| ai_task_sidebar_app_id | false |
build_number | false |
created_at | false |
daily_cost | false |
deadline | false |
has_ai_task | false |
id | false |
initiator_by_avatar_url | false |
initiator_by_name | false |
initiator_by_username | false |
initiator_id | false |
job_id | false |
max_deadline | false |
provisioner_state | false |
reason | false |
template_version_id | true |
template_version_preset_id | false |
transition | false |
updated_at | false |
workspace_id | false |
|
| WorkspaceProxy
| Field | Tracked |
| created_at | true |
deleted | false |
derp_enabled | true |
derp_only | true |
display_name | true |
icon | true |
id | true |
name | true |
region_id | true |
token_hashed_secret | true |
updated_at | false |
url | true |
version | true |
wildcard_hostname | true |
|
| WorkspaceTable
| Field | Tracked |
| automatic_updates | true |
autostart_schedule | true |
created_at | false |
deleted | false |
deleting_at | true |
dormant_at | true |
favorite | true |
id | true |
last_used_at | false |
name | true |
next_start_at | true |
organization_id | false |
owner_id | true |
template_id | true |
ttl | true |
updated_at | false |
|
@@ -91,16 +89,16 @@ log entry:
"ts": "2023-06-13T03:45:37.294730279Z",
"level": "INFO",
"msg": "audit_log",
- "caller": "/home/runner/work/coder/coder/enterprise/audit/backends/slog.go:36",
- "func": "github.com/coder/coder/enterprise/audit/backends.slogBackend.Export",
+ "caller": "/home/coder/coder/enterprise/audit/backends/slog.go:38",
+ "func": "github.com/coder/coder/v2/enterprise/audit/backends.(*SlogExporter).ExportStruct",
"logger_names": ["coderd"],
"fields": {
"ID": "033a9ffa-b54d-4c10-8ec3-2aaf9e6d741a",
"Time": "2023-06-13T03:45:37.288506Z",
"UserID": "6c405053-27e3-484a-9ad7-bcb64e7bfde6",
"OrganizationID": "00000000-0000-0000-0000-000000000000",
- "Ip": "{IPNet:{IP:\u003cnil\u003e Mask:\u003cnil\u003e} Valid:false}",
- "UserAgent": "{String: Valid:false}",
+ "Ip": null,
+ "UserAgent": null,
"ResourceType": "workspace_build",
"ResourceID": "ca5647e0-ef50-4202-a246-717e04447380",
"ResourceTarget": "",
diff --git a/enterprise/audit/table.go b/enterprise/audit/table.go
index 2a563946dc347..6c1f907abfa00 100644
--- a/enterprise/audit/table.go
+++ b/enterprise/audit/table.go
@@ -27,8 +27,6 @@ var AuditActionMap = map[string][]codersdk.AuditAction{
"Group": {codersdk.AuditActionCreate, codersdk.AuditActionWrite, codersdk.AuditActionDelete},
"APIKey": {codersdk.AuditActionLogin, codersdk.AuditActionLogout, codersdk.AuditActionRegister, codersdk.AuditActionCreate, codersdk.AuditActionDelete},
"License": {codersdk.AuditActionCreate, codersdk.AuditActionDelete},
- "WorkspaceAgent": {codersdk.AuditActionConnect, codersdk.AuditActionDisconnect},
- "WorkspaceApp": {codersdk.AuditActionOpen, codersdk.AuditActionClose},
}
type Action string
@@ -343,63 +341,6 @@ var auditableResourcesTypes = map[any]map[string]Action{
"field": ActionTrack,
"mapping": ActionTrack,
},
- &database.WorkspaceAgent{}: {
- "id": ActionIgnore,
- "created_at": ActionIgnore,
- "updated_at": ActionIgnore,
- "name": ActionIgnore,
- "first_connected_at": ActionIgnore,
- "last_connected_at": ActionIgnore,
- "disconnected_at": ActionIgnore,
- "resource_id": ActionIgnore,
- "auth_token": ActionIgnore,
- "auth_instance_id": ActionIgnore,
- "architecture": ActionIgnore,
- "environment_variables": ActionIgnore,
- "operating_system": ActionIgnore,
- "instance_metadata": ActionIgnore,
- "resource_metadata": ActionIgnore,
- "directory": ActionIgnore,
- "version": ActionIgnore,
- "last_connected_replica_id": ActionIgnore,
- "connection_timeout_seconds": ActionIgnore,
- "troubleshooting_url": ActionIgnore,
- "motd_file": ActionIgnore,
- "lifecycle_state": ActionIgnore,
- "expanded_directory": ActionIgnore,
- "logs_length": ActionIgnore,
- "logs_overflowed": ActionIgnore,
- "started_at": ActionIgnore,
- "ready_at": ActionIgnore,
- "subsystems": ActionIgnore,
- "display_apps": ActionIgnore,
- "api_version": ActionIgnore,
- "display_order": ActionIgnore,
- "parent_id": ActionIgnore,
- "api_key_scope": ActionIgnore,
- "deleted": ActionIgnore,
- },
- &database.WorkspaceApp{}: {
- "id": ActionIgnore,
- "created_at": ActionIgnore,
- "agent_id": ActionIgnore,
- "display_name": ActionIgnore,
- "icon": ActionIgnore,
- "command": ActionIgnore,
- "url": ActionIgnore,
- "healthcheck_url": ActionIgnore,
- "healthcheck_interval": ActionIgnore,
- "healthcheck_threshold": ActionIgnore,
- "health": ActionIgnore,
- "subdomain": ActionIgnore,
- "sharing_level": ActionIgnore,
- "slug": ActionIgnore,
- "external": ActionIgnore,
- "display_group": ActionIgnore,
- "display_order": ActionIgnore,
- "hidden": ActionIgnore,
- "open_in": ActionIgnore,
- },
}
// auditMap converts a map of struct pointers to a map of struct names as
pFad - Phonifier reborn
Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy