feat: add support for workspace app audit (#16801)

This change adds support for workspace app auditing.

To avoid audit log spam, we introduce the concept of app audit sessions.
An audit session is unique per workspace app, user, ip, user agent and
http status code. The sessions are stored in a separate table from audit
logs to allow use-case specific optimizations. Sessions are ephemeral
and the table does not function as a log.

The logic for auditing is placed in the DBTokenProvider for workspace
apps so that wsproxies are included.

This is the final change affecting the API fo #15139.

Updates #15139
This commit is contained in:
Mathias Fredriksson
2025-03-18 13:50:52 +02:00
committed by GitHub
parent 3ae55bbbf4
commit de41bd6b95
25 changed files with 1042 additions and 159 deletions

View File

@ -226,6 +226,10 @@ type Options struct {
UpdateAgentMetrics func(ctx context.Context, labels prometheusmetrics.AgentMetricLabels, metrics []*agentproto.Stats_Metric)
StatsBatcher workspacestats.Batcher
// WorkspaceAppAuditSessionTimeout allows changing the timeout for audit
// sessions. Raising or lowering this value will directly affect the write
// load of the audit log table. This is used for testing. Default 1 hour.
WorkspaceAppAuditSessionTimeout time.Duration
WorkspaceAppsStatsCollectorOptions workspaceapps.StatsCollectorOptions
// This janky function is used in telemetry to parse fields out of the raw
@ -534,16 +538,6 @@ func New(options *Options) *API {
Authorizer: options.Authorizer,
Logger: options.Logger,
},
WorkspaceAppsProvider: workspaceapps.NewDBTokenProvider(
options.Logger.Named("workspaceapps"),
options.AccessURL,
options.Authorizer,
options.Database,
options.DeploymentValues,
oauthConfigs,
options.AgentInactiveDisconnectTimeout,
options.AppSigningKeyCache,
),
metricsCache: metricsCache,
Auditor: atomic.Pointer[audit.Auditor]{},
TailnetCoordinator: atomic.Pointer[tailnet.Coordinator]{},
@ -561,6 +555,18 @@ func New(options *Options) *API {
),
dbRolluper: options.DatabaseRolluper,
}
api.WorkspaceAppsProvider = workspaceapps.NewDBTokenProvider(
options.Logger.Named("workspaceapps"),
options.AccessURL,
options.Authorizer,
&api.Auditor,
options.Database,
options.DeploymentValues,
oauthConfigs,
options.AgentInactiveDisconnectTimeout,
options.WorkspaceAppAuditSessionTimeout,
options.AppSigningKeyCache,
)
f := appearance.NewDefaultFetcher(api.DeploymentValues.DocsURL.String())
api.AppearanceFetcher.Store(&f)