From 35ace20838ff18c9266c16c4d28130a3183cdad2 Mon Sep 17 00:00:00 2001 From: Sandipan Das Date: Wed, 16 Sep 2026 00:22:33 -0400 Subject: [PATCH 1/5] fix(deps): pin vulnerable transitive dependencies to patched versions bun audit flagged six transitive packages with known CVEs across the three lockfiles: shell-quote, brace-expansion, protobufjs, undici, nanoid, postcss. None are direct dependencies, so pin the patched versions via package.json overrides. --- argus-server/bun.lock | 13 ++++++++----- argus-server/package.json | 5 +++++ argus-ui/bun.lock | 8 ++++++-- argus-ui/package.json | 4 ++++ bun.lock | 5 ++++- package.json | 3 +++ 6 files changed, 30 insertions(+), 8 deletions(-) diff --git a/argus-server/bun.lock b/argus-server/bun.lock index 65f5fbf..4f3f127 100644 --- a/argus-server/bun.lock +++ b/argus-server/bun.lock @@ -14,6 +14,11 @@ }, }, }, + "overrides": { + "brace-expansion": "^5.0.12", + "protobufjs": "^7.6.6", + "undici": "^8.10.2", + }, "packages": { "@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.91.1", "", { "dependencies": { "json-schema-to-ts": "^3.1.1" }, "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["zod"], "bin": { "anthropic-ai-sdk": "bin/cli" } }, "sha512-LAmu761tSN9r66ixvmciswUj/ZC+1Q4iAfpedTfSVLeswRwnY3n2Nb6Tsk+cLPP28aLOPWeMgIuTuCcMC6W/iw=="], @@ -117,8 +122,6 @@ "@protobufjs/float": ["@protobufjs/float@1.0.2", "", {}, "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="], - "@protobufjs/inquire": ["@protobufjs/inquire@1.1.2", "", {}, "sha512-pa0vFRuws4wkvaXKK1uXZMAwAX4/t8ANaJo45iw/oQHNQ9q5xUzwgFmVJGXiga2BeN+zpX7Vf9vmsiIa2J+MUw=="], - "@protobufjs/path": ["@protobufjs/path@1.1.2", "", {}, "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="], "@protobufjs/pool": ["@protobufjs/pool@1.1.0", "", {}, "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="], @@ -163,7 +166,7 @@ "bowser": ["bowser@2.14.1", "", {}, "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg=="], - "brace-expansion": ["brace-expansion@5.0.6", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g=="], + "brace-expansion": ["brace-expansion@5.0.12", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ=="], "buffer-equal-constant-time": ["buffer-equal-constant-time@1.0.1", "", {}, "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="], @@ -257,7 +260,7 @@ "proper-lockfile": ["proper-lockfile@4.1.2", "", { "dependencies": { "graceful-fs": "^4.2.4", "retry": "^0.12.0", "signal-exit": "^3.0.2" } }, "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA=="], - "protobufjs": ["protobufjs@7.6.3", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.5", "@protobufjs/eventemitter": "^1.1.1", "@protobufjs/fetch": "^1.1.1", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.2", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.1", "@types/node": ">=13.7.0", "long": "^5.3.2" } }, "sha512-+k0vdJKNdW+Vu+dYe8tZA/VvQb6XKNWexC6URwBFXxNnjLJz9nQJCemGyNgRAWD+B7+nGNc9qMPGwcD7s4nzUw=="], + "protobufjs": ["protobufjs@7.6.6", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.5", "@protobufjs/eventemitter": "^1.1.1", "@protobufjs/fetch": "^1.1.1", "@protobufjs/float": "^1.0.2", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.1", "@types/node": ">=13.7.0", "long": "^5.3.2" } }, "sha512-dYDWdjSl5RNb7SgPxGQcRU+GtvP7s2fpkrY0r432PcOIaZ0/rBcxEZnQN67iJhFuQiVw754JDoPruPCNdGsbjg=="], "retry": ["retry@0.12.0", "", {}, "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow=="], @@ -279,7 +282,7 @@ "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], - "undici": ["undici@8.3.0", "", {}, "sha512-TkUDgb6tl7KOGZ+7e8E3d2FYgUQgF6z5YypqjWmixVQSQERFcVrVg0ySADm2LVLRh5ljAaHTCR5Fmz3Q34rB7Q=="], + "undici": ["undici@8.10.2", "", {}, "sha512-/y4/bH9YNU5hi9NIrpOuvGXFcxrj3CMrV+/AYpowAYTpHn8gX/XPFjNy766FPoYY0miQhdW977JFWKGNhBdwyQ=="], "undici-types": ["undici-types@7.24.6", "", {}, "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg=="], diff --git a/argus-server/package.json b/argus-server/package.json index c9c269a..72b7925 100644 --- a/argus-server/package.json +++ b/argus-server/package.json @@ -16,5 +16,10 @@ "devDependencies": { "@types/bun": "^1.2.0", "typescript": "^5.7.0" + }, + "overrides": { + "brace-expansion": "^5.0.12", + "protobufjs": "^7.6.6", + "undici": "^8.10.2" } } \ No newline at end of file diff --git a/argus-ui/bun.lock b/argus-ui/bun.lock index 4bf05ab..d845190 100644 --- a/argus-ui/bun.lock +++ b/argus-ui/bun.lock @@ -21,6 +21,10 @@ }, }, }, + "overrides": { + "nanoid": "^3.3.19", + "postcss": "^8.5.28", + }, "packages": { "@emnapi/core": ["@emnapi/core@1.10.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw=="], @@ -156,13 +160,13 @@ "marked": ["marked@18.0.5", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-S6GcvALHg6K4ohtu4E7x0a1AqhAjp6cV8KhLSyN9qVapnzJkusVBxZRcIU9AeYsbe6P1hKDusSbEOzGyyuce6w=="], - "nanoid": ["nanoid@3.3.12", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ=="], + "nanoid": ["nanoid@3.3.19", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug=="], "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], "picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="], - "postcss": ["postcss@8.5.15", "", { "dependencies": { "nanoid": "^3.3.12", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A=="], + "postcss": ["postcss@8.5.28", "", { "dependencies": { "nanoid": "^3.3.18", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A=="], "react": ["react@19.2.7", "", {}, "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ=="], diff --git a/argus-ui/package.json b/argus-ui/package.json index bbdaa02..3669899 100644 --- a/argus-ui/package.json +++ b/argus-ui/package.json @@ -23,5 +23,9 @@ "tailwindcss": "^4.3.0", "typescript": "^5.7.0", "vite": "^8.0.16" + }, + "overrides": { + "nanoid": "^3.3.19", + "postcss": "^8.5.28" } } \ No newline at end of file diff --git a/bun.lock b/bun.lock index 06f72b9..da057bd 100644 --- a/bun.lock +++ b/bun.lock @@ -9,6 +9,9 @@ }, }, }, + "overrides": { + "shell-quote": "^1.10.0", + }, "packages": { "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], @@ -38,7 +41,7 @@ "rxjs": ["rxjs@7.8.2", "", { "dependencies": { "tslib": "^2.1.0" } }, "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA=="], - "shell-quote": ["shell-quote@1.8.3", "", {}, "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw=="], + "shell-quote": ["shell-quote@1.10.0", "", {}, "sha512-w1aiOKwKuRgtwAReIIj89puqg+I7GvX4IbLrvmhXbzQsj1+Zwi4VO3+fa6ZF91TWSjIxoEkKnMeHcLEODK5ZXA=="], "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], diff --git a/package.json b/package.json index 16f19b6..2a9d607 100644 --- a/package.json +++ b/package.json @@ -5,5 +5,8 @@ "type": "module", "devDependencies": { "concurrently": "^9.2.0" + }, + "overrides": { + "shell-quote": "^1.10.0" } } \ No newline at end of file From a9c63a89269d7fbb842b557d974ee9b058c0e1ff Mon Sep 17 00:00:00 2001 From: Sandipan Das Date: Wed, 16 Sep 2026 00:22:38 -0400 Subject: [PATCH 2/5] ci: add scheduled bun audit workflow GitHub's dependency graph doesn't parse bun.lock, so Dependabot alerts never fire here. Run bun audit on push, PR, and a weekly schedule instead, mirroring the govulncheck workflow in gwlint. --- .github/workflows/vulncheck.yml | 37 +++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .github/workflows/vulncheck.yml diff --git a/.github/workflows/vulncheck.yml b/.github/workflows/vulncheck.yml new file mode 100644 index 0000000..e44739a --- /dev/null +++ b/.github/workflows/vulncheck.yml @@ -0,0 +1,37 @@ +name: Vulnerabilities + +# Its own workflow because it is the one check whose result can change without the +# repository changing: a newly published advisory against an unchanged dependency only +# surfaces on a scheduled run. bun.lock isn't parsed by GitHub's dependency graph, so +# Dependabot alerts don't cover this repo — bun audit is what actually catches it. +on: + push: + branches: [main] + pull_request: + branches: [main] + schedule: + # Weekly, off the hour to avoid the top-of-hour scheduling crowd. + - cron: "17 4 * * 1" + # So an advisory can be checked without waiting for the next scheduled run. + workflow_dispatch: + +jobs: + vulncheck: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + + - uses: oven-sh/setup-bun@v2 + with: + bun-version: "1.3.6" + + # Each has its own bun.lock (root, server, UI aren't one bun workspace), so each + # gets its own audit. Reads the lockfile directly — no install needed. + - name: Audit — root + run: bun audit + + - name: Audit — server + run: bun audit --cwd argus-server + + - name: Audit — UI + run: bun audit --cwd argus-ui From ae7a0951e881e1be8f77e505585bdafceca77259 Mon Sep 17 00:00:00 2001 From: Sandipan Das Date: Wed, 16 Sep 2026 00:22:48 -0400 Subject: [PATCH 3/5] docs: add security policy Adapted from gwlint's SECURITY.md, scoped to argus's actual attack surface (REST/WebSocket/webhook endpoints, tool-calling agent) instead of copied as-is. --- SECURITY.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..8ff1b6f --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,20 @@ +# Security policy + +## Reporting a vulnerability + +Please don't open a public issue for a security problem. + +Use [GitHub's private vulnerability reporting](https://github.com/sdOps/argus/security/advisories/new) instead, from the repo's **Security** tab ("Report a vulnerability"). +This opens a private advisory visible only to you and the maintainers, so the issue can be discussed and fixed before it's public. + +We'll acknowledge a new report within a few days and follow up with next steps once we've assessed it. + +## Scope + +Argus is a headless agent that runs a server: argus-server exposes a REST API, a WebSocket, and a webhook receiver (Alertmanager alerts in), and it drives an LLM-backed agent that can call tools, including ones that execute remediation actions against the monitored stack. +The most relevant vulnerability classes here are things like: unauthenticated or under-authorized access to the API/WebSocket/webhook endpoints; a crafted alert or tool result that leads to prompt injection or an unintended tool call; secrets (LLM provider keys, webhook URLs) leaking via logs or responses; or a dependency with a known, reachable vulnerability (tracked via `bun audit`, see `.github/workflows/vulncheck.yml`). + +## Supported versions + +Argus is pre-1.0 and does not yet maintain multiple release branches. +Fixes land on `main`; there's no backport policy at this stage. From 5bcc74dd68e2f83fbfc23b0a8835814a221cc5b5 Mon Sep 17 00:00:00 2001 From: Sandipan Das Date: Wed, 16 Sep 2026 00:29:18 -0400 Subject: [PATCH 4/5] ci: bump actions/checkout to v7 v5 was two majors behind. No behavior change affects these workflows (v6's cred-persistence change and v7's fork-PR checkout block are both no-ops here). oven-sh/setup-bun@v2 already floats to the latest v2.x release, so it's unchanged. --- .github/workflows/ci.yml | 4 ++-- .github/workflows/vulncheck.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4b2c2e6..4ed4497 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ jobs: ci: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v7 - uses: oven-sh/setup-bun@v2 with: @@ -40,7 +40,7 @@ jobs: docker-build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v7 - name: Build compose images (demo-services + argus-server, which builds the UI) run: docker compose build diff --git a/.github/workflows/vulncheck.yml b/.github/workflows/vulncheck.yml index e44739a..70a9cd7 100644 --- a/.github/workflows/vulncheck.yml +++ b/.github/workflows/vulncheck.yml @@ -19,7 +19,7 @@ jobs: vulncheck: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v7 - uses: oven-sh/setup-bun@v2 with: From e6eacf4582a23375f910cbfad147792dbf432888 Mon Sep 17 00:00:00 2001 From: Sandipan Das Date: Wed, 16 Sep 2026 00:31:00 -0400 Subject: [PATCH 5/5] ci: lint PR titles against Conventional Commits Mirrors gwlint's pr-title.yml. Same action, same pinned version. --- .github/workflows/pr-title.yml | 36 ++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .github/workflows/pr-title.yml diff --git a/.github/workflows/pr-title.yml b/.github/workflows/pr-title.yml new file mode 100644 index 0000000..4a9045e --- /dev/null +++ b/.github/workflows/pr-title.yml @@ -0,0 +1,36 @@ +name: PR Title + +# Lints the PR title against Conventional Commits. This matters most on a +# squash merge, where the squash commit message defaults to the PR title — +# argus also allows merge and rebase merges, where individual commits land +# as-is, so this doesn't guarantee every commit on main complies, only the +# PR title itself. +on: + pull_request: + types: [opened, edited, synchronize, reopened] + +permissions: + pull-requests: read + +concurrency: + group: pr-title-${{ github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + lint: + name: Lint PR title + runs-on: ubuntu-latest + steps: + - uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6.1.1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + types: | + feat + fix + chore + docs + refactor + test + ci + requireScope: false