git-credential-mosaic: escape the escalation record, and stop naming a record that was never written
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
Both defects found in review by rev-code-01 on #1311. F3 — the JSONL record interpolated every field with a bare %s. An identity comes from git config or the environment and a cwd is whatever directory git ran in, so either can contain a quote or a backslash. One such refusal turned the day's spool into unparseable JSONL, and the operator would only discover it while reading the record that explains an outage. Fields are now JSON-escaped. F2 — the diagnostic printed "record: <spool>/<date>.jsonl" unconditionally, but the record is only written inside the branch where mkdir -p succeeded. When the spool cannot be created the helper named a file that does not exist, on exactly the hosts where the escalation was lost. It now reports the real path or says NOT WRITTEN. Also: prettier on README.md, which was the format-step failure on pipeline 2508. It reflowed only the two tables this branch added. Tests: cases 14 and 15 cover both. Verified discriminating — against the previous helper with these same tests, case 14 fails with the unparseable record printed and case 15 fails on both assertions; against this one both pass. The first draft of case 14 used `ls "$spool"/*.jsonl | head -1`, which under `set -o pipefail` exits 2 on a missed glob and killed the suite with zero output — the same silent-nonzero failure rev-code-01 hit from a partial tools/ extraction and the reason this file exists. Replaced with a glob loop and a comment.
This commit is contained in:
@@ -141,18 +141,42 @@ ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
# top of it is best-effort. Record and alert are deduplicated separately — a cap
|
||||
# on the alert alone lets the spool grow without bound exactly while the operator
|
||||
# is being told nothing, so the louder the failure the quieter it gets.
|
||||
#
|
||||
# A record field is arbitrary operator-supplied text: an identity comes from git
|
||||
# config or the environment, and cwd is whatever directory git ran in. Either can
|
||||
# contain a quote or a backslash, which would make the line unparseable JSON --
|
||||
# and a spool that silently stops parsing is worse than no spool, because the
|
||||
# operator only discovers it while reading the record that explains an outage.
|
||||
json_escape() {
|
||||
local s=$1
|
||||
s=${s//\\/\\\\}
|
||||
s=${s//\"/\\\"}
|
||||
s=${s//$'\t'/\\t}
|
||||
s=${s//$'\r'/\\r}
|
||||
s=${s//$'\n'/\\n}
|
||||
printf '%s' "$s"
|
||||
}
|
||||
|
||||
spool="${MOSAIC_CREDENTIAL_SPOOL:-$HOME/.local/state/mosaic-credential-escalations}"
|
||||
spool_record=""
|
||||
if mkdir -p "$spool" 2>/dev/null; then
|
||||
chmod 700 "$spool" 2>/dev/null
|
||||
spoolfile="$spool/$(date -u +%Y%m%d).jsonl"
|
||||
dedupe="$spool/.spooled-${seat}-${ident:-none}-${reason}-$(date -u +%Y%m%d%H%M)"
|
||||
if [ ! -e "$dedupe" ]; then
|
||||
: > "$dedupe" 2>/dev/null
|
||||
spoolfile="$spool/$(date -u +%Y%m%d).jsonl"
|
||||
printf '{"ts":"%s","reason":"%s","identity":"%s","identity_source":"%s","kind":"%s","seat":"%s","host":"%s","cwd":"%s"}\n' \
|
||||
"$ts" "$reason" "${ident:-<unset>}" "$ident_src" "${ident_kind:-none}" "$seat" "$host" "$PWD" \
|
||||
"$(json_escape "$ts")" "$(json_escape "$reason")" \
|
||||
"$(json_escape "${ident:-<unset>}")" "$(json_escape "$ident_src")" \
|
||||
"$(json_escape "${ident_kind:-none}")" "$(json_escape "$seat")" \
|
||||
"$(json_escape "$host")" "$(json_escape "$PWD")" \
|
||||
>> "$spoolfile" 2>/dev/null
|
||||
chmod 600 "$spoolfile" 2>/dev/null
|
||||
fi
|
||||
# Name the record only if one is actually on disk. Printing the path
|
||||
# unconditionally sends the operator to a file that does not exist on exactly
|
||||
# the hosts where the spool could not be created.
|
||||
[ -s "$spoolfile" ] && spool_record="$spoolfile"
|
||||
find "$spool" -maxdepth 1 -name '.spooled-*' -mmin +120 -delete 2>/dev/null
|
||||
fi
|
||||
|
||||
@@ -186,6 +210,11 @@ seat and is read ONLY from its own secrets/ slot; any other identity is read fro
|
||||
If this identity legitimately needs git access and has none, ask the orchestrator
|
||||
to provision one.
|
||||
|
||||
record: ${spool}/$(date -u +%Y%m%d).jsonl
|
||||
EOF
|
||||
|
||||
if [ -n "$spool_record" ]; then
|
||||
echo " record: ${spool_record}" >&2
|
||||
else
|
||||
echo " record: NOT WRITTEN — spool unavailable at ${spool}" >&2
|
||||
fi
|
||||
exit 1
|
||||
|
||||
Reference in New Issue
Block a user