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 reports the policy it actually enforces and rejects controls it cannot enforce.
When environment is omitted, child processes receive a scrubbed locale
and path baseline without inheriting other host values. An explicit Hash
or EnvironmentPolicy replaces that baseline, including an empty Hash.
Workspace routing values are added separately when a process starts.
policy = LittleGhost::Sandbox::Policy.new(
files: {root: :read_write},
network: :none
)
policy.root_filesystem # => :isolated
policy.environment.inherit? # => false
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
- DEFAULT_ENVIRONMENT =
:nodoc:
Object.new.freeze
Instance Attribute Summary collapse
-
#environment ⇒ Object
readonly
Environment inheritance and values requested for child processes.
-
#files ⇒ Object
readonly
Named Workspace paths visible to tools and child processes.
-
#network ⇒ Object
readonly
Network policy, or
nilfor the backend-specific 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: DEFAULT_ENVIRONMENT, network: nil) ⇒ Policy
constructor
:call-seq: new(files: :read_only, runtime_paths: {}, root_filesystem: :isolated, network: nil) new(files: :read_only, runtime_paths: {}, root_filesystem: :isolated, environment: value, network: nil).
-
#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: DEFAULT_ENVIRONMENT, network: nil) ⇒ Policy
:call-seq:
new(files: {root: :read_only}, runtime_paths: {}, root_filesystem: :isolated, network: nil)
new(files: {root: :read_only}, runtime_paths: {}, root_filesystem: :isolated, environment: value, network: nil)
Builds a backend-independent policy from named Workspace paths.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/little_ghost/sandbox/policy.rb', line 43 def initialize( files: {root: :read_only}, runtime_paths: {}, root_filesystem: :isolated, environment: DEFAULT_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 = if environment.equal?(DEFAULT_ENVIRONMENT) EnvironmentPolicy.default else EnvironmentPolicy.coerce(environment) end @network = NetworkPolicy.coerce(network) freeze end |
Instance Attribute Details
#environment ⇒ Object (readonly)
Environment inheritance and values requested for child processes.
69 70 71 |
# File 'lib/little_ghost/sandbox/policy.rb', line 69 def environment @environment end |
#files ⇒ Object (readonly)
Named Workspace paths visible to tools and child processes.
63 64 65 |
# File 'lib/little_ghost/sandbox/policy.rb', line 63 def files @files end |
#network ⇒ Object (readonly)
Network policy, or nil for the backend-specific default.
71 72 73 |
# File 'lib/little_ghost/sandbox/policy.rb', line 71 def network @network end |
#root_filesystem ⇒ Object (readonly)
Requested host-root access: :isolated, :read_only, or :read_write.
67 68 69 |
# File 'lib/little_ghost/sandbox/policy.rb', line 67 def root_filesystem @root_filesystem end |
#runtime_paths ⇒ Object (readonly)
Named workspace paths visible only to sandboxed processes.
65 66 67 |
# File 'lib/little_ghost/sandbox/policy.rb', line 65 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.
30 31 32 33 34 35 36 |
# File 'lib/little_ghost/sandbox/policy.rb', line 30 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.
76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/little_ghost/sandbox/policy.rb', line 76 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.
73 |
# File 'lib/little_ghost/sandbox/policy.rb', line 73 def workspace_writable? = files.fetch(:root, :read_only) == :read_write |