mirror of
https://github.com/DeBrosOfficial/orama.git
synced 2026-08-07 20:09:27 +00:00
Namespace gateways never received the API-key HMAC secret, so auth.Service.HashAPIKey returned keys UNCHANGED (service.go:172). One gap, two symptoms — both confirmed live on devnet: 1. A namespace gateway could not authenticate ANY key from the authoritative core registry: core stores 64-char HMAC-SHA256 hashes, the namespace gateway looked up the 39-char raw key. Valid key on main gateway :6001 => 200, same key on namespace gateway :10004 => 401. This is what broke serverless WASM http_fetch calls to /v1/auth/token (bugboard #160). 2. Keys the namespace gateway wrote were stored in PLAINTEXT, against docs/SECURITY.md:54-59. The anchat-test namespace RQLite holds 361 39-char plaintext keys vs 64-char hashes in core. The main gateway reads the secret from <oramaDir>/secrets/api-key-hmac-secret (node/gateway.go:50). The namespace spawner never passed it and the gateway YAML had no field for it, so it could not have been passed at all. - cmd/gateway/config.go: new api_key_hmac_secret YAML field - namespace/systemd_spawner.go: read the same secret file at spawn and emit it; a missing or blank secret now fails the spawn loudly rather than booting a gateway that cannot authenticate anything - config file mode pinned to 0600 by test (it already was) Also reverts the API-key lookup change from 0.122.97. That change pointed namespace gateways at their own RQLite, which split the system into two disagreeing key registries and caused the internal 401s above. apiKeyDB() now resolves authClient (global) -> client, never sqlDB. GlobalRQLiteDSN's "API key validation" comment was correct: keys live in the core registry. Verified on devnet 0.122.99 across both gateways and all nodes: external 200, internal namespace gateway 200, bogus 401. Full suite green. Co-Authored-By: Claude <noreply@anthropic.com>
42 lines
1.7 KiB
Go
42 lines
1.7 KiB
Go
package gateway
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/DeBrosOfficial/network/pkg/client"
|
|
)
|
|
|
|
// apiKeyQuerier is the minimal query capability API-key lookups need.
|
|
//
|
|
// API keys are authoritatively stored in the GLOBAL/CORE RQLite registry,
|
|
// HMAC-hashed (docs/SECURITY.md:54-59). `orama namespace keys create` and
|
|
// POST /v1/namespace/keys write there, and ONLY there. A namespace gateway's
|
|
// own RQLite (g.sqlDB) may hold a stale, unrelated api_keys table -- it is
|
|
// never authoritative and must never be queried for key validation. Every
|
|
// gateway, main or namespace, must resolve keys against the same global
|
|
// registry so the external (main gateway) and internal (namespace gateway,
|
|
// e.g. WASM http_fetch) validation paths agree.
|
|
type apiKeyQuerier interface {
|
|
Query(ctx context.Context, sql string, args ...interface{}) (*client.QueryResult, error)
|
|
}
|
|
|
|
// apiKeyDB returns the querier API-key lookups should use: the explicit
|
|
// global-registry client (g.authClient, built from cfg.GlobalRQLiteDSN -- see
|
|
// New in gateway.go) when available, falling back to g.client (core-bound on
|
|
// namespace gateways, since client.DefaultClientConfig() resolves to the core
|
|
// bootstrap peers) only when no dedicated global client was configured.
|
|
// g.sqlDB (this gateway's own namespace RQLite) must NEVER be used here --
|
|
// its api_keys table is not authoritative, and querying it split key
|
|
// validation into two disagreeing registries (bugboard #151/#152
|
|
// regression). Returns nil when neither is available; callers must surface
|
|
// an error rather than silently treating every key as invalid.
|
|
func (g *Gateway) apiKeyDB() apiKeyQuerier {
|
|
if g.authClient != nil {
|
|
return g.authClient.Database()
|
|
}
|
|
if g.client != nil {
|
|
return g.client.Database()
|
|
}
|
|
return nil
|
|
}
|