Any SWI-Prolog web server can be pengine enabled by loading
library(pengines) and configuring the access rights. Clients can then
create pengines that execute code in the module
default, they can only execute white-listed code as defined by the
library(sandbox), i.e., mostly Prolog code that has no side effects.
Typically, a server serves a particular application. This application
comes with a particular API. A nice and clean example is the RDF library
as realised by library(semweb/rdf_db). If the pengine server wishes to
make this library available to pengines, it must import this library
into the module
pengine_sandbox using the following query:
This declaration allows pengines to use the side effect free RDF query
predicates, in particular rdf/3.
An application that wishes to provide similar functionality should take
the following steps:
- Define a module that exports the desired API. Remember that the
client can easily add predicates that combine API calls and massage
data into a format suitable for the application, so you don't have
to think about these application oriented queries. Instead, make
your queries general and purely declarative!
- Import this library into
pengine_sandbox as illustrated above.
That is all, except that library(sandbox) may not like your code. What
now? There are several reasons and work-arounds.
- The sandbox library does not understand my code
This shows up as instantiation errors and implies that the
sandboxing libraries finds meta-calls but cannot determine what
will be called. There are two remedies:
- Make the source easier to track. Avoid some meta-calling by
passing terms that indicate what should happen and a static
predicate that interprets these terms. This is often a good
idea if the intend is to meta-call to a well defined set of
- Isolate the most deeply nested bit of code that is safe,
regardless how it is called and declare this to be safe
using sandbox:safe_primitive/1 or, if it is a meta-predicate,
- The API calls foreign code
Library(sandbox) cannot prove anything about foreign code. Make sure
it is written properly and declare it using sandbox:safe_primitive/1.
- The API has side effects, but that it what it should do
Make sure that the API correctly validates arguments and really
cannot do anything unintended and declare it using