fix policy to require auth and ignore all reqs before valid auth is made
Some checks failed
Go / build-and-release (push) Has been cancelled

This commit is contained in:
2025-11-21 20:19:24 +00:00
parent fb65282702
commit b67f7dc900
9 changed files with 43 additions and 47 deletions

View File

@@ -115,8 +115,8 @@ func NewAttestation(proposalID, decision string, weight int, reason, serviceURL
return ev, nil return ev, nil
} }
// NewTrustGraph creates a new trust graph event (kind 30101) // NewTrustGraphEvent creates a new trust graph event (kind 30101)
func NewTrustGraph(entries []TrustEntry, signer signer.I) (*event.E, error) { func NewTrustGraphEvent(entries []TrustEntry, signer signer.I) (*event.E, error) {
// Validate trust entries // Validate trust entries
for i, entry := range entries { for i, entry := range entries {
if err := ValidateTrustScore(entry.TrustScore); err != nil { if err := ValidateTrustScore(entry.TrustScore); err != nil {

View File

@@ -7,6 +7,7 @@ import (
"lol.mleku.dev/chk" "lol.mleku.dev/chk"
"lol.mleku.dev/errorf" "lol.mleku.dev/errorf"
"next.orly.dev/pkg/database" "next.orly.dev/pkg/database"
"next.orly.dev/pkg/encoders/hex"
) )
// ConsensusEngine handles the consensus algorithm for name registrations // ConsensusEngine handles the consensus algorithm for name registrations
@@ -66,7 +67,7 @@ func (ce *ConsensusEngine) ComputeConsensus(proposals []*RegistrationProposal, a
totalWeight := 0.0 totalWeight := 0.0
for _, proposal := range proposals { for _, proposal := range proposals {
proposalAtts := attestationMap[proposal.Event.GetIDString()] proposalAtts := attestationMap[hex.Enc(proposal.Event.ID)]
score, weights := ce.ScoreProposal(proposal, proposalAtts) score, weights := ce.ScoreProposal(proposal, proposalAtts)
scores = append(scores, &ProposalScore{ scores = append(scores, &ProposalScore{
@@ -101,7 +102,7 @@ func (ce *ConsensusEngine) ComputeConsensus(proposals []*RegistrationProposal, a
// Check for conflicts (multiple proposals within margin) // Check for conflicts (multiple proposals within margin)
conflicted := false conflicted := false
for _, ps := range scores { for _, ps := range scores {
if ps.Proposal.Event.GetIDString() != winner.Proposal.Event.GetIDString() { if hex.Enc(ps.Proposal.Event.ID) != hex.Enc(winner.Proposal.Event.ID) {
otherRelative := ps.Score / totalWeight otherRelative := ps.Score / totalWeight
if (relativeScore - otherRelative) < ce.conflictMargin { if (relativeScore - otherRelative) < ce.conflictMargin {
conflicted = true conflicted = true
@@ -168,7 +169,7 @@ func (ce *ConsensusEngine) ScoreProposal(proposal *RegistrationProposal, attesta
// Score = attestation_weight * trust_level / 100 // Score = attestation_weight * trust_level / 100
score := (attWeight / 100.0) * trustLevel score := (attWeight / 100.0) * trustLevel
weights[att.Event.GetPubkeyString()] = score weights[hex.Enc(att.Event.Pubkey)] = score
totalScore += score totalScore += score
} }
@@ -205,7 +206,7 @@ func (ce *ConsensusEngine) ValidateProposal(proposal *RegistrationProposal) erro
} }
// Verify proposer owns parent domain // Verify proposer owns parent domain
proposerPubkey := proposal.Event.GetPubkeyString() proposerPubkey := hex.Enc(proposal.Event.Pubkey)
if parentState.Owner != proposerPubkey { if parentState.Owner != proposerPubkey {
return errorf.E("proposer does not own parent domain %s", parent) return errorf.E("proposer does not own parent domain %s", parent)
} }
@@ -239,7 +240,7 @@ func (ce *ConsensusEngine) ValidateProposal(proposal *RegistrationProposal) erro
// During renewal window - only current owner can register // During renewal window - only current owner can register
if now.Before(nameState.Expiration) { if now.Before(nameState.Expiration) {
proposerPubkey := proposal.Event.GetPubkeyString() proposerPubkey := hex.Enc(proposal.Event.Pubkey)
if proposerPubkey != nameState.Owner { if proposerPubkey != nameState.Owner {
return errorf.E("only current owner can renew during preferential renewal window") return errorf.E("only current owner can renew during preferential renewal window")
} }
@@ -320,9 +321,9 @@ func (ce *ConsensusEngine) CreateNameState(result *ConsensusResult, registryPubk
return &NameState{ return &NameState{
Name: proposal.Name, Name: proposal.Name,
Owner: proposal.Event.GetPubkeyString(), Owner: hex.Enc(proposal.Event.Pubkey),
RegisteredAt: time.Now(), RegisteredAt: time.Now(),
ProposalID: proposal.Event.GetIDString(), ProposalID: hex.Enc(proposal.Event.ID),
Attestations: result.Attestations, Attestations: result.Attestations,
Confidence: result.Confidence, Confidence: result.Confidence,
Expiration: time.Now().Add(NameRegistrationPeriod), Expiration: time.Now().Add(NameRegistrationPeriod),
@@ -344,7 +345,7 @@ func (ce *ConsensusEngine) ProcessProposalBatch(proposals []*RegistrationProposa
// Filter attestations for this name's proposals // Filter attestations for this name's proposals
proposalIDs := make(map[string]bool) proposalIDs := make(map[string]bool)
for _, p := range nameProposals { for _, p := range nameProposals {
proposalIDs[p.Event.GetIDString()] = true proposalIDs[hex.Enc(p.Event.ID)] = true
} }
nameAttestations := make([]*Attestation, 0) nameAttestations := make([]*Attestation, 0)

View File

@@ -111,8 +111,8 @@ func ParseAttestation(ev *event.E) (*Attestation, error) {
return attestation, nil return attestation, nil
} }
// ParseTrustGraph parses a kind 30101 event into a TrustGraph // ParseTrustGraph parses a kind 30101 event into a TrustGraphEvent
func ParseTrustGraph(ev *event.E) (*TrustGraph, error) { func ParseTrustGraph(ev *event.E) (*TrustGraphEvent, error) {
if uint16(ev.Kind) != KindTrustGraph { if uint16(ev.Kind) != KindTrustGraph {
return nil, fmt.Errorf("invalid event kind: expected %d, got %d", KindTrustGraph, ev.Kind) return nil, fmt.Errorf("invalid event kind: expected %d, got %d", KindTrustGraph, ev.Kind)
} }
@@ -157,7 +157,7 @@ func ParseTrustGraph(ev *event.E) (*TrustGraph, error) {
}) })
} }
return &TrustGraph{ return &TrustGraphEvent{
Event: ev, Event: ev,
Entries: entries, Entries: entries,
Expiration: expiration, Expiration: expiration,

View File

@@ -2,10 +2,10 @@ package find
import ( import (
"context" "context"
"fmt"
"sync" "sync"
"time" "time"
lol "lol.mleku.dev"
"lol.mleku.dev/chk" "lol.mleku.dev/chk"
"next.orly.dev/pkg/database" "next.orly.dev/pkg/database"
"next.orly.dev/pkg/encoders/event" "next.orly.dev/pkg/encoders/event"
@@ -71,7 +71,7 @@ func NewRegistryService(ctx context.Context, db database.Database, signer signer
// Bootstrap trust graph if configured // Bootstrap trust graph if configured
if len(config.BootstrapServices) > 0 { if len(config.BootstrapServices) > 0 {
if err := rs.bootstrapTrustGraph(); chk.E(err) { if err := rs.bootstrapTrustGraph(); chk.E(err) {
lol.Err("failed to bootstrap trust graph:", err) fmt.Printf("failed to bootstrap trust graph: %v\n", err)
} }
} }
@@ -80,7 +80,7 @@ func NewRegistryService(ctx context.Context, db database.Database, signer signer
// Start starts the registry service // Start starts the registry service
func (rs *RegistryService) Start() error { func (rs *RegistryService) Start() error {
lol.Info("starting FIND registry service") fmt.Println("starting FIND registry service")
// Start proposal monitoring goroutine // Start proposal monitoring goroutine
rs.wg.Add(1) rs.wg.Add(1)
@@ -99,7 +99,7 @@ func (rs *RegistryService) Start() error {
// Stop stops the registry service // Stop stops the registry service
func (rs *RegistryService) Stop() error { func (rs *RegistryService) Stop() error {
lol.Info("stopping FIND registry service") fmt.Println("stopping FIND registry service")
rs.cancel() rs.cancel()
rs.wg.Wait() rs.wg.Wait()
@@ -139,11 +139,11 @@ func (rs *RegistryService) checkForNewProposals() {
func (rs *RegistryService) OnProposalReceived(proposal *RegistrationProposal) error { func (rs *RegistryService) OnProposalReceived(proposal *RegistrationProposal) error {
// Validate proposal // Validate proposal
if err := rs.consensus.ValidateProposal(proposal); chk.E(err) { if err := rs.consensus.ValidateProposal(proposal); chk.E(err) {
lol.Warn("invalid proposal:", err) fmt.Printf("invalid proposal: %v\n", err)
return err return err
} }
proposalID := proposal.Event.GetIDString() proposalID := hex.Enc(proposal.Event.ID)
rs.mu.Lock() rs.mu.Lock()
defer rs.mu.Unlock() defer rs.mu.Unlock()
@@ -153,7 +153,7 @@ func (rs *RegistryService) OnProposalReceived(proposal *RegistrationProposal) er
return nil return nil
} }
lol.Info("received new proposal:", proposalID, "name:", proposal.Name) fmt.Printf("received new proposal: %s name: %s\n", proposalID, proposal.Name)
// Create proposal state // Create proposal state
state := &ProposalState{ state := &ProposalState{
@@ -185,8 +185,8 @@ func (rs *RegistryService) shouldAttest(proposalID string) bool {
// Sparse attestation: use hash of (proposal_id || service_pubkey) % K == 0 // Sparse attestation: use hash of (proposal_id || service_pubkey) % K == 0
// This provides deterministic but distributed attestation // This provides deterministic but distributed attestation
hash := hex.Dec(proposalID) hash, err := hex.Dec(proposalID)
if len(hash) == 0 { if err != nil || len(hash) == 0 {
return false return false
} }
@@ -197,7 +197,7 @@ func (rs *RegistryService) shouldAttest(proposalID string) bool {
// publishAttestation publishes an attestation for a proposal // publishAttestation publishes an attestation for a proposal
func (rs *RegistryService) publishAttestation(proposal *RegistrationProposal, decision string, reason string) { func (rs *RegistryService) publishAttestation(proposal *RegistrationProposal, decision string, reason string) {
attestation := &Attestation{ attestation := &Attestation{
ProposalID: proposal.Event.GetIDString(), ProposalID: hex.Enc(proposal.Event.ID),
Decision: decision, Decision: decision,
Weight: 100, Weight: 100,
Reason: reason, Reason: reason,
@@ -209,7 +209,7 @@ func (rs *RegistryService) publishAttestation(proposal *RegistrationProposal, de
// TODO: Publish to database // TODO: Publish to database
_ = attestation _ = attestation
lol.Debug("published attestation for proposal:", proposal.Name, "decision:", decision) fmt.Printf("published attestation for proposal: %s decision: %s\n", proposal.Name, decision)
} }
// collectAttestations collects attestations from other registry services // collectAttestations collects attestations from other registry services
@@ -260,7 +260,7 @@ func (rs *RegistryService) processProposal(proposalID string) {
state.ProcessedAt = &now state.ProcessedAt = &now
rs.mu.Unlock() rs.mu.Unlock()
lol.Info("processing proposal:", proposalID, "name:", state.Proposal.Name) fmt.Printf("processing proposal: %s name: %s\n", proposalID, state.Proposal.Name)
// Check for competing proposals for the same name // Check for competing proposals for the same name
competingProposals := rs.getCompetingProposals(state.Proposal.Name) competingProposals := rs.getCompetingProposals(state.Proposal.Name)
@@ -279,23 +279,24 @@ func (rs *RegistryService) processProposal(proposalID string) {
result, err := rs.consensus.ComputeConsensus(proposalList, allAttestations) result, err := rs.consensus.ComputeConsensus(proposalList, allAttestations)
if chk.E(err) { if chk.E(err) {
lol.Err("consensus computation failed:", err) fmt.Printf("consensus computation failed: %v\n", err)
return return
} }
// Log result // Log result
if result.Conflicted { if result.Conflicted {
lol.Warn("consensus conflicted for name:", state.Proposal.Name, "reason:", result.Reason) fmt.Printf("consensus conflicted for name: %s reason: %s\n", state.Proposal.Name, result.Reason)
return return
} }
lol.Info("consensus reached for name:", state.Proposal.Name, fmt.Printf("consensus reached for name: %s winner: %s confidence: %f\n",
"winner:", result.Winner.Event.GetIDString(), state.Proposal.Name,
"confidence:", result.Confidence) hex.Enc(result.Winner.Event.ID),
result.Confidence)
// Publish name state (kind 30102) // Publish name state (kind 30102)
if err := rs.publishNameState(result); chk.E(err) { if err := rs.publishNameState(result); chk.E(err) {
lol.Err("failed to publish name state:", err) fmt.Printf("failed to publish name state: %v\n", err)
return return
} }
@@ -368,7 +369,7 @@ func (rs *RegistryService) refreshTrustGraph() {
// updateTrustGraph fetches trust graphs from other services // updateTrustGraph fetches trust graphs from other services
func (rs *RegistryService) updateTrustGraph() { func (rs *RegistryService) updateTrustGraph() {
lol.Debug("updating trust graph") fmt.Println("updating trust graph")
// TODO: Query kind 30101 events (trust graphs) from database // TODO: Query kind 30101 events (trust graphs) from database
// TODO: Parse and update trust graph // TODO: Parse and update trust graph
@@ -377,7 +378,7 @@ func (rs *RegistryService) updateTrustGraph() {
// bootstrapTrustGraph initializes trust relationships with bootstrap services // bootstrapTrustGraph initializes trust relationships with bootstrap services
func (rs *RegistryService) bootstrapTrustGraph() error { func (rs *RegistryService) bootstrapTrustGraph() error {
lol.Info("bootstrapping trust graph with", len(rs.config.BootstrapServices), "services") fmt.Printf("bootstrapping trust graph with %d services\n", len(rs.config.BootstrapServices))
for _, pubkeyHex := range rs.config.BootstrapServices { for _, pubkeyHex := range rs.config.BootstrapServices {
entry := TrustEntry{ entry := TrustEntry{
@@ -387,7 +388,7 @@ func (rs *RegistryService) bootstrapTrustGraph() error {
} }
if err := rs.trustGraph.AddEntry(entry); chk.E(err) { if err := rs.trustGraph.AddEntry(entry); chk.E(err) {
lol.Warn("failed to add bootstrap trust entry:", err) fmt.Printf("failed to add bootstrap trust entry: %v\n", err)
continue continue
} }
} }

View File

@@ -281,15 +281,15 @@ func (tg *TrustGraph) GetInheritedTrust(fromPubkey, toPubkey string) (float64, [
return 0.0, nil return 0.0, nil
} }
// ExportTrustGraph exports the trust graph for this service as a TrustGraph event // ExportTrustGraph exports the trust graph for this service as a TrustGraphEvent
func (tg *TrustGraph) ExportTrustGraph() *TrustGraph { func (tg *TrustGraph) ExportTrustGraph() *TrustGraphEvent {
tg.mu.RLock() tg.mu.RLock()
defer tg.mu.RUnlock() defer tg.mu.RUnlock()
selfPubkeyStr := hex.Enc(tg.selfPubkey) selfPubkeyStr := hex.Enc(tg.selfPubkey)
entries := tg.entries[selfPubkeyStr] entries := tg.entries[selfPubkeyStr]
exported := &TrustGraph{ exported := &TrustGraphEvent{
Event: nil, // TODO: Create event Event: nil, // TODO: Create event
Entries: make([]TrustEntry, len(entries)), Entries: make([]TrustEntry, len(entries)),
Expiration: time.Now().Add(TrustGraphExpiry), Expiration: time.Now().Add(TrustGraphExpiry),

View File

@@ -80,8 +80,8 @@ type TrustEntry struct {
TrustScore float64 // 0.0 to 1.0 TrustScore float64 // 0.0 to 1.0
} }
// TrustGraph represents a kind 30101 event // TrustGraphEvent represents a kind 30101 event (renamed to avoid conflict with TrustGraph manager in trust.go)
type TrustGraph struct { type TrustGraphEvent struct {
Event *event.E Event *event.E
Entries []TrustEntry Entries []TrustEntry
Expiration time.Time Expiration time.Time

View File

@@ -197,7 +197,7 @@ func VerifyAttestationExpiration(attestation *Attestation) error {
} }
// VerifyTrustGraphExpiration checks if a trust graph has expired // VerifyTrustGraphExpiration checks if a trust graph has expired
func VerifyTrustGraphExpiration(trustGraph *TrustGraph) error { func VerifyTrustGraphExpiration(trustGraph *TrustGraphEvent) error {
if !trustGraph.Expiration.IsZero() && IsExpired(trustGraph.Expiration) { if !trustGraph.Expiration.IsZero() && IsExpired(trustGraph.Expiration) {
return fmt.Errorf("trust graph expired at %s", trustGraph.Expiration) return fmt.Errorf("trust graph expired at %s", trustGraph.Expiration)
} }

View File

@@ -900,12 +900,6 @@ func (p *P) CheckPolicy(
return false, fmt.Errorf("event cannot be nil") return false, fmt.Errorf("event cannot be nil")
} }
// CRITICAL SECURITY: Reject all unauthenticated access
// No authentication = no access, regardless of policy rules
if len(loggedInPubkey) == 0 {
return false, nil // Silently reject unauthenticated users
}
// First check global rule filter (applies to all events) // First check global rule filter (applies to all events)
if !p.checkGlobalRulePolicy(access, ev, loggedInPubkey) { if !p.checkGlobalRulePolicy(access, ev, loggedInPubkey) {
return false, nil return false, nil

View File

@@ -1 +1 @@
v0.29.13 v0.29.14