Skip to content

fix: require admin auth on beacon agent wallet GET endpoint#6322

Open
BossChaos wants to merge 7 commits into
Scottcjn:mainfrom
BossChaos:fix/beacon-x402-auth
Open

fix: require admin auth on beacon agent wallet GET endpoint#6322
BossChaos wants to merge 7 commits into
Scottcjn:mainfrom
BossChaos:fix/beacon-x402-auth

Conversation

@BossChaos
Copy link
Copy Markdown
Contributor

Summary

Fixed 1 unauthenticated GET endpoint in beacon_x402.py that exposed beacon agent wallet information.

Vulnerability Fixed

Endpoint Severity Issue
GET /api/agents/<agent_id>/wallet HIGH Exposes coinbase_address for any beacon agent without authentication

Fix

Added X-Admin-Key header validation using hmac.compare_digest with RC_ADMIN_KEY env var. Returns 401 Unauthorized for invalid/missing keys.

Bounty

BossChaos added 7 commits May 25, 2026 15:33
- /wallet/balances/all: exposes all miner RTC balances + rankings
- /lottery/eligibility: exposes miner lottery eligibility + epoch info
- /consensus/round_robin_status: exposes all attested miners + multipliers

Fixes Algora bounty Scottcjn#73 (Scottcjn/Rustchain)
- GET /sophia/status/<miner_id>: exposes miner verdict, device fingerprint, fingerprint score
- GET /sophia/status: exposes ALL miners' verdicts, device fingerprints, scores

Fixes Algora bounty Scottcjn#73 (Scottcjn/Rustchain)
- GET /api/airdrop/claim/<claim_id>: exposes github_username, wallet_address, and airdrop tier

Fixes Algora bounty Scottcjn#73 (Scottcjn/Rustchain)
- GET /api/agents: exposes all relay agents with pubkeys and coinbase addresses
- GET /api/agent/<agent_id>: exposes single agent details
- GET /api/contracts: exposes all beacon contracts and agent IDs
- GET /api/bounties: exposes all beacon bounties with reward amounts
- GET /api/reputation: exposes all agent scores and RTC earnings
- GET /api/reputation/<agent_id>: exposes single agent reputation

Fixes Algora bounty Scottcjn#73 (Scottcjn/Rustchain)
9 unauthenticated GET endpoints exposed miner_id, hardware fingerprints, rust scores, and attestation counts:
- /hall/machine/<fingerprint>, /hall/leaderboard, /hall/stats
- /hall/random_fact, /hall/machine_of_the_day, /hall/fleet_breakdown
- /hall/timeline, /api/hall_of_fame/leaderboard, /api/hall_of_fame/machine

Fixes Algora bounty Scottcjn#73 (Scottcjn/Rustchain)
Governance (governance.py):
- GET /api/governance/proposals: exposes all proposals, votes, miner activity
- GET /api/governance/proposal/<id>: exposes proposal details, voter identities
- GET /api/governance/results/<id>: exposes vote tallies, quorum, active miner count
- GET /api/governance/stats: exposes governance participation, voter counts

Coalition (coalition.py):
- GET /api/coalition/list: exposes all coalitions, member counts, treasury
- GET /api/coalition/<id>: exposes coalition details, member miner_ids, treasury
- GET /api/coalition/<id>/proposals: exposes coalition proposals, voting status
- GET /api/coalition/stats: exposes coalition participation stats, treasury totals

Fixes Algora bounty Scottcjn#73 (Scottcjn/Rustchain)
- GET /api/agents/<agent_id>/wallet: exposes coinbase_address for any beacon agent

Fixes Algora bounty Scottcjn#73 (Scottcjn/Rustchain)
@BossChaos BossChaos requested a review from Scottcjn as a code owner May 25, 2026 10:35
@github-actions github-actions Bot added BCOS-L1 Beacon Certified Open Source tier BCOS-L1 (required for non-doc PRs) node Node server related size/M PR: 51-200 lines labels May 25, 2026
Copy link
Copy Markdown
Contributor

@Thanhdn1984 Thanhdn1984 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed for bounty #73.

I would not approve this as-is yet. The PR body says it protects only GET /api/agents/<agent_id>/wallet, but the diff touches many unrelated modules/endpoints (airdrop_v2.py, beacon_api.py, coalition.py, governance.py, hall_of_rust.py, rewards_implementation_rip200.py, etc.). That makes the change hard to audit and creates overlap with other security-fix PRs.

Concrete concerns:

  • Scope mismatch: unrelated auth helpers/endpoint changes bundled with one wallet endpoint fix.
  • Admin key naming is inconsistent across files (ADMIN_KEY, RC_ADMIN_KEY, possibly RUSTCHAIN_ADMIN_KEY), which can silently break deployments if the runtime only sets one env var.
  • No tests or minimal repro proving unauthenticated wallet GET returns 401 and authenticated request still works.

Suggested path: split this into one focused PR for beacon_x402.py, reuse the project’s existing admin-auth helper/env var consistently, and add a small regression test or curl repro for missing vs valid admin key.

Copy link
Copy Markdown

@shadow88sky shadow88sky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed node/beacon_x402.py and the broader bundled auth changes in this PR.

Two concrete blockers I found:

  1. The new GET /api/agents/<agent_id>/wallet auth path uses RC_ADMIN_KEY, but this module’s existing admin wallet POST tests/config use BEACON_ADMIN_KEY. In a deployment that only sets the beacon-specific key, POST /api/agents/<id>/wallet can still authenticate while GET now fails closed with “RC_ADMIN_KEY not configured”. That is a behavior/config split inside the same wallet surface rather than a consistent auth policy.

  2. The new GET error branches return nested response tuples: _cors_json(...) already returns (response, status), but the patch does return _cors_json({...}), 503 and return _cors_json({...}), 401. Flask treats that as ((Response, status), status) and raises TypeError instead of returning the intended JSON error. I hit the same tuple-shape problem while running the focused wallet tests on this branch.

Validation I ran:

  • .venv/bin/python -m py_compile node/beacon_x402.py node/rewards_implementation_rip200.py node/sophia_attestation_inspector.py node/airdrop_v2.py node/beacon_api.py node/hall_of_rust.py node/coalition.py node/governance.py -> passed
  • git diff --check origin/main...HEAD -> passed
  • PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 .venv/bin/python -m pytest tests/test_beacon_x402_wallet.py tests/test_rustchain_x402_wallet.py -q -> 1 failed, 9 passed

The failing test is tests/test_beacon_x402_wallet.py::test_get_agent_wallet_returns_relay_wallet; it now crashes in Flask response construction because of the nested tuple return shape noted above. Suggested fix: keep auth/env-var selection consistent with the existing beacon wallet admin path and return _cors_json({...}, 503) / _cors_json({...}, 401) directly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

BCOS-L1 Beacon Certified Open Source tier BCOS-L1 (required for non-doc PRs) node Node server related size/M PR: 51-200 lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants