Skip to content

feat(auth): protect the admin subtree with a bearer key - #146

Open
n30nex wants to merge 1 commit into
MeshCore-Beacon:devfrom
n30nex:codex/beacon-bearer-auth
Open

n30nex wants to merge 1 commit into
MeshCore-Beacon:devfrom
n30nex:codex/beacon-bearer-auth

Conversation

@n30nex

@n30nex n30nex commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

What this PR does

Protect the reserved /api/v1/admin subtree with a single operator bearer key, replacing NoopAuth. Set auth.api_key or BEACON_API_KEY; a set environment variable overrides YAML, including an explicitly empty value that disables admin access.

Closes #59. An unconfigured key returns JSON 503 for admin requests while public reads and WebSockets remain available. Configured auth rejects missing, incorrect, malformed or duplicate Authorization headers with the existing JSON error envelope and WWW-Authenticate: Bearer. Verification uses constant-time comparison and accepts the case-insensitive Bearer scheme. Query/form tokens do not grant access. Protected responses use Cache-Control: no-store, and the config key is excluded from JSON serialization.

This establishes the auth boundary only. Admin operations belong to #60; an accepted key currently reaches the empty admin router's 404. Global CORS preflights remain public. Documentation requires HTTPS at the proxy, private direct listener access, a random key and restart-based rotation. No key is generated or committed, and no schema or dependency changes are included.

Type of change

  • New feature
  • Tests
  • Docs / config

Checklist

  • go build ./... passes
  • gofmt -l . is empty
  • go vet ./... passes
  • go test ./... passes
  • New behavior has unit and router/config tests
  • Swagger regenerated; no generated diff or new operation
  • No DB or dependency changes
  • I have read CONTRIBUTING.md

Testing notes

Full local and native Pi 5 Go checks pass, with PostgreSQL integration tests enabled natively. Focused Windows race checks cover config, middleware and router. Tests cover unset/empty/environment/YAML precedence, malformed and duplicate headers, exact token matching, ignored query/form credentials, subtree root/children/double slashes and multiple methods, unchanged public reads, and unauthenticated CORS preflights. A missing or rejected token never reaches the downstream handler.

CI and CodeQL pass. The exact combined ARM64 binary was also run in a temporary private instance with a generated, short-lived key: missing/wrong/duplicate/query/form credentials returned 401, the correct key reached the expected 404, and public reads remained 200. The key did not appear in application logs; the instance and transient key file were removed. It used an isolated test database and no live MQTT connection.

The Canadaverse preview includes this change with prior candidates. Admin access is deliberately unconfigured there and returns JSON 503/no-store. Public CORS preflights, API reads, WebSocket upgrade/hello/ping, both live feeds and the corresponding-source hash pass. Existing HTTP and WebSocket limits remain intact in the combined build. This PR is based directly on current dev; when integrating with #140/#141, retain their additional router arguments alongside the new auth config.

AI-assisted implementation and testing under the contributor's standing authorization; submitted for maintainer review without claiming a separate human review of this final diff.

@n30nex

n30nex commented Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

@MrAlders0n please review this change with your Claude agent as part of the September 13 Beacon review batch. The current candidate is aaacfd3a9605; validation and Pi evidence are in the PR description.

Please check bearer parsing, constant-time matching, disabled-admin behavior, CORS/public-route preservation and environment/YAML precedence. This implements the scoped authentication request and now links issue #59 for closure on merge. Admin operations remain in #60.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Authentication

1 participant