Module: SecurityBox
- Defined in:
- lib/security_box.rb,
lib/security_box/pool.rb,
lib/security_box/errors.rb,
lib/security_box/result.rb,
lib/security_box/runtime.rb,
lib/security_box/sandbox.rb,
lib/security_box/version.rb,
lib/security_box/envelope.rb,
lib/security_box/eval_run.rb,
lib/security_box/registry.rb,
lib/security_box/guest_rpc.rb,
lib/security_box/ractor_pool.rb,
lib/security_box/module_cache.rb,
lib/security_box/configuration.rb
Defined Under Namespace
Modules: Envelope, EvalRun, GuestRpc, ModuleCache, Mounts, Registry, Rpcs, Runtime Classes: Configuration, Error, ImageMissing, InvalidConfiguration, Pool, PoolClosed, RactorPool, Result, Sandbox
Constant Summary collapse
- VERSION =
"0.6.0"
Class Method Summary collapse
-
.eval(code, **overrides) ⇒ Object
Convenience shortcut: SecurityBox.eval("1 + 1") # => Result SecurityBox.eval("1", fuel: 100) # per-call overrides.
-
.pool(profile = nil, size: 4, **overrides) ⇒ Object
Builds a Pool of :oneshot sandboxes (bounded concurrency on threads).
-
.ractor_pool(profile = nil, size: 4, **overrides) ⇒ Object
Builds a RactorPool (real parallelism: worker Ractors sharing one Engine+Module).
-
.register(name, from: nil, &block) ⇒ Object
Registers a named, reusable profile (see Registry).
-
.spawn(profile = nil, **overrides) ⇒ Object
Builds a Sandbox from a registered profile, a Configuration, or the defaults: SecurityBox.spawn(:lean) # named profile SecurityBox.spawn(:lean, fuel: 1_000) # profile + per-call overrides SecurityBox.spawn(my_config) # explicit configuration SecurityBox.spawn # default configuration.
-
.warmup(**options) ⇒ Object
Prepares the shared runtime artifacts (Engine + compiled Module) ahead of time so the first #eval skips the cold module compilation (~15s per process).
Class Method Details
.eval(code, **overrides) ⇒ Object
Convenience shortcut:
SecurityBox.eval("1 + 1") # => Result
SecurityBox.eval("1", fuel: 100) # per-call overrides
21 22 23 |
# File 'lib/security_box.rb', line 21 def self.eval(code, **overrides) Sandbox.new.eval(code, **overrides) end |
.pool(profile = nil, size: 4, **overrides) ⇒ Object
Builds a Pool of :oneshot sandboxes (bounded concurrency on threads). NOTE: evals serialize on the GVL — see RactorPool for parallelism. SecurityBox.pool(:lean, size: 4).eval("1 + 1")
55 56 57 |
# File 'lib/security_box.rb', line 55 def self.pool(profile = nil, size: 4, **overrides) Pool.new(profile, size: size, **overrides) end |
.ractor_pool(profile = nil, size: 4, **overrides) ⇒ Object
Builds a RactorPool (real parallelism: worker Ractors sharing one Engine+Module). Costs one module deserialize at creation (~0.5s via the disk cache); each eval still pays the guest boot (~240ms). SecurityBox.ractor_pool(:lean, size: 4).eval("1 + 1")
63 64 65 |
# File 'lib/security_box.rb', line 63 def self.ractor_pool(profile = nil, size: 4, **overrides) RactorPool.new(profile, size: size, **overrides) end |
.register(name, from: nil, &block) ⇒ Object
Registers a named, reusable profile (see Registry). SecurityBox.register(:lean, from: :default) { |c| c.fuel 5_000_000 }
27 28 29 |
# File 'lib/security_box.rb', line 27 def self.register(name, from: nil, &block) Registry.register(name, from: from, &block) end |
.spawn(profile = nil, **overrides) ⇒ Object
Builds a Sandbox from a registered profile, a Configuration, or the defaults:
SecurityBox.spawn(:lean) # named profile
SecurityBox.spawn(:lean, fuel: 1_000) # profile + per-call overrides
SecurityBox.spawn(my_config) # explicit configuration
SecurityBox.spawn # default configuration
37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/security_box.rb', line 37 def self.spawn(profile = nil, **overrides) config = case profile when nil then Configuration.build(**overrides) when Symbol, String resolved = Registry.resolve(profile) overrides.empty? ? resolved : resolved.with(**overrides) when Configuration overrides.empty? ? profile : profile.with(**overrides) else raise ArgumentError, "profile must be a registered name or a Configuration, got #{profile.class}" end Sandbox.new(config) end |
.warmup(**options) ⇒ Object
Prepares the shared runtime artifacts (Engine + compiled Module) ahead of time so the first #eval skips the cold module compilation (~15s per process). #eval warms these caches lazily on first use, so calling warmup is a pure optimization: behavior and results are identical without it. Accepts the same options as Configuration.build (only image_path and epoch_interval_ms affect what gets warmed). Returns the warmed Sandbox; safe to call multiple times.
74 75 76 |
# File 'lib/security_box.rb', line 74 def self.warmup(**) Sandbox.new(Configuration.build(**)) end |