Repository navigation
fix(security): redact secrets, harden dispatch, add timeouts, tighten deploy - #455
Merged
Merged
Conversation
… deploy - Add utils/redact.py and apply it to logs, Telegram sends, crash alerts, the automation digest, and web3 provider errors so RPC/API keys never reach Telegram, the alerts DB/API, or journald. - Run the emergency dispatch hook even when Telegram delivery fails; retry Telegram 429s once after retry_after; truncate by UTF-16 length; share the parse-error plain-text retry with the test-chat path. - Add Alert.dispatch so unconfirmed signals notify without moving funds: stables depegs need two consecutive breaches, 3Jane/Cap PPS drops need a minimum size. Sign a sent_at timestamp into the dispatch body for replay protection. - Per-task timeouts in jobs.yaml (default 3600s, stables 300s) and timeouts on git fetch/reset and uv sync so a hang can't freeze a profile or code sync; timeouts on Gauntlet requests. - Deploy: API unit loads no secrets and cannot read /etc/monitoring; Caddy fails closed on an empty token list; install.sh no longer stores personal gh tokens; CI pins actions to SHAs with read-only permissions. - Explainer: treat supplied context as untrusted and label AI summaries unverified. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
spalen0
marked this pull request as ready for review
November 5, 2026 11:28
- git sync: on timeout send SIGTERM before SIGKILL so git cleans up its lock files, and remove lock files older than 30 minutes left by a killed process. - dispatch: run the alert hook before the Telegram send so 429 waits and Markdown retries cannot delay it. - 3Jane PPS / Cap stcUSD: measure the dispatch gate as drawdown from the peak since the last dispatch-eligible alert, so a loss split into many small drops still dispatches. - stables: a prior breach older than 25 minutes no longer confirms a new one. - redaction: match configured secrets in escape_markdown form, cover suffixed names (TELEGRAM_BOT_TOKEN_DEFAULT, *_SECRET_X) and bare bot tokens, mask scheme-less provider URLs, use a Markdown-safe REDACTED marker, cache the secret list, and drop a duplicate redaction call. - docs: 3Jane and Cap READMEs, new stables README, monitoring.yaml. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # utils/alert.py # utils/telegram.py
…erate malformed provider URLs - git sync: run each step in its own process group, signal the whole group on timeout (SIGTERM, then SIGKILL), and bound output draining so a descendant holding the pipes cannot keep the sync profile locked. - cap: a drop of convertToAssets(1e18) to zero is dispatch-eligible. - redaction: a provider URL that urlsplit rejects no longer makes every redact_secrets call raise; the value is still masked whole. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…meouts - stables: a failed send no longer skips later protocols' dispatch; a breach only confirms on a newer DeFiLlama sample with minimum spacing - telegram: replace lone surrogates; count the test-chat label in the limit - redact: keep token-address links and word slugs, mask drpc dkey - automation: stop timed-out tasks with SIGTERM then SIGKILL per process group; run_with_alert kills detached CLI agents on SIGTERM - share the peak-drawdown dispatch gate between Cap and 3Jane Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Port the PR's dispatch hardening onto main's durable emergency queue (#457): - Keep the Alert.dispatch gate: unconfirmed signals are never enqueued. - Redact the alert message before it is persisted to the outbox or sent. - Drop the signed `sent_at` field. Retries must resend the exact persisted bytes and keep the liquidity envelope unchanged; vaults-mommy dedupes on the signed event_id instead. Runbook updated accordingly. - Give the per-minute emergency-delivery-retries task a 600s timeout so a hang can't block retries behind its flock for the 1h default. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes from a security and stability review of the monitoring box. I reproduced the first two issues before fixing them.
Secret leakage (high)
ProviderConnectionErrorput full RPC URLs (/v2/<alchemy-key>) in its message.run_with_alertthen sentstr(exc)to Telegram and stored it inalert_eventsunder the protocol key, which the API and public site query. The automation digest did the same with stderr tails.utils/redact.pymasks configured secrets:PROVIDER_URL_*becomesscheme://host/***, and the values of*_KEY,*_TOKEN,*_SECRETand*_PASSWORDvars become***. It also has pattern fallbacks for bot tokens,?apikey=query params and keys in RPC URL paths.send_telegram_messagebefore the message is stored or sent, in crash alerts, in the digest error tail, in web3 provider errors and logs (host only), and in the dispatched message.Emergency dispatch (high)
retry_after(capped at 30s).Alert.dispatchflag. Unconfirmed signals still alert but don't move funds:dispatch=Falsealerts are never enqueued, and the message is redacted before it is written to the outbox DB or sent. The signed body has nosent_at, because retries resend the exact persisted bytes and the liquidity envelope stays unchanged. Vaults-mommy dedupes onevent_id.Stability (medium)
timeout:injobs.yaml: default 3600s, 300s for thestablessync-heartbeat task, 600s for the per-minuteemergency-delivery-retriestask. A timed-out task is killed and shows up in the digest. Before this, a hung task held itsflockforever, and if that wasten_minute, code sync stopped too.git fetch(120s),git reset(60s) anduv sync(600s) now have timeouts.requests.getcalls now have timeouts.Deploy / CI
monitoring-api.service: no longer loads anEnvironmentFile(the API needs no credentials), and/etc/monitoringisInaccessiblePaths.Caddyfile: rejects any bearer value that isn't 64 hex characters before comparing tokens. An emptyALERTS_API_TOKENSpreviously reduced the token check to^Bearer ()$; it now fails closed. I checked this against a local Caddy 2.10.2:The docs now include an
ExecStartPrecheck so Caddy refuses to start without tokens.install.sh: no longer copies the operator's personalgh auth tokeninto~/.git-credentials, a file the service can read. It requires an explicitGITHUB_TOKENand the docs recommend a fine-grained, read-only token.CI: actions pinned to commit SHAs,
permissions: contents: read, andpersist-credentials: false.Runbook: new "Security baseline" section and a note on rotating keys after redaction.
LLM explainer (low)
AI Summary (unverified).Smaller fixes
jobs.yamlcomment about manualuv sync.Behaviour changes to check
PPS_DISPATCH_MIN_DECREASE_BPSandASSETS_PER_SHARE_DISPATCH_MIN_DECREASE_BPSif you want different thresholds.timeout:.install.shre-renders it.Ops follow-ups (not code)
alert_eventsrows.main: required review and CI, no force push, signed commits if possible.ExecStartPretoken check to the caddy drop-in.Test plan
uv run pytest tests/: 2318 passed, 4 skipped (after merging main). New tests cover redaction, 429 retry, hook-on-failure, dispatch gating, task/git/uv timeouts, stables confirmation, and the 3Jane/Cap thresholds.ruff check,ruff format --check,ty checkbash -n deploy/install.sh🤖 Generated with Claude Code