Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 42 additions & 3 deletions .github/workflows/security-gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,62 @@ jobs:
with:
node-version: '22'

# GHSA-mrhx-c7xc-m3w5 (zod < 4.6.6, high, memory exhaustion on
# oversized array validation): two separate paths resolved to it
# in each package below.
#
# @stellar/mpp > mppx > viem/abitype/incur > zod was fixed for
# real, in sdk and cli, via a nested override (package.json's
# "overrides": { "mppx": { "zod": "^4.6.6" }, "@stellar/mpp": {...},
# "viem": {...} }) — every package on that path already accepts
# zod ^4.x, so this bumps it to a patched version rather than
# forcing anything. Verified 2026-10-23: `npm ls zod` shows that
# whole subtree resolving to 4.6.7/4.6.2→4.6.7 in both packages;
# both still build clean; a live test (temporarily installing a
# real unrelated critical advisory, GHSA-xvch-5gv4-984h via
# minimist@1.2.0) confirmed the allowlist below does NOT swallow
# it — the gate still failed on that one while passing on this
# GHSA, proving the allowlist is scoped to exactly this advisory,
# not a blanket pass.
#
# mcp does NOT get the same override — tried it, and it produces
# a real `npm error code ELSPROBLEMS: invalid: zod@3.25.76`
# (mcp's own direct "zod": "^3.25.0" dependency conflicts with
# @modelcontextprotocol/sdk wanting ^4.6.6 once the override is
# applied; npm's flatter resolution here doesn't give the same
# per-branch isolation pnpm gives the equivalent case in
# nirium-core). Reverted; mcp keeps the allowlist-only fix.
# (Separately, confirmed on a pristine clone of this repo's
# unmodified main: mcp's built server currently can't boot at all
# - `Cannot find package 'viem'` from mppx/dist/evm/client -
# pre-existing, unrelated to this fix, not touched here.)
#
# @x402/core (resolved in all three packages, 2.28.0) still
# requires zod ^3.24.2, which cannot resolve to 4.x even with the
# override — confirmed against the latest published @x402/core,
# same range. No patched 3.x release of zod exists either. That
# instance is what's allowlisted below in all three packages -
# the only path left reaching this GHSA in sdk/cli after the
# override, and the only mechanism available for mcp. Every other
# high finding still blocks the build. Revisit when @x402/core
# moves to zod 4 (no issue filed upstream yet as of this date).
- name: SDK — npm audit (high+ — blocks build)
working-directory: packages/sdk
run: |
npm install --legacy-peer-deps
npm audit --audit-level=high
npx audit-ci@7 --high --allowlist GHSA-mrhx-c7xc-m3w5

- name: CLI — npm audit (high+ — blocks build)
working-directory: packages/cli
run: |
npm install --legacy-peer-deps
npm audit --audit-level=high
npx audit-ci@7 --high --allowlist GHSA-mrhx-c7xc-m3w5

- name: MCP — npm audit (high+ — blocks build)
working-directory: packages/mcp
run: |
npm install --legacy-peer-deps
npm audit --audit-level=high
npx audit-ci@7 --high --allowlist GHSA-mrhx-c7xc-m3w5

python-audit:
name: Python Supply Chain Audit
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ console.log(market);

The other side of the counter. Wiring x402 by hand is ~25 lines of facilitator client, per-method auth headers, per-network scheme registration and a route table whose shape you have to reverse-engineer. This is the same thing with the defaults that already run in production:

```bash
npm install nirium @x402/express @x402/core @x402/stellar
```

```ts
import { x402Serve } from 'nirium';

Expand Down
2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ The Soroban contracts, the frontend at nirium.xyz and the agent API at nirium-ag
- domainLock and response obfuscation modules exist in the repo but are not mounted on any route. **Update, 2026-10-12 (checked against the agent codebase that day):** this line previously also listed "AML screening" as a live control. The AML middleware was never imported or mounted on any route and has been removed as dead code.

**Infrastructure:**
- Row Level Security (RLS) on all Supabase tables - **Update, 2026-10-23 (checked against the live project that day, read-only HEAD requests with no row content fetched):** this line was false for six tables (`auth_keys`, `payroll_runs`, `treasury_vaults`, `security_events`, `sandbox_accounts`, `sandbox_usage`), all readable in full by the public anon key the browser ships, because the agent's own backend used that same anon key for privileged access and their RLS policies were left permissive to compensate. The agent's database client has been switched to the service_role key (which does not depend on RLS at all); a migration to remove the permissive policies and restrict those six tables to `service_role` is prepared but not yet applied to the live project as of this update. Tables that stay intentionally open to anon (`logs`, `agent_logs`, `nirium_swarm_agents`, `strategies`, `nirium_protocol_records` - the public verifiable feed; `vault_delegations`'s anon insert/update/active-only-select, a documented design relying on on-chain signature verification, not RLS; `nirium_llm_config`, documented as holding no sensitive data) are not covered by this line and were not changed.
- Row Level Security (RLS) on all Supabase tables - **Update, 2026-10-23 (checked against the live project that day, read-only HEAD requests with no row content fetched):** this line was false for six tables (`auth_keys`, `payroll_runs`, `treasury_vaults`, `security_events`, `sandbox_accounts`, `sandbox_usage`), all readable in full by the public anon key the browser ships, because the agent's own backend used that same anon key for privileged access and their RLS policies were left permissive to compensate. The agent's database client has been switched to the service_role key (which does not depend on RLS at all); a migration to remove the permissive policies and restrict those six tables to `service_role` is prepared but not yet applied to the live project as of this update. Tables that stay intentionally open to anon (`logs`, `agent_logs`, `nirium_swarm_agents`, `strategies`, `nirium_protocol_records` - the public verifiable feed; `vault_delegations`'s anon insert/update/active-only-select, a documented design relying on on-chain signature verification, not RLS; `nirium_llm_config`, documented as holding no sensitive data) are not covered by this line and were not changed. **Update, 2026-10-23, later the same day (re-checked against the live project with the same read-only method):** a seventh table, `webhooks`, had the same exposure - its `secret` column is a raw HMAC signing key, stored in plaintext by necessity (it has to be the real key to sign outgoing payloads with), so this one was genuinely recoverable in cleartext, not just a hash. All seven tables' migrations have been applied to the live project and re-verified: the anon key now gets `Content-Range: */0` on all seven. The three `webhooks` rows that were exposed were already `active: false` test endpoints; their secrets were rotated before the fix landed. Closed.
- Non-custodial architecture - users retain sole key control
- HMAC-SHA256 signed immutable audit trail per agent action
- x402/MPP payment validation middleware on all premium routes
Expand Down
2 changes: 1 addition & 1 deletion actions/verify-audit-cid/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: nirium-protocol/nirium-sdk/actions/verify-audit-cid@main
- uses: nirium-protocol/nirium/actions/verify-audit-cid@main
id: audit
with:
cid: QmSSZdtt3dQ8BqUm62zrKQ85E4BUHYiVfvDgZmHfJsqU1U
Expand Down
17 changes: 9 additions & 8 deletions docs/FOR-REVIEWERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,14 @@ Three things you can check on Stellar Expert directly:
- Autonomous invest, **the agent signs** - this is the one that matters: the agent moved funds it doesn't own, and the contract gave it no way to take them out. [`82d73f53…6b3d4`](https://stellar.expert/explorer/public/tx/82d73f537e907140367f9343f63a36704c74a5286aced7a938cee8fffb56b3d4)
- The vault contract itself, roles readable on-chain: [`CAMDXG6L…K57MH`](https://stellar.expert/explorer/public/contract/CAMDXG6L4LXLXXV675KZSHM3BMSETZ4NVMC7JYIQCZ2JTG54OMSK57MH)

The underlying vault strategy (Etherfuse CETES on Blend v2) was audited by
OtterSec, March 2025 - 16 findings, all 13 vulnerabilities resolved. Full
writeup with the same links: [this repo's own README, "Networks"
The DeFindex vault and its Blend v2 strategy code were audited by OtterSec
(March 2025: 16 findings, 13 of them vulnerabilities, all resolved). The
Etherfuse CETES pool itself is outside that audit. Full writeup with the
same links: [this repo's own README, "Networks"
section](../README.md#networks), and the identical evidence is
cross-referenced in the full [Eras256/Nirium
mirror](https://github.com/Eras256/Nirium) - two independent places
citing the same verifiable transactions, not two different claims.
cross-referenced in the full [nirium-core
mirror](https://github.com/nirium-protocol/nirium-core) - both our repos
cite the same transactions; the chain is the independent source.

## 3. A real partner integration, not a listed logo

Expand All @@ -54,7 +55,7 @@ The demo-app integration itself,

**Another real integration, publicly thanked by the protocol, not just a logo.** [Trustless-Work/agentic-escrow-research](https://github.com/Trustless-Work/agentic-escrow-research): 4 PRs merged on 21-sep-2026 ([#1](https://github.com/Trustless-Work/agentic-escrow-research/pull/1), [#2](https://github.com/Trustless-Work/agentic-escrow-research/pull/2), [#3](https://github.com/Trustless-Work/agentic-escrow-research/pull/3), [#4](https://github.com/Trustless-Work/agentic-escrow-research/pull/4)), thanked by name by Trustless Work's official account.

**A real escrow cycle, liquidated with real money, not a description of one.** Beyond the 4 merged PRs above, Nirium ran Trustless Work's own Multi-Release escrow contract end to end on mainnet, 3-sep-2026: deploy → fund → approve → release, a real 0.50 USDC, self-directed (one key holding every role, proving the mechanism, not a decision to open this flow to Payouts production - that stays behind legal review). Four confirmed transactions, receiver balance moved by exactly 0.4985 USDC (0.50 minus Trustless Work's fixed 0.3% fee): [`4110dd16…12aefe84`](https://stellar.expert/explorer/public/tx/4110dd16df6c7cdaf50d89f7402e3e51de0ac4f63255f6601e800e3912aefe84) → [`7b181a13…451c09c`](https://stellar.expert/explorer/public/tx/7b181a13160d6d7170f78ba9a4e15309cc0a8f6e20a1db01adfcdb667451c09c) → [`a3aa35a2…4096ca5`](https://stellar.expert/explorer/public/tx/a3aa35a272774547d3ca4ce5a32e361641daac6cf829ecf8951b83a194096ca5) → [`0c533088…a8192b`](https://stellar.expert/explorer/public/tx/0c533088ab6326a78b9f79c197b7636ca4662a0d72562968ddea37f370a8192b). Full detail, including the deploy-path timing evidence, in the [Eras256/Nirium mirror's README](https://github.com/Eras256/Nirium#readme).
**A real escrow cycle, liquidated with real money, not a description of one.** Beyond the 4 merged PRs above, Nirium ran Trustless Work's own Multi-Release escrow contract end to end on mainnet, 3-sep-2026: deploy → fund → approve → release, a real 0.50 USDC, self-directed (one key holding every role, proving the mechanism, not a decision to open this flow to Payouts production - that stays behind legal review). Four confirmed transactions, receiver balance moved by exactly 0.4985 USDC (0.50 minus Trustless Work's fixed 0.3% fee): [`4110dd16…12aefe84`](https://stellar.expert/explorer/public/tx/4110dd16df6c7cdaf50d89f7402e3e51de0ac4f63255f6601e800e3912aefe84) → [`7b181a13…451c09c`](https://stellar.expert/explorer/public/tx/7b181a13160d6d7170f78ba9a4e15309cc0a8f6e20a1db01adfcdb667451c09c) → [`a3aa35a2…4096ca5`](https://stellar.expert/explorer/public/tx/a3aa35a272774547d3ca4ce5a32e361641daac6cf829ecf8951b83a194096ca5) → [`0c533088…a8192b`](https://stellar.expert/explorer/public/tx/0c533088ab6326a78b9f79c197b7636ca4662a0d72562968ddea37f370a8192b). Full detail, including the deploy-path timing evidence, in the [nirium-core mirror's README](https://github.com/nirium-protocol/nirium-core#readme).

## 4. Upstream contributions - bugs fixed in code we don't control

Expand Down Expand Up @@ -116,4 +117,4 @@ omit it - caught 2026-09-28 re-verifying this page.

*Every number and link on this page was checked live against its source
(Horizon, GitHub's API, the running API itself) before being written down
- not copied from an internal doc or an earlier draft. Last verified: 28 Sep 2026.*
- not copied from an internal doc or an earlier draft. Last verified: 23 Oct 2026.*
Loading
Loading