fix(workflows): mask output env in persisted logs, preserve cancelled status, run agent step async

This commit is contained in:
2026-07-20 12:01:35 +01:00
parent e35e8fc839
commit 98284f4387
2 changed files with 37 additions and 14 deletions
+17 -7
View File
@@ -139,7 +139,7 @@ func executeRun(runID string) {
now := time.Now()
ctx, cancel := wfCtx()
defer cancel()
_, _ = db.Col("workflow_runs").UpdateOne(ctx, bson.M{"run_id": runID},
_, _ = db.Col("workflow_runs").UpdateOne(ctx, bson.M{"run_id": runID, "status": "running"},
bson.M{"$set": bson.M{"status": status, "finished_at": now}})
}
@@ -156,6 +156,7 @@ func runServer(runID string, srvIdx int, steps []models.ResolvedStep, serverID s
}
runEnv := map[string]string{}
allSecrets := map[string]string{}
serverFailed := false
for i, step := range steps {
@@ -169,6 +170,9 @@ func runServer(runID string, srvIdx int, steps []models.ResolvedStep, serverID s
// Merge secrets into command env (kept out of persisted logs).
secretVals := resolveSecrets(step.SecretRefs)
for k, v := range secretVals {
allSecrets[k] = v
}
cmdEnv := map[string]string{}
for k, v := range runEnv {
cmdEnv[k] = v
@@ -193,14 +197,14 @@ func runServer(runID string, srvIdx int, steps []models.ResolvedStep, serverID s
// Mask secret values before persisting.
stdout, stderr := "", ""
exit := 1
outEnv := map[string]string{}
outEnv := map[string]string{} // masked copy, safe to persist
if res != nil {
stdout = maskSecrets(res.Stdout, secretVals)
stderr = maskSecrets(res.Stderr, secretVals)
stdout = maskSecrets(res.Stdout, allSecrets)
stderr = maskSecrets(res.Stderr, allSecrets)
exit = res.ExitCode
for k, v := range res.OutputEnv {
outEnv[k] = v
runEnv[k] = v // implicit: all outputs flow to all later steps
runEnv[k] = v // real, unmasked value threads forward to later steps
outEnv[k] = maskSecrets(v, allSecrets)
}
} else {
stderr = "[vantage] agent did not return a result"
@@ -231,10 +235,16 @@ func runServer(runID string, srvIdx int, steps []models.ResolvedStep, serverID s
if serverFailed {
status = "failed"
}
// Persist only a masked copy of runEnv; the real (unmasked) runEnv was already
// used above to build cmdEnv for each step and must never be written to the DB.
maskedRunEnv := make(map[string]string, len(runEnv))
for k, v := range runEnv {
maskedRunEnv[k] = maskSecrets(v, allSecrets)
}
setServerRun(runID, srvIdx, bson.M{
"server_runs.$.status": status,
"server_runs.$.finished_at": fin,
"server_runs.$.run_env": runEnv,
"server_runs.$.run_env": maskedRunEnv,
})
}