Conversation
This was referenced Sep 13, 2026
Open
Open
Contributor
Author
|
@MrAlders0n please review this change with your Claude agent as part of the September 13 Beacon review batch. The current candidate is 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. |
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.
What this PR does
Protect the reserved
/api/v1/adminsubtree with a single operator bearer key, replacingNoopAuth. Setauth.api_keyorBEACON_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 useCache-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
Checklist
go build ./...passesgofmt -l .is emptygo vet ./...passesgo test ./...passesTesting 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.