class LittleGhost::Network::EnvoyGateway
Manages Envoy as a native process or pinned Docker sidecar for one Sandbox. CONNECT policy sees destinations, not encrypted request details. Optional HTTP inspection changes the child trust configuration and may not work for clients with certificate pinning or custom trust stores. The Sandbox must block direct sockets for either mode to be an enforcement boundary.
Attributes
Internal Docker network exposed only to sandbox clients, when used.
Host path of the explicit proxy’s Unix socket, when used.
Configured runtime selector: :auto, :native, or :docker.
Public Class Methods
# File lib/little_ghost/network/envoy_gateway.rb, line 27 def initialize(policy:, runtime: :auto, transport: :unix, envoy: "envoy", docker: "docker", image: ENVOY_IMAGE, pull: :if_missing, dns: []) super(policy:) @runtime = runtime.to_sym @transport = transport.to_sym raise PolicyError, "Envoy runtime must be :auto, :native, or :docker" unless RUNTIMES.include?(@runtime) raise PolicyError, "Envoy transport must be :unix or :docker" unless TRANSPORTS.include?(@transport) @envoy = String(envoy) @docker = String(docker) @image = String(image) @pull = pull.to_sym raise PolicyError, "Envoy image must be a non-option image reference" if @image.empty? || @image.start_with?("-") raise PolicyError, "Envoy pull must be :if_missing, :never, or :always" unless %i[if_missing never always].include?(@pull) @dns = Array(dns).map do |address| address = String(address) IPAddr.new(address) address.freeze rescue IPAddr::InvalidAddressError raise PolicyError, "Envoy DNS resolvers must be IP addresses" end.freeze @gateway_id = SecureRandom.uuid @opened = false end
Builds a run-scoped Envoy gateway. Envoy remains an optional external dependency and the Docker image is pinned by digest by default.
LittleGhost::Network::Gateway::new
Public Instance Methods
Source
# File lib/little_ghost/network/envoy_gateway.rb, line 92 def close stop_native stop_docker @authorizer_server&.close FileUtils.remove_entry_secure(@root) if @root && File.exist?(@root) @root = nil @opened = false nil end
Removes the process, containers, networks, sockets, and trust material.
Source
# File lib/little_ghost/network/envoy_gateway.rb, line 103 def environment endpoint = if @transport == :docker "http://#{@container_name}:3128" else "http://127.0.0.1:3128" end values = { "HTTP_PROXY" => endpoint, "HTTPS_PROXY" => endpoint, "http_proxy" => endpoint, "https_proxy" => endpoint, "NO_PROXY" => "localhost,127.0.0.1", "no_proxy" => "localhost,127.0.0.1" } values.merge!(trust_environment) if @trust_paths values.freeze end
Returns proxy variables and, for inspection, child-scoped trust paths.
Source
# File lib/little_ghost/network/envoy_gateway.rb, line 122 def mounts return [] unless @transport == :unix || @trust_paths [{source: @client_root, target: "/run/little-ghost-egress", access: :read_only}].freeze end
Returns the gateway files that must be mounted into the sandbox.
Source
# File lib/little_ghost/network/envoy_gateway.rb, line 61 def open(run: nil) return self if @opened @root = Dir.mktmpdir("little-ghost-egress-", "/tmp") File.chmod(0o700, @root) @client_root = File.join(@root, "client") Dir.mkdir(@client_root, 0o700) @proxy_socket = File.join(@client_root, "proxy.sock") if @transport == :unix @interceptor_socket = File.join(@root, "interceptor.sock") @authorizer_socket = File.join(@root, "authorizer.sock") @access_log = File.join(@root, "access.log") @envoy_log = File.join(@root, "envoy.log") File.write(@access_log, "") File.chmod(0o600, @access_log) @resolved_runtime = resolve_runtime validate_runtime! prepare_http_inspection(run) @config_path = File.join(@root, "envoy.json") File.open(@config_path, File::WRONLY | File::CREAT | File::EXCL, 0o600) do |file| file.write("#{JSON.pretty_generate(configuration)}\n") end (@resolved_runtime == :native) ? start_native : start_docker wait_until_ready! @opened = true self rescue close raise end
Creates configuration, trust material, and the Envoy process.
Source
# File lib/little_ghost/network/envoy_gateway.rb, line 129 def proxy_mount_path = "/run/little-ghost-egress/proxy.sock"
Returns the proxy socket’s stable path inside a mounted sandbox.