Skip to content

Commit b4bfc29

Browse files
committed
Merge remote-tracking branch 'origin/main' into stevenmasley/merge_oidc_account
2 parents 3c8ee52 + bce8a98 commit b4bfc29

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+3158
-581
lines changed

.github/workflows/security.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,15 @@ jobs:
125125
pcc_pass: ${{ secrets.PRISMA_CLOUD_SECRET_KEY }}
126126
image_name: ${{ steps.build.outputs.image }}
127127

128+
- name: Scan image
129+
id: sysdig-scan
130+
uses: sysdiglabs/scan-action@v3
131+
with:
132+
image-tag: ${{ steps.build.outputs.image }}
133+
sysdig-secure-token: ${{ secrets.SYSDIG_API_TOKEN }}
134+
input-type: docker-daemon
135+
sysdig-secure-url: https://app.us4.sysdig.com
136+
128137
- name: Run Trivy vulnerability scanner
129138
uses: aquasecurity/trivy-action@41f05d9ecffa2ed3f1580af306000f734b733e54
130139
with:

agent/agent.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ func (a *agent) reportMetadataLoop(ctx context.Context) {
332332
lastCollectedAts[mr.key] = mr.result.CollectedAt
333333
err := a.client.PostMetadata(ctx, mr.key, *mr.result)
334334
if err != nil {
335-
a.logger.Error(ctx, "report metadata", slog.Error(err))
335+
a.logger.Error(ctx, "agent failed to report metadata", slog.Error(err))
336336
}
337337
case <-baseTicker.C:
338338
}
@@ -462,7 +462,7 @@ func (a *agent) reportLifecycleLoop(ctx context.Context) {
462462
return
463463
}
464464
// If we fail to report the state we probably shouldn't exit, log only.
465-
a.logger.Error(ctx, "post state", slog.Error(err))
465+
a.logger.Error(ctx, "agent failed to report the lifecycle state", slog.Error(err))
466466
}
467467
}
468468
}
@@ -1365,7 +1365,7 @@ func (a *agent) startReportingConnectionStats(ctx context.Context) {
13651365
)
13661366
})
13671367
if err != nil {
1368-
a.logger.Error(ctx, "report stats", slog.Error(err))
1368+
a.logger.Error(ctx, "agent failed to report stats", slog.Error(err))
13691369
} else {
13701370
if err = a.trackConnGoroutine(func() {
13711371
// This is OK because the agent never re-creates the tailnet

agent/agentssh/agentssh.go

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -180,21 +180,24 @@ func (s *Server) ConnStats() ConnStats {
180180
}
181181

182182
func (s *Server) sessionHandler(session ssh.Session) {
183+
logger := s.logger.With(slog.F("remote_addr", session.RemoteAddr()), slog.F("local_addr", session.LocalAddr()))
184+
logger.Info(session.Context(), "handling ssh session")
185+
ctx := session.Context()
183186
if !s.trackSession(session, true) {
184187
// See (*Server).Close() for why we call Close instead of Exit.
185188
_ = session.Close()
189+
logger.Info(ctx, "unable to accept new session, server is closing")
186190
return
187191
}
188192
defer s.trackSession(session, false)
189193

190-
ctx := session.Context()
191-
192194
extraEnv := make([]string, 0)
193195
x11, hasX11 := session.X11()
194196
if hasX11 {
195197
handled := s.x11Handler(session.Context(), x11)
196198
if !handled {
197199
_ = session.Exit(1)
200+
logger.Error(ctx, "x11 handler failed")
198201
return
199202
}
200203
extraEnv = append(extraEnv, fmt.Sprintf("DISPLAY=:%d.0", x11.ScreenNumber))
@@ -206,25 +209,26 @@ func (s *Server) sessionHandler(session ssh.Session) {
206209
s.sftpHandler(session)
207210
return
208211
default:
209-
s.logger.Debug(ctx, "unsupported subsystem", slog.F("subsystem", ss))
212+
logger.Warn(ctx, "unsupported subsystem", slog.F("subsystem", ss))
210213
_ = session.Exit(1)
211214
return
212215
}
213216

214217
err := s.sessionStart(session, extraEnv)
215218
var exitError *exec.ExitError
216219
if xerrors.As(err, &exitError) {
217-
s.logger.Warn(ctx, "ssh session returned", slog.Error(exitError))
220+
logger.Info(ctx, "ssh session returned", slog.Error(exitError))
218221
_ = session.Exit(exitError.ExitCode())
219222
return
220223
}
221224
if err != nil {
222-
s.logger.Warn(ctx, "ssh session failed", slog.Error(err))
225+
logger.Warn(ctx, "ssh session failed", slog.Error(err))
223226
// This exit code is designed to be unlikely to be confused for a legit exit code
224227
// from the process.
225228
_ = session.Exit(MagicSessionErrorCode)
226229
return
227230
}
231+
logger.Info(ctx, "normal ssh session exit")
228232
_ = session.Exit(0)
229233
}
230234

@@ -337,7 +341,7 @@ func (s *Server) startPTYSession(session ptySession, magicTypeLabel string, cmd
337341
if manifest != nil {
338342
err := showMOTD(session, manifest.MOTDFile)
339343
if err != nil {
340-
s.logger.Error(ctx, "show MOTD", slog.Error(err))
344+
s.logger.Error(ctx, "agent failed to show MOTD", slog.Error(err))
341345
s.metrics.sessionErrors.WithLabelValues(magicTypeLabel, "yes", "motd").Add(1)
342346
}
343347
} else {
@@ -406,7 +410,7 @@ func (s *Server) startPTYSession(session ptySession, magicTypeLabel string, cmd
406410
// ExitErrors just mean the command we run returned a non-zero exit code, which is normal
407411
// and not something to be concerned about. But, if it's something else, we should log it.
408412
if err != nil && !xerrors.As(err, &exitErr) {
409-
s.logger.Warn(ctx, "wait error", slog.Error(err))
413+
s.logger.Warn(ctx, "process wait exited with error", slog.Error(err))
410414
s.metrics.sessionErrors.WithLabelValues(magicTypeLabel, "yes", "wait").Add(1)
411415
}
412416
if err != nil {
@@ -565,7 +569,12 @@ func (s *Server) CreateCommand(ctx context.Context, script string, env []string)
565569
return cmd, nil
566570
}
567571

568-
func (s *Server) Serve(l net.Listener) error {
572+
func (s *Server) Serve(l net.Listener) (retErr error) {
573+
s.logger.Info(context.Background(), "started serving listener", slog.F("listen_addr", l.Addr()))
574+
defer func() {
575+
s.logger.Info(context.Background(), "stopped serving listener",
576+
slog.F("listen_addr", l.Addr()), slog.Error(retErr))
577+
}()
569578
defer l.Close()
570579

571580
s.trackListener(l, true)
@@ -580,15 +589,23 @@ func (s *Server) Serve(l net.Listener) error {
580589
}
581590

582591
func (s *Server) handleConn(l net.Listener, c net.Conn) {
592+
logger := s.logger.With(
593+
slog.F("remote_addr", c.RemoteAddr()),
594+
slog.F("local_addr", c.LocalAddr()),
595+
slog.F("listen_addr", l.Addr()))
583596
defer c.Close()
584597

585598
if !s.trackConn(l, c, true) {
586599
// Server is closed or we no longer want
587600
// connections from this listener.
588-
s.logger.Debug(context.Background(), "received connection after server closed")
601+
logger.Info(context.Background(), "received connection after server closed")
589602
return
590603
}
591604
defer s.trackConn(l, c, false)
605+
logger.Info(context.Background(), "started serving connection")
606+
defer func() {
607+
logger.Info(context.Background(), "stopped serving connection")
608+
}()
592609

593610
s.srv.HandleConn(c)
594611
}

coderd/apidoc/docs.go

Lines changed: 2 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

Lines changed: 2 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/audit.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ func (api *API) auditLogIsResourceDeleted(ctx context.Context, alog database.Get
288288
if xerrors.Is(err, sql.ErrNoRows) {
289289
return true
290290
}
291-
api.Logger.Error(ctx, "fetch template", slog.Error(err))
291+
api.Logger.Error(ctx, "unable to fetch template", slog.Error(err))
292292
}
293293
return template.Deleted
294294
case database.ResourceTypeUser:
@@ -297,7 +297,7 @@ func (api *API) auditLogIsResourceDeleted(ctx context.Context, alog database.Get
297297
if xerrors.Is(err, sql.ErrNoRows) {
298298
return true
299299
}
300-
api.Logger.Error(ctx, "fetch user", slog.Error(err))
300+
api.Logger.Error(ctx, "unable to fetch user", slog.Error(err))
301301
}
302302
return user.Deleted
303303
case database.ResourceTypeWorkspace:
@@ -306,7 +306,7 @@ func (api *API) auditLogIsResourceDeleted(ctx context.Context, alog database.Get
306306
if xerrors.Is(err, sql.ErrNoRows) {
307307
return true
308308
}
309-
api.Logger.Error(ctx, "fetch workspace", slog.Error(err))
309+
api.Logger.Error(ctx, "unable to fetch workspace", slog.Error(err))
310310
}
311311
return workspace.Deleted
312312
case database.ResourceTypeWorkspaceBuild:
@@ -315,15 +315,15 @@ func (api *API) auditLogIsResourceDeleted(ctx context.Context, alog database.Get
315315
if xerrors.Is(err, sql.ErrNoRows) {
316316
return true
317317
}
318-
api.Logger.Error(ctx, "fetch workspace build", slog.Error(err))
318+
api.Logger.Error(ctx, "unable to fetch workspace build", slog.Error(err))
319319
}
320320
// We use workspace as a proxy for workspace build here
321321
workspace, err := api.Database.GetWorkspaceByID(ctx, workspaceBuild.WorkspaceID)
322322
if err != nil {
323323
if xerrors.Is(err, sql.ErrNoRows) {
324324
return true
325325
}
326-
api.Logger.Error(ctx, "fetch workspace", slog.Error(err))
326+
api.Logger.Error(ctx, "unable to fetch workspace", slog.Error(err))
327327
}
328328
return workspace.Deleted
329329
default:

coderd/authorize.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func AuthorizeFilter[O rbac.Objecter](h *HTTPAuthorizer, r *http.Request, action
2222
objects, err := rbac.Filter(r.Context(), h.Authorizer, roles.Actor, action, objects)
2323
if err != nil {
2424
// Log the error as Filter should not be erroring.
25-
h.Logger.Error(r.Context(), "filter failed",
25+
h.Logger.Error(r.Context(), "authorization filter failed",
2626
slog.Error(err),
2727
slog.F("user_id", roles.Actor.ID),
2828
slog.F("username", roles.ActorName),

coderd/csp.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ func (api *API) logReportCSPViolations(rw http.ResponseWriter, r *http.Request)
3131
dec := json.NewDecoder(r.Body)
3232
err := dec.Decode(&v)
3333
if err != nil {
34-
api.Logger.Warn(ctx, "csp violation", slog.Error(err))
34+
api.Logger.Warn(ctx, "CSP violation reported", slog.Error(err))
3535
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
3636
Message: "Failed to read body, invalid json.",
3737
Detail: err.Error(),
@@ -43,7 +43,7 @@ func (api *API) logReportCSPViolations(rw http.ResponseWriter, r *http.Request)
4343
for k, v := range v.Report {
4444
fields = append(fields, slog.F(k, v))
4545
}
46-
api.Logger.Debug(ctx, "csp violation", fields...)
46+
api.Logger.Debug(ctx, "CSP violation reported", fields...)
4747

4848
httpapi.Write(ctx, rw, http.StatusOK, "ok")
4949
}

coderd/database/dbauthz/dbauthz.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,13 @@ func (q *querier) DeleteApplicationConnectAPIKeysByUserID(ctx context.Context, u
707707
return q.db.DeleteApplicationConnectAPIKeysByUserID(ctx, userID)
708708
}
709709

710+
func (q *querier) DeleteCoordinator(ctx context.Context, id uuid.UUID) error {
711+
if err := q.authorizeContext(ctx, rbac.ActionDelete, rbac.ResourceTailnetCoordinator); err != nil {
712+
return err
713+
}
714+
return q.db.DeleteCoordinator(ctx, id)
715+
}
716+
710717
func (q *querier) DeleteGitSSHKey(ctx context.Context, userID uuid.UUID) error {
711718
return deleteQ(q.log, q.auth, q.db.GetGitSSHKey, q.db.DeleteGitSSHKey)(ctx, userID)
712719
}
@@ -772,6 +779,21 @@ func (q *querier) DeleteUserOauthMergeStates(ctx context.Context, userID uuid.UU
772779
return q.db.DeleteUserOauthMergeStates(ctx, userID)
773780
}
774781

782+
783+
func (q *querier) DeleteTailnetAgent(ctx context.Context, arg database.DeleteTailnetAgentParams) (database.DeleteTailnetAgentRow, error) {
784+
if err := q.authorizeContext(ctx, rbac.ActionUpdate, rbac.ResourceTailnetCoordinator); err != nil {
785+
return database.DeleteTailnetAgentRow{}, err
786+
}
787+
return q.db.DeleteTailnetAgent(ctx, arg)
788+
}
789+
790+
func (q *querier) DeleteTailnetClient(ctx context.Context, arg database.DeleteTailnetClientParams) (database.DeleteTailnetClientRow, error) {
791+
if err := q.authorizeContext(ctx, rbac.ActionDelete, rbac.ResourceTailnetCoordinator); err != nil {
792+
return database.DeleteTailnetClientRow{}, err
793+
}
794+
return q.db.DeleteTailnetClient(ctx, arg)
795+
}
796+
775797
func (q *querier) GetAPIKeyByID(ctx context.Context, id string) (database.APIKey, error) {
776798
return fetch(q.log, q.auth, q.db.GetAPIKeyByID)(ctx, id)
777799
}
@@ -1144,6 +1166,20 @@ func (q *querier) GetServiceBanner(ctx context.Context) (string, error) {
11441166
return q.db.GetServiceBanner(ctx)
11451167
}
11461168

1169+
func (q *querier) GetTailnetAgents(ctx context.Context, id uuid.UUID) ([]database.TailnetAgent, error) {
1170+
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceTailnetCoordinator); err != nil {
1171+
return nil, err
1172+
}
1173+
return q.db.GetTailnetAgents(ctx, id)
1174+
}
1175+
1176+
func (q *querier) GetTailnetClientsForAgent(ctx context.Context, agentID uuid.UUID) ([]database.TailnetClient, error) {
1177+
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceTailnetCoordinator); err != nil {
1178+
return nil, err
1179+
}
1180+
return q.db.GetTailnetClientsForAgent(ctx, agentID)
1181+
}
1182+
11471183
// Only used by metrics cache.
11481184
func (q *querier) GetTemplateAverageBuildTime(ctx context.Context, arg database.GetTemplateAverageBuildTimeParams) (database.GetTemplateAverageBuildTimeRow, error) {
11491185
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
@@ -2545,3 +2581,24 @@ func (q *querier) UpsertServiceBanner(ctx context.Context, value string) error {
25452581
}
25462582
return q.db.UpsertServiceBanner(ctx, value)
25472583
}
2584+
2585+
func (q *querier) UpsertTailnetAgent(ctx context.Context, arg database.UpsertTailnetAgentParams) (database.TailnetAgent, error) {
2586+
if err := q.authorizeContext(ctx, rbac.ActionUpdate, rbac.ResourceTailnetCoordinator); err != nil {
2587+
return database.TailnetAgent{}, err
2588+
}
2589+
return q.db.UpsertTailnetAgent(ctx, arg)
2590+
}
2591+
2592+
func (q *querier) UpsertTailnetClient(ctx context.Context, arg database.UpsertTailnetClientParams) (database.TailnetClient, error) {
2593+
if err := q.authorizeContext(ctx, rbac.ActionUpdate, rbac.ResourceTailnetCoordinator); err != nil {
2594+
return database.TailnetClient{}, err
2595+
}
2596+
return q.db.UpsertTailnetClient(ctx, arg)
2597+
}
2598+
2599+
func (q *querier) UpsertTailnetCoordinator(ctx context.Context, id uuid.UUID) (database.TailnetCoordinator, error) {
2600+
if err := q.authorizeContext(ctx, rbac.ActionUpdate, rbac.ResourceTailnetCoordinator); err != nil {
2601+
return database.TailnetCoordinator{}, err
2602+
}
2603+
return q.db.UpsertTailnetCoordinator(ctx, id)
2604+
}

0 commit comments

Comments
 (0)