feat(coderd): audit whether a workspace build secret is ephemeral

This commit is contained in:
Steven Masley
2026-10-15 21:25:16 +00:00
parent 93d7cd3c29
commit c6645491dd
2 changed files with 17 additions and 10 deletions
+13 -9
View File
@@ -11,12 +11,15 @@ import (
)
// WorkspaceBuildSecret is the metadata of a secret linked to a workspace
// build. Secret values are never audited.
// build. Secret values are never audited. Ephemeral is recorded so an
// ephemeral secret missing from the next build's entry can be told apart
// from one the request removed.
type WorkspaceBuildSecret struct {
Name string `json:"name"`
EnvName string `json:"env_name"`
FilePath string `json:"file_path"`
Source database.WorkspaceSecretSource `json:"source"`
Name string `json:"name"`
EnvName string `json:"env_name"`
FilePath string `json:"file_path"`
Ephemeral bool `json:"ephemeral"`
Source database.WorkspaceSecretSource `json:"source"`
}
// WorkspaceBuildFields returns the additional fields for a workspace build
@@ -42,10 +45,11 @@ func WorkspaceBuildFields(ctx context.Context, db database.Store, workspace data
}
for _, row := range rows {
fields.WorkspaceSecrets = append(fields.WorkspaceSecrets, WorkspaceBuildSecret{
Name: row.Name,
EnvName: row.EnvName,
FilePath: row.FilePath,
Source: row.Source,
Name: row.Name,
EnvName: row.EnvName,
FilePath: row.FilePath,
Ephemeral: row.Ephemeral,
Source: row.Source,
})
}
return fields, nil
+4 -1
View File
@@ -7160,15 +7160,18 @@ func TestWorkspaceSecretsAudit(t *testing.T) {
req.Secrets = []codersdk.WorkspaceSecretInput{
{Name: "api-key", Value: new("secret-value"), EnvName: "API_KEY"},
{Name: "cert", Value: new("secret-value"), FilePath: "/home/coder/.cert"},
{Name: "one-shot", Value: new("secret-value"), EnvName: "ONE_SHOT", Ephemeral: true},
}
})
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID)
require.ElementsMatch(t, []audit.WorkspaceBuildSecret{
{Name: "api-key", EnvName: "API_KEY", Source: database.WorkspaceSecretSourceRequest},
{Name: "cert", FilePath: "/home/coder/.cert", Source: database.WorkspaceSecretSourceRequest},
{Name: "one-shot", EnvName: "ONE_SHOT", Ephemeral: true, Source: database.WorkspaceSecretSourceRequest},
}, buildSecrets(t, workspace.LatestBuild.ID))
// The entry lists the build's full set. Removed secrets are absent.
// The entry lists the build's full set. Removed secrets are absent, and so
// is the ephemeral secret, which the previous entry marked as such.
build, err := client.CreateWorkspaceBuild(ctx, workspace.ID, codersdk.CreateWorkspaceBuildRequest{
Transition: codersdk.WorkspaceTransitionStop,
Secrets: []codersdk.WorkspaceSecretInput{