You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
Allow-list query functions on the server (#1058)
* Allow-list query functions on the server
Query functions, predicates, aggregates and attribute/entity predicates
resolved through clojure.core/resolve and reflection, so any client of
the HTTP API or the Kabel listener could run load-string in the server.
New leaf namespace datahike.query.resolve owns symbol resolution:
*symbol-resolver* stays permissive embedded, the server and
routes/handler set the safe resolver (curated clojure.core subset,
clojure.string, registry) process-wide and restore it on stop;
register-fn! / register-ns! expose application functions to clients.
Entity predicates go through the registry, unresolved aggregates are a
typed error, datahike.api/q is a nested-query built-in.
Also carries src-kabel on the :http-server alias, which has failed to
start the standalone server (and the native-image CBOR leg) since the
Kabel listener landed, and a kaocha hook so a handler a test never
releases does not decide the next namespace's resolution.
Claude-Session: https://claude.ai/code/session_01J9RUNkHFidHP8EvQVCSqf3
* Bind the safe resolver per request instead of mutating the root
The server no longer alter-var-roots the query function resolver.
routes/handler binds it around every request and the Kabel listener
around every client dispatch (register-global-handlers! :wrap-handler);
the local writer captures the caller's thread bindings at dispatch and
applies them on the writer thread, so entity and attribute predicates
see the same resolver. Plan and result caches are keyed by resolver.
datahike.api installs its read-only functions (q for subqueries, pull,
pull-many, entity, datoms, seek-datoms, index-range) as functions every
resolver knows. The kaocha hook is gone with the root mutation.
Claude-Session: https://claude.ai/code/session_01J9RUNkHFidHP8EvQVCSqf3
* Close the review findings on the safe resolver
The curated functions refuse a database, connection or reference as
argument: on the server `$` is the live DB record, so `(get $ :config)`
handed a read-only client the store configuration. The planner's
external-engine metadata hooks and the secondary-index solver resolve a
symbol only when the current resolver admits it. The permissive resolver
falls back to every bare clojure.core symbol except eval, as before, so
embedded queries using bit-and, ffirst and friends keep working. repeat
leaves the curated list; the writer's NPE payload drops the bindings.
Claude-Session: https://claude.ai/code/session_01J9RUNkHFidHP8EvQVCSqf3