Class: LittleGhost::Sandbox::Policy
- Inherits:
-
Object
- Object
- LittleGhost::Sandbox::Policy
- Defined in:
- lib/little_ghost/sandbox/policy.rb
Overview
Normalizes requested filesystem, process, environment, and child-network controls into one immutable policy. Policy is a declaration, not proof of isolation; the selected backend exposes #effective_policy and rejects controls it cannot enforce.
Constant Summary collapse
- COMMON_KEYS =
%i[ files runtime_paths root_filesystem environment network ].freeze
- ACCESS_MODES =
:nodoc:
%i[read_only read_write].freeze
- ROOT_FILESYSTEM_MODES =
:nodoc:
%i[isolated read_only read_write].freeze
Instance Attribute Summary collapse
-
#environment ⇒ Object
readonly
Environment inheritance and explicit values.
-
#files ⇒ Object
readonly
Named Workspace paths visible to tools and child processes.
-
#network ⇒ Object
readonly
Network policy, or
nilfor a backend-specific secure default. -
#root_filesystem ⇒ Object
readonly
Requested host-root access:
:isolated,:read_only, or:read_write. -
#runtime_paths ⇒ Object
readonly
Named workspace paths visible only to sandboxed processes.
Class Method Summary collapse
-
.coerce(value = nil, **options) ⇒ Object
Returns an existing policy or builds one from a Hash and keyword options.
Instance Method Summary collapse
-
#initialize(files: {root: :read_only}, runtime_paths: {}, root_filesystem: :isolated, environment: {}, network: nil) ⇒ Policy
constructor
Builds a backend-independent policy from named Workspace paths.
-
#process_grants(workspace) ⇒ Object
Builds internal identity grants for a concrete Workspace.
-
#workspace_writable? ⇒ Boolean
Whether the
:rootentry infilesrequests:read_writeaccess.
Constructor Details
#initialize(files: {root: :read_only}, runtime_paths: {}, root_filesystem: :isolated, environment: {}, network: nil) ⇒ Policy
Builds a backend-independent policy from named Workspace paths.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/little_ghost/sandbox/policy.rb', line 25 def initialize( files: {root: :read_only}, runtime_paths: {}, root_filesystem: :isolated, environment: {}, network: nil ) @files = normalize_paths(files, "files") @runtime_paths = normalize_paths(runtime_paths, "runtime_paths") @root_filesystem = enum!(root_filesystem, ROOT_FILESYSTEM_MODES, "root filesystem") @environment = EnvironmentPolicy.coerce(environment) @network = NetworkPolicy.coerce(network) freeze end |
Instance Attribute Details
#environment ⇒ Object (readonly)
Environment inheritance and explicit values.
47 48 49 |
# File 'lib/little_ghost/sandbox/policy.rb', line 47 def environment @environment end |
#files ⇒ Object (readonly)
Named Workspace paths visible to tools and child processes.
41 42 43 |
# File 'lib/little_ghost/sandbox/policy.rb', line 41 def files @files end |
#network ⇒ Object (readonly)
Network policy, or nil for a backend-specific secure default.
49 50 51 |
# File 'lib/little_ghost/sandbox/policy.rb', line 49 def network @network end |
#root_filesystem ⇒ Object (readonly)
Requested host-root access: :isolated, :read_only, or :read_write.
45 46 47 |
# File 'lib/little_ghost/sandbox/policy.rb', line 45 def root_filesystem @root_filesystem end |
#runtime_paths ⇒ Object (readonly)
Named workspace paths visible only to sandboxed processes.
43 44 45 |
# File 'lib/little_ghost/sandbox/policy.rb', line 43 def runtime_paths @runtime_paths end |
Class Method Details
.coerce(value = nil, **options) ⇒ Object
Returns an existing policy or builds one from a Hash and keyword options.
16 17 18 19 20 21 22 |
# File 'lib/little_ghost/sandbox/policy.rb', line 16 def self.coerce(value = nil, **) return value if value.is_a?(self) && .empty? values = value.nil? ? {} : value raise PolicyError, "sandbox policy must be a Hash or Sandbox::Policy" unless values.is_a?(Hash) new(**values.transform_keys(&:to_sym).merge()) end |
Instance Method Details
#process_grants(workspace) ⇒ Object
Builds internal identity grants for a concrete Workspace.
54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/little_ghost/sandbox/policy.rb', line 54 def process_grants(workspace) # :nodoc: file_mounts = files.map do |name, access| source = workspace_directory(workspace, name) Mount.new(source:, target: source, access:, protect_aliases: true) end process_mounts = runtime_paths.map do |name, access| source = workspace_directory(workspace, name) Mount.new(source:, target: source, access:, protect_aliases: true, tools: false) end (file_mounts + process_mounts).sort_by { |mount| -mount.target.length }.freeze end |
#workspace_writable? ⇒ Boolean
Whether the :root entry in files requests :read_write access.
51 |
# File 'lib/little_ghost/sandbox/policy.rb', line 51 def workspace_writable? = files.fetch(:root, :read_only) == :read_write |