feat(resolvemcp): require authentication on MCP endpoints and enforce model rules on writes

Guard() rejects unauthenticated callers (no guest/optional mode); Setup*/New* helpers take a
SecurityList and have explicit *Unauthenticated variants. Model rules now reach the security
hooks, create checks CanCreate (security.CheckModelCreateAllowed), create/update validate keys
against the model's writable columns, update sets only given keys (NULL allowed), update and
delete go through row security via a new BeforeScan hook, and the annotation tool is opt-in
(Config.EnableAnnotations) and runs BeforeHandle.
This commit is contained in:
Hein
2026-10-01 13:31:13 +02:00
parent 7662d5055c
commit ad2f54693f
13 changed files with 643 additions and 104 deletions
+21 -1
View File
@@ -1,6 +1,11 @@
package resolvemcp
import "context"
import (
"context"
"github.com/bitechdev/ResolveSpec/pkg/modelregistry"
"github.com/bitechdev/ResolveSpec/pkg/security"
)
type contextKey string
@@ -69,3 +74,18 @@ func withRequestData(ctx context.Context, schema, entity, tableName string, mode
ctx = WithModelPtr(ctx, modelPtr)
return ctx
}
// withModelRules puts the handler registry's rules for the model into the context, where the
// security hooks look them up first. The handler registry is private, so without this the
// hooks would not see rules set by RegisterModelWithRules / SetModelRules.
func (h *Handler) withModelRules(ctx context.Context, schema, entity string) context.Context {
reg, ok := h.registry.(*modelregistry.DefaultModelRegistry)
if !ok {
return ctx
}
rules, err := reg.GetModelRules(buildModelName(schema, entity))
if err != nil {
return ctx
}
return context.WithValue(ctx, security.ModelRulesKey, rules)
}