[System]
You are a helpful assistant that answers strictly in JSON. Here's the JSON schema you must adhere to:
<schema>
{"$schema":"http://json-schema.org/draft-07/schema#","title":"LayerFileConfig","description":"mirrord allows for a high degree of customization when it comes to which features you want to enable, and how they should function.\n\nAll of the configuration fields have a default value, so a minimal configuration would be no configuration at all.\n\nThe configuration supports templating using the [Tera](https://keats.github.io/tera/docs/) template engine. Currently we don't provide additional values to the context, if you have anything you want us to provide please let us know.\n\nTo use a configuration file in the CLI, use the `-f <CONFIG_PATH>` flag. Or if using VSCode Extension or JetBrains plugin, simply create a `.mirrord/mirrord.json` file or use the UI.\n\nTo help you get started, here are examples of a basic configuration file, and a complete configuration file containing all fields.\n\n### Basic `config.json` {#root-basic}\n\n```json { \"target\": \"pod/bear-pod\", \"feature\": { \"env\": true, \"fs\": \"read\", \"network\": true } } ```\n\n### Basic `config.json` with templating {#root-basic-templating}\n\n```json { \"target\": \"{{ get_env(name=\"TARGET\", default=\"pod/fallback\") }}\", \"feature\": { \"env\": true, \"fs\": \"read\", \"network\": true } } ```\n\n### Complete `config.json` {#root-complete}\n\nDon't use this example as a starting point, it's just here to show you all the available options. ```json { \"accept_invalid_certificates\": false, \"skip_processes\": \"ide-debugger\", \"target\": { \"path\": \"pod/bear-pod\", \"namespace\": \"default\" }, \"connect_tcp\": null, \"agent\": { \"log_level\": \"info\", \"json_log\": false, \"labels\": { \"user\": \"meow\" }, \"annotations\": { \"cats.io/inject\": \"enabled\" }, \"namespace\": \"default\", \"image\": \"ghcr.io/metalbear-co/mirrord:latest\", \"image_pull_policy\": \"IfNotPresent\", \"image_pull_secrets\": [ { \"secret-key\": \"secret\" } ], \"ttl\": 30, \"ephemeral\": false, \"communication_timeout\": 30, \"startup_timeout\": 360, \"network_interface\": \"eth0\", \"flush_connections\": true, \"metrics\": \"0.0.0.0:9000\", }, \"feature\": { \"env\": { \"include\": \"DATABASE_USER;PUBLIC_ENV\", \"exclude\": \"DATABASE_PASSWORD;SECRET_ENV\", \"override\": { \"DATABASE_CONNECTION\": \"db://localhost:7777/my-db\", \"LOCAL_BEAR\": \"panda\" }, \"mapping\": { \".+_TIMEOUT\": \"1000\" } }, \"fs\": { \"mode\": \"write\", \"read_write\": \".+\\\\.json\" , \"read_only\": [ \".+\\\\.yaml\", \".+important-file\\\\.txt\" ], \"local\": [ \".+\\\\.js\", \".+\\\\.mjs\" ] }, \"network\": { \"incoming\": { \"mode\": \"steal\", \"http_filter\": { \"header_filter\": \"host: api\\\\..+\" }, \"port_mapping\": [[ 7777, 8888 ]], \"ignore_localhost\": false, \"ignore_ports\": [9999, 10000] }, \"outgoing\": { \"tcp\": true, \"udp\": true, \"filter\": { \"local\": [\"tcp://1.1.1.0/24:1337\", \"1.1.5.0/24\", \"google.com\", \":53\"] }, \"ignore_localhost\": false, \"unix_streams\": \"bear.+\" }, \"dns\": { \"enabled\": true, \"filter\": { \"local\": [\"1.1.1.0/24:1337\", \"1.1.5.0/24\", \"google.com\"] } } }, \"copy_target\": { \"scale_down\": false } }, \"operator\": true, \"kubeconfig\": \"~/.kube/config\", \"sip_binaries\": \"bash\", \"telemetry\": true, \"kube_context\": \"my-cluster\" } ```\n\n# Options {#root-options}","type":"object","properties":{"accept_invalid_certificates":{"title":"accept_invalid_certificates {#root-accept_invalid_certificates}","description":"Controls whether or not mirrord accepts invalid TLS certificates (e.g. self-signed certificates).\n\nIf not provided, mirrord will use value from the kubeconfig.","type":["boolean","null"]},"agent":{"title":"agent {#root-agent}","anyOf":[{"$ref":"#/definitions/AgentFileConfig"},{"type":"null"}]},"container":{"title":"container {#root-container}","anyOf":[{"$ref":"#/definitions/ContainerFileConfig"},{"type":"null"}]},"experimental":{"title":"experimental {#root-experimental}","anyOf":[{"$ref":"#/definitions/ExperimentalFileConfig"},{"type":"null"}]},"external_proxy":{"title":"external_proxy {#root-external_proxy}","anyOf":[{"$ref":"#/definitions/ExternalProxyFileConfig"},{"type":"null"}]},"feature":{"title":"feature {#root-feature}","anyOf":[{"$ref":"#/definitions/FeatureFileConfig"},{"type":"null"}]},"internal_proxy":{"title":"internal_proxy {#root-internal_proxy}","anyOf":[{"$ref":"#/definitions/InternalProxyFileConfig"},{"type":"null"}]},"kube_context":{"title":"kube_context {#root-kube_context}","description":"Kube context to use from the kubeconfig file. Will use current context if not specified.\n\n```json { \"kube_context\": \"mycluster\" } ```","type":["string","null"]},"kubeconfig":{"title":"kubeconfig {#root-kubeconfig}","description":"Path to a kubeconfig file, if not specified, will use `KUBECONFIG`, or `~/.kube/config`, or the in-cluster config.\n\n```json { \"kubeconfig\": \"~/bear/kube-config\" } ```","type":["string","null"]},"operator":{"title":"operator {#root-operator}","description":"Whether mirrord should use the operator. If not set, mirrord will first attempt to use the operator, but continue without it in case of failure.","type":["boolean","null"]},"profile":{"title":"profile {#root-profile}","description":"Name of the mirrord profile to use.\n\nTo select a cluster-wide profile\n\n```json { \"profile\": \"my-profile-name\" } ```\n\nTo select a namespaced profile\n\n```json { \"profile\": \"my-namespace/my-profile-name\" } ```","type":["string","null"]},"sip_binaries":{"title":"sip_binaries {#root-sip_binaries}","description":"Binaries to patch (macOS SIP).\n\nUse this when mirrord isn't loaded to protected binaries that weren't automatically patched.\n\nRuns `endswith` on the binary path (so `bash` would apply to any binary ending with `bash` while `/usr/bin/bash` would apply only for that binary).\n\n```json { \"sip_binaries\": [\"bash\", \"python\"] } ```","anyOf":[{"$ref":"#/definitions/VecOrSingle_for_String"},{"type":"null"}]},"skip_build_tools":{"title":"skip_build_tools {#root-skip_build_tools}","description":"Allows mirrord to skip build tools. Useful when running command lines that build and run the application in a single command.\n\nDefaults to `true`.\n\nBuild-Tools: `[\"as\", \"cc\", \"ld\", \"go\", \"air\", \"asm\", \"cc1\", \"cgo\", \"dlv\", \"gcc\", \"git\", \"link\", \"math\", \"cargo\", \"hpack\", \"rustc\", \"compile\", \"collect2\", \"cargo-watch\", \"debugserver\"]`","type":["boolean","null"]},"skip_extra_build_tools":{"title":"skip_extra_build_tools {#root-skip_build_tools}","description":"Allows mirrord to skip the specified build tools. Useful when running command lines that build and run the application in a single command.\n\nMust also enable [`skip_build_tools`](#root-skip_build_tools) for this to take an effect.\n\nIt's similar to [`skip_processes`](#root-skip_processes), except that here it also skips SIP patching.\n\nAccepts a single value, or an array of values.\n\n```json { \"skip_extra_build_tools\": [\"bash\", \"node\"] } ```","anyOf":[{"$ref":"#/definitions/VecOrSingle_for_String"},{"type":"null"}]},"skip_processes":{"title":"skip_processes {#root-skip_processes}","description":"Allows mirrord to skip unwanted processes.\n\nUseful when process A spawns process B, and the user wants mirrord to operate only on process B. Accepts a single value, or an array of values.\n\n```json { \"skip_processes\": [\"bash\", \"node\"] } ```","anyOf":[{"$ref":"#/definitions/VecOrSingle_for_String"},{"type":"null"}]},"skip_sip":{"title":"skip_sip {#root-skip_sip}","description":"Allows mirrord to skip patching (macOS SIP) unwanted processes.\n\nWhen patching is skipped, mirrord will no longer be able to load into the process and its child processes.\n\nDefaults to `{ \"skip_sip\": \"git\" }`\n\nWhen specified, the given value will replace the default list rather than being added to.","anyOf":[{"$ref":"#/definitions/VecOrSingle_for_String"},{"type":"null"}]},"target":{"title":"target {#root-target}","anyOf":[{"$ref":"#/definitions/TargetFileConfig"},{"type":"null"}]},"telemetry":{"title":"telemetry {#root-telemetry}","description":"Controls whether or not mirrord sends telemetry data to MetalBear cloud. Telemetry sent doesn't contain personal identifiers or any data that should be considered sensitive. It is used to improve the product. [For more information](https://github.com/metalbear-co/mirrord/blob/main/TELEMETRY.md)","type":["boolean","null"]},"use_proxy":{"title":"use_proxy {#root-use_proxy}","description":"When disabled, mirrord will remove `HTTP[S]_PROXY` env variables before doing any network requests. This is useful when the system sets a proxy but you don't want mirrord to use it. This also applies to the mirrord process (as it just removes the env). If the remote pod sets this env, the mirrord process will still use it.","type":["boolean","null"]}},"additionalProperties":false,"definitions":{"AdvancedFsUserConfig":{"description":"Allows the user to specify the default behavior for file operations:\n\n1. `\"read\"` or `true` - Read from the remote file system (default) 2. `\"write\"` - Read/Write from the remote file system. 3. `\"local\"` or `false` - Read from the local file system. 4. `\"localwithoverrides\"` - perform fs operation locally, unless the path matches a pre-defined or user-specified exception.\n\n> Note: by default, some paths are read locally or remotely, regardless of the selected FS mode. > This is described in further detail below.\n\nBesides the default behavior, the user can specify behavior for specific regex patterns. Case insensitive.\n\n1. `\"read_write\"` - List of patterns that should be read/write remotely. 2. `\"read_only\"` - List of patterns that should be read only remotely. 3. `\"local\"` - List of patterns that should be read locally. 4. `\"not_found\"` - List of patters that should never be read nor written. These files should be treated as non-existent. 4. `\"mapping\"` - Map of patterns and their corresponding replacers. The replacement happens before any specific behavior as defined above or mode (uses [`Regex::replace`](https://docs.rs/regex/latest/regex/struct.Regex.html#method.replace))\n\nThe logic for choosing the behavior is as follows:\n\n1. Check agains \"mapping\" if path needs to be replaced, if matched then continue to next step with new path after replacements otherwise continue as usual. 2. Check if one of the patterns match the file path, do the corresponding action. There's no specified order if two lists match the same path, we will use the first one (and we do not guarantee what is first).\n\n**Warning**: Specifying the same path in two lists is unsupported and can lead to undefined behaviour.\n\n3. There are pre-defined exceptions to the set FS mode. 1. Paths that match [the patterns defined here](https://github.com/metalbear-co/mirrord/tree/latest/mirrord/layer/src/file/filter/read_local_by_default.rs) are read locally by default. 2. Paths that match [the patterns defined here](https://github.com/metalbear-co/mirrord/tree/latest/mirrord/layer/src/file/filter/read_remote_by_default.rs) are read remotely by default when the mode is `localwithoverrides`. 3. Paths that match [the patterns defined here](https://github.com/metalbear-co/mirrord/tree/latest/mirrord/layer/src/file/filter/not_found_by_default.rs) under the running user's home directory will not be found by the application when the mode is not `local`.\n\nIn order to override that default setting for a path, or a pattern, include it the appropriate pattern set from above. E.g. in order to read files under `/etc/` remotely even though it is covered by [the set of patterns that are read locally by default](https://github.com/metalbear-co/mirrord/tree/latest/mirrord/layer/src/file/filter/read_local_by_default.rs), add `\"^/etc/.\"` to the `read_only` set.\n\n4. If none of the above match, use the default behavior (mode).\n\nFor more information, check the file operations [technical reference](https://metalbear.co/mirrord/docs/reference/fileops/).\n\n```json { \"feature\": { \"fs\": { \"mode\": \"write\", \"read_write\": \".+\\\\.json\" , \"read_only\": [ \".+\\\\.yaml\", \".+important-file\\\\.txt\" ], \"local\": [ \".+\\\\.js\", \".+\\\\.mjs\" ], \"not_found\": [ \"\\\\.config/gcloud\" ] } } } ```","type":"object","properties":{"local":{"title":"feature.fs.local {#feature-fs-local}","description":"Specify file path patterns that if matched will be opened locally.","anyOf":[{"$ref":"#/definitions/VecOrSingle_for_String"},{"type":"null"}]},"mapping":{"title":"feature.fs.mapping {#feature-fs-mapping}","description":"Specify map of patterns that if matched will replace the path according to specification.\n\n*Capture groups are allowed.*\n\nExample: ```json { \"^/home/(?<user>\\\\S+)/dev/tomcat\": \"/etc/tomcat\" \"^/home/(?<user>\\\\S+)/dev/config/(?<app>\\\\S+)\": \"/mnt/configs/${user}-$app\" } ``` Will do the next replacements for any io operaton\n\n`/home/johndoe/dev/tomcat/context.xml` => `/etc/tomcat/context.xml` `/home/johndoe/dev/config/api/app.conf` => `/mnt/configs/johndoe-api/app.conf`\n\n- Relative paths: this feature (currently) does not apply mappings to relative paths, e.g. `../dev`.","type":["object","null"],"additionalProperties":{"type":"string"}},"mode":{"title":"feature.fs.mode {#feature-fs-mode}","anyOf":[{"$ref":"#/definitions/FsModeConfig"},{"type":"null"}]},"not_found":{"title":"feature.fs.not_found {#feature-fs-not_found}","description":"Specify file path patterns that if matched will be treated as non-existent.","anyOf":[{"$ref":"#/definitions/VecOrSingle_for_String"},{"type":"null"}]},"read_only":{"title":"feature.fs.read_only {#feature-fs-read_only}","description":"Specify file path patterns that if matched will be read from the remote. if file matching the pattern is opened for writing or read/write it will be opened locally.","anyOf":[{"$ref":"#/definitions/VecOrSingle_for_String"},{"type":"null"}]},"read_write":{"title":"feature.fs.read_write {#feature-fs-read_write}","description":"Specify file path patterns that if matched will be read and written to the remote.","anyOf":[{"$ref":"#/definitions/VecOrSingle_for_String"},{"type":"null"}]},"readonly_file_buffer":{"title":"feature.fs.readonly_file_buffer {#feature-fs-readonly_file_buffer}","description":"Sets buffer size for read-only remote files in bytes. By default, the value is 128000 bytes, or 128 kB.\n\nSetting the value to 0 disables file buffering. Otherwise, read-only remote files will be read in chunks and buffered locally. This improves performance when the user application reads data in small portions.","type":["integer","null"],"format":"uint64","minimum":0.0}},"additionalProperties":false},"AgentFileConfig":{"description":"Configuration for the mirrord-agent pod that is spawned in the Kubernetes cluster.\n\n**Note:** this configuration is ignored when using the mirrord Operator. Agent configuration is done by the cluster admin.\n\nWe provide sane defaults for this option, so you don't have to set up anything here.\n\n```json { \"agent\": { \"log_level\": \"info\", \"json_log\": false, \"namespace\": \"default\", \"image\": \"ghcr.io/metalbear-co/mirrord:latest\", \"image_pull_policy\": \"IfNotPresent\", \"image_pull_secrets\": [ { \"secret-key\": \"secret\" } ], \"ttl\": 30, \"ephemeral\": false, \"communication_timeout\": 30, \"startup_timeout\": 360, \"network_interface\": \"eth0\", \"flush_connections\": false, \"exclude_from_mesh\": false } } ```","type":"object","properties":{"annotations":{"title":"agent.annotations {#agent-annotations}","description":"Allows setting up custom annotations for the agent Job and Pod.\n\n```json { \"annotations\": { \"cats.io/inject\": \"enabled\" \"prometheus.io/scrape\": \"true\", \"prometheus.io/port\": \"9000\" } } ```","type":["object","null"],"additionalProperties":{"type":"string"}},"check_out_of_pods":{"title":"agent.check_out_of_pods {#agent-check_out_of_pods}","description":"Determine if to check whether there is room for agent job in target node. (Not applicable when using ephemeral containers feature)\n\nCan be disabled if the check takes too long and you are sure there is enough resources on each node","type":["boolean","null"]},"communication_timeout":{"title":"agent.communication_timeout {#agent-communication_timeout}","description":"Controls how long the agent lives when there are no connections.\n\nEach connection has its own heartbeat mechanism, so even if the local application has no messages, the agent stays alive until there are no more heartbeat messages.","type":["integer","null"],"format":"uint16","minimum":0.0},"disabled_capabilities":{"title":"agent.disabled_capabilities {#agent-disabled_capabilities}","description":"Disables specified Linux capabilities for the agent container. If nothing is disabled here, agent uses `NET_ADMIN`, `NET_RAW`, `SYS_PTRACE` and `SYS_ADMIN`.\n\nHas no effect when using the targetless mode, as targetless agent containers have no capabilities.","type":["array","null"],"items":{"$ref":"#/definitions/LinuxCapability"}},"dns":{"title":"agent.dns {#agent-dns}","anyOf":[{"$ref":"#/definitions/FileAgentDnsConfig"},{"type":"null"}]},"ephemeral":{"title":"agent.ephemeral {#agent-ephemeral}","description":"Runs the agent as an [ephemeral container](https://kubernetes.io/docs/concepts/workloads/pods/ephemeral-containers/).\n\nNot compatible with targetless runs.\n\nDefaults to `false`.","type":["boolean","null"]},"exclude_from_mesh":{"title":"agent.exclude_from_mesh {#agent-exclude_from_mesh}","description":"When running the agent as an ephemeral container, use this option to exclude the agent's port from the service mesh sidecar proxy.","type":["boolean","null"]},"flush_connections":{"title":"agent.flush_connections {#agent-flush_connections}","description":"Flushes existing connections when starting to steal, might fix issues where connections aren't stolen (due to being already established)\n\nDefaults to `true`.","type":["boolean","null"]},"image":{"title":"agent.image {#agent-image}","description":"Name of the agent's docker image.\n\nUseful when a custom build of mirrord-agent is required, or when using an internal registry.\n\nDefaults to the latest stable image `\"ghcr.io/metalbear-co/mirrord:latest\"`.\n\n```json { \"image\": \"internal.repo/images/mirrord:latest\" } ```\n\nComplete setup:\n\n```json { \"image\": { \"registry\": \"internal.repo/images/mirrord\", \"tag\": \"latest\" } } ```","anyOf":[{"$ref":"#/definitions/AgentImageFileConfig"},{"type":"null"}]},"image_pull_policy":{"title":"agent.image_pull_policy {#agent-image_pull_policy}","description":"Controls when a new agent image is downloaded.\n\nSupports `\"IfNotPresent\"`, `\"Always\"`, `\"Never\"`, or any valid kubernetes [image pull policy](https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy)\n\nDefaults to `\"IfNotPresent\"`","type":["string","null"]},"image_pull_secrets":{"title":"agent.image_pull_secrets {#agent-image_pull_secrets}","description":"List of secrets the agent pod has access to.\n\nTakes an array of entries with the format `{ name: <secret-name> }`.\n\nRead more [here](https://kubernetes.io/docs/concepts/containers/images/#referring-to-an-imagepullsecrets-on-a-pod).\n\n```json { \"agent\": { \"image_pull_secrets\": [ { \"name\": \"secret-key-1\" }, { \"name\": \"secret-key-2\" } ] } } ```","type":["array","null"],"items":{"$ref":"#/definitions/AgentPullSecret"}},"json_log":{"title":"agent.json_log {#agent-json_log}","description":"Controls whether the agent produces logs in a human-friendly format, or json.\n\n```json { \"agent\": { \"json_log\": true } } ```","type":["boolean","null"]},"labels":{"title":"agent.labels {#agent-labels}","description":"Allows setting up custom labels for the agent Job and Pod.\n\n```json { \"labels\": { \"user\": \"meow\", \"state\": \"asleep\" } } ```","type":["object","null"],"additionalProperties":{"type":"string"}},"log_level":{"title":"agent.log_level {#agent-log_level}","description":"Log level for the agent.\n\nSupports `\"trace\"`, `\"debug\"`, `\"info\"`, `\"warn\"`, `\"error\"`, or any string that would work with `RUST_LOG`.\n\n```json { \"agent\": { \"log_level\": \"mirrord=debug,warn\" } } ```","type":["string","null"]},"metrics":{"title":"agent.metrics {#agent-metrics}","description":"Enables prometheus metrics for the agent pod.\n\nYou might need to add annotations to the agent pod depending on how prometheus is configured to scrape for metrics.\n\n```json { \"metrics\": \"0.0.0.0:9000\" } ```","type":["string","null"]},"namespace":{"title":"agent.namespace {#agent-namespace}","description":"Namespace where the agent shall live.\n\n**Note:** ignored in targetless runs or when the agent is run as an ephemeral container.\n\nDefaults to the current kubernetes namespace.","type":["string","null"]},"network_interface":{"title":"agent.network_interface {#agent-network_interface}","description":"Which network interface to use for mirroring.\n\nThe default behavior is try to access the internet and use that interface. If that fails it uses `eth0`.","type":["string","null"]},"nftables":{"title":"agent.nftables {#agent-nftables}","description":"Use iptables-nft instead of iptables-legacy. Defaults to `false`.\n\nNeeded if your mesh uses nftables instead of iptables-legacy,","type":["boolean","null"]},"node_selector":{"title":"agent.node_selector {#agent-node_selector}","description":"Allows setting up custom node selector for the agent Pod. Applies only to targetless runs, as targeted agent always runs on the same node as its target container.\n\n```json { \"node_selector\": { \"kubernetes.io/hostname\": \"node1\" } } ```","type":["object","null"],"additionalProperties":{"type":"string"}},"priority_class":{"title":"agent.priority_class {#agent-priority_class}","description":"Specifies the priority class to assign to the agent pod.\n\nThis option is only applicable when running in the targetless mode.\n\n```json { \"priority_class\": \"my-priority-class-name\" } ```\n\nIn some cases, the targetless agent pod may fail to schedule due to node resource constraints. Setting a priority class allows you to explicitly assign an existing priority class from your cluster to the agent pod, increasing its priority relative to other workloads.","type":["string","null"]},"privileged":{"title":"agent.privileged {#agent-privileged}","description":"Run the mirror agent as privileged container. Defaults to `false`.\n\nMight be needed in strict environments such as Bottlerocket.\n\nHas no effect when using the targetless mode, as targetless agent containers are never privileged.","type":["boolean","null"]},"resources":{"title":"agent.resources {#agent-resources}","description":"Set pod resource reqirements. (not with ephemeral agents) Default is ```json { \"requests\": { \"cpu\": \"1m\", \"memory\": \"1Mi\" }, \"limits\": { \"cpu\": \"100m\", \"memory\": \"100Mi\" } } ```","anyOf":[{"$ref":"#/definitions/io.k8s.api.core.v1.ResourceRequirements"},{"type":"null"}]},"service_account":{"title":"agent.service_account {#agent-service_account}","description":"Allows setting up custom Service Account for the agent Job and Pod.\n\n```json { \"service_account\": \"my-service-account\" } ```","type":["string","null"]},"startup_timeout":{"title":"agent.startup_timeout {#agent-startup_timeout}","description":"Controls how long to wait for the agent to finish initialization.\n\nIf initialization takes longer than this value, mirrord exits.\n\nDefaults to `60`.","type":["integer","null"],"format":"uint64","minimum":0.0},"tolerations":{"title":"agent.tolerations {#agent-tolerations}","description":"Set pod tolerations. (not with ephemeral agents).\n\nDefaults to `operator: Exists`.\n\n```json [ { \"key\": \"meow\", \"operator\": \"Exists\", \"effect\": \"NoSchedule\" } ] ```\n\nSet to an empty array to have no tolerations at all","type":["array","null"],"items":{"$ref":"#/definitions/io.k8s.api.core.v1.Toleration"}},"ttl":{"title":"agent.ttl {#agent-ttl}","description":"Controls how long the agent pod persists for after the agent exits (in seconds).\n\nCan be useful for collecting logs.\n\nDefaults to `1`.","type":["integer","null"],"format":"uint16","minimum":0.0}},"additionalProperties":false},"AgentImageFileConfig":{"description":"<!--${internal}--> Allows us to support the dual configuration for the agent image.\n\nWhatever values missing are replaced with our defaults.","anyOf":[{"description":"The shortened version of: `image: \"repo/mirrord:latest\"`.","type":["string","null"]},{"description":"Expanded version: `image: { registry: \"repo/mirrord\", tag: \"latest\" }`.","type":"object","properties":{"registry":{"type":["string","null"]},"tag":{"type":["string","null"]}},"additionalProperties":false}]},"AgentPullSecret":{"description":"<!--${internal}--> Specifies a secret reference for the agent pod.","type":"object","required":["name"],"properties":{"name":{"description":"Name of the secret.","type":"string"}}},"ConcurrentSteal":{"description":"(Operator Only): Allows overriding port locks\n\nCan be set to either `\"continue\"` or `\"override\"`.\n\n- `\"continue\"`: Continue with normal execution - `\"override\"`: If port lock detected then override it with new lock and force close the original locking connection.","oneOf":[{"description":"<!--${internal}--> ### override\n\nOverride any port lock and force close the original lock connection","type":"string","enum":["override"]},{"description":"<!--${internal}--> ### continue\n\nContinue with normal execution","type":"string","enum":["continue"]},{"description":"<!--${internal}--> ### abort\n\nAbort Execution when trying to steal traffic from a target whose traffic is already being stolen.","type":"string","enum":["abort"]}]},"ContainerFileConfig":{"description":"Unstable: `mirrord container` command specific config.","type":"object","properties":{"cli_extra_args":{"title":"container.cli_extra_args {#container-cli_extra_args}","description":"Any extra args to use when creating the sidecar mirrord-cli container.\n\nThis is useful when you want to use portforwarding, passing `-p local:container` won't work for main command but adding them here will work ```json { \"container\": { \"cli_extra_args\": [\"-p\", \"local:container\"] } } ```","type":["array","null"],"items":{"type":"string"}},"cli_image":{"title":"container.cli_image {#container-cli_image}","description":"Tag of the `mirrord-cli` image you want to use.\n\nDefaults to `\"ghcr.io/metalbear-co/mirrord-cli:<cli version>\"`.","type":["string","null"]},"cli_image_lib_path":{"title":"container.cli_image_lib_path {#container-cli_image}","description":"Path of the mirrord-layer lib inside the specified mirrord-cli image.\n\nDefaults to `\"/opt/mirrord/lib/libmirrord_layer.so\"`.","type":["string","null"]},"cli_prevent_cleanup":{"title":"container.cli_prevent_cleanup {#container-cli_extra_args}","description":"Don't add `--rm` to sidecar command to prevent cleanup.","type":["boolean","null"]},"override_host_ip":{"title":"container.override_host_ip {#container-override_host_ip}","description":"Allows to override the IP address for the internal proxy to use when connecting to the host machine from within the container.\n\n```json5 { \"container\": { \"override_host_ip\": \"172.17.0.1\" // usual resolution of value from `host.docker.internal` } } ```\n\nThis should be useful if your host machine is exposed with a different IP address than the one bound as host.\n\n- If you're running inside WSL, and encountering problems, try setting `external_proxy.host_ip` T `0.0.0.0`, and this to the internal container runtime address (for docker, this  would be what `host.docker.internal` resolved to, which by default is `192.168.65.254`). You can find this ip by resolving it from inside a running container, e.g. `docker run --rm -it {image-with-nslookup} nslookup host.docker.internal`","type":["string","null"],"format":"ip"}},"additionalProperties":false},"CopyTargetFileConfig":{"anyOf":[{"type":"boolean"},{"type":"object","properties":{"enabled":{"type":["boolean","null"]},"scale_down":{"type":["boolean","null"]}},"additionalProperties":false}]},"CronJobTarget":{"type":"object","required":["cron_job"],"properties":{"container":{"type":["string","null"]},"cron_job":{"type":"string"}},"additionalProperties":false},"DeploymentTarget":{"description":"<!--${internal}--> Mirror the deployment specified by [`DeploymentTarget::deployment`].","type":"object","required":["deployment"],"properties":{"container":{"type":["string","null"]},"deployment":{"description":"<!--${internal}--> Deployment to mirror.","type":"string"}},"additionalProperties":false},"DnsFileConfig":{"description":"Resolve DNS via the remote pod.\n\nDefaults to `true`.\n\nMind that: - DNS resolving can be done in multiple ways. Some frameworks use `getaddrinfo`/`gethostbyname` functions, while others communicate directly with the DNS server at port `53` and perform a sort of manual resolution. Just enabling the `dns` feature in mirrord might not be enough. If you see an address resolution error, try enabling the [`fs`](#feature-fs) feature, and setting `read_only: [\"/etc/resolv.conf\"]`. - DNS filter currently works only with frameworks that use `getaddrinfo`/`gethostbyname` functions.","type":"object","properties":{"enabled":{"type":["boolean","null"]},"filter":{"title":"feature.network.dns.filter {#feature-network-dns-filter}","description":"Unstable: the precise syntax of this config is subject to change.","anyOf":[{"$ref":"#/definitions/DnsFilterConfig"},{"type":"null"}]}},"additionalProperties":false},"DnsFilterConfig":{"description":"List of addresses/ports/subnets that should be resolved through either the remote pod or local app, depending how you set this up with either `remote` or `local`.\n\nYou may use this option to specify when DNS resolution is done from the remote pod (which is the default behavior when you enable remote DNS), or from the local app (default when you have remote DNS disabled).\n\nTakes a list of values, such as:\n\n- Only queries for hostname `my-service-in-cluster` will go through the remote pod.\n\n```json { \"remote\": [\"my-service-in-cluster\"] } ```\n\n- Only queries for addresses in subnet `1.1.1.0/24` with service port `1337`` will go through the remote pod.\n\n```json { \"remote\": [\"1.1.1.0/24:1337\"] } ```\n\n- Only queries for hostname `google.com` with service port `1337` or `7331` will go through the remote pod.\n\n```json { \"remote\": [\"google.com:1337\", \"google.com:7331\"] } ```\n\n- Only queries for `localhost` with service port `1337` will go through the local app.\n\n```json { \"local\": [\"localhost:1337\"] } ```\n\n- Only queries with service port `1337` or `7331` will go through the local app.\n\n```json { \"local\": [\":1337\", \":7331\"] } ```\n\nValid values follow this pattern: `[name|address|subnet/mask][:port]`.","oneOf":[{"description":"DNS queries matching what is specified here will go through the remote pod, everything else will go through local.","type":"object","required":["remote"],"properties":{"remote":{"$ref":"#/definitions/VecOrSingle_for_String"}},"additionalProperties":false},{"description":"DNS queries matching what is specified here will go through the local app, everything else will go through the remote pod.","type":"object","required":["local"],"properties":{"local":{"$ref":"#/definitions/VecOrSingle_for_String"}},"additionalProperties":false}]},"EnvFileConfig":{"description":"Allows the user to set or override the local process' environment variables with the ones from the remote pod.\n\nCan be set to one of the options:\n\n1. `false` - Disables the feature, won't have remote environment variables. 2. `true` - Enables the feature, will obtain remote environment variables. 3. object - see below (means `true` + additional configuration).\n\nWhich environment variables to load from the remote pod are controlled by setting either [`include`](#feature-env-include) or [`exclude`](#feature-env-exclude).\n\nSee the environment variables [reference](https://metalbear.co/mirrord/docs/reference/env/) for more details.\n\n```json { \"feature\": { \"env\": { \"include\": \"DATABASE_USER;PUBLIC_ENV;MY_APP_*\", \"exclude\": \"DATABASE_PASSWORD;SECRET_ENV\", \"override\": { \"DATABASE_CONNECTION\": \"db://localhost:7777/my-db\", \"LOCAL_BEAR\": \"panda\" }, \"mapping\": { \".+_TIMEOUT\": \"1000\" } } } } ```","type":"object","properties":{"env_file":{"title":"feature.env_file {#feature-env-file}","description":"Allows for passing environment variables from an env file.\n\nThese variables will override environment fetched from the remote target.","type":["string","null"]},"exclude":{"title":"feature.env.exclude {#feature-env-exclude}","description":"Include the remote environment variables in the local process that are **NOT** specified by this option. Variable names can be matched using `*` and `?` where `?` matches exactly one occurrence of any character and `*` matches arbitrary many (including zero) occurrences of any character.\n\nSome of the variables that are excluded by default: `PATH`, `HOME`, `HOMEPATH`, `CLASSPATH`, `JAVA_EXE`, `JAVA_HOME`, `PYTHONPATH`.\n\nCan be passed as a list or as a semicolon-delimited string (e.g. `\"VAR;OTHER_VAR\"`).","anyOf":[{"$ref":"#/definitions/VecOrSingle_for_String"},{"type":"null"}]},"include":{"title":"feature.env.include {#feature-env-include}","description":"Include only these remote environment variables in the local process. Variable names can be matched using `*` and `?` where `?` matches exactly one occurrence of any character and `*` matches arbitrary many (including zero) occurrences of any character.\n\nCan be passed as a list or as a semicolon-delimited string (e.g. `\"VAR;OTHER_VAR\"`).\n\nSome environment variables are excluded by default (`PATH` for example), including these requires specifying them with `include`","anyOf":[{"$ref":"#/definitions/VecOrSingle_for_String"},{"type":"null"}]},"load_from_process":{"title":"feature.env.load_from_process {#feature-env-load_from_process}","description":"Allows for changing the way mirrord loads remote environment variables. If set, the variables are fetched after the user application is started.\n\nThis setting is meant to resolve issues when using mirrord via the IntelliJ plugin on WSL and the remote environment contains a lot of variables.","type":["boolean","null"]},"mapping":{"title":"feature.env.mapping {#feature-env-mapping}","description":"Specify map of patterns that if matched will replace the value according to specification.\n\n*Capture groups are allowed.*\n\nExample: ```json { \".+_TIMEOUT\": \"10000\" \"LOG_.+_VERBOSITY\": \"debug\" \"(\\w+)_(\\d+)\": \"magic-value\" } ```\n\nWill do the next replacements for environment variables that match:\n\n* `CONNECTION_TIMEOUT: 500` => `CONNECTION_TIMEOUT: 10000`\n\n* `LOG_FILE_VERBOSITY: info` => `LOG_FILE_VERBOSITY: debug`\n\n* `DATA_1234: common-value` => `DATA_1234: magic-value`","type":["object","null"],"additionalProperties":{"type":"string"}},"override":{"title":"feature.env.override {#feature-env-override}","description":"Allows setting or overriding environment variables (locally) with a custom value.\n\nFor example, if the remote pod has an environment variable `REGION=1`, but this is an undesirable value, it's possible to use `override` to set `REGION=2` (locally) instead.\n\nEnvironment specified here will also override variables passed via the env file.","type":["object","null"],"additionalProperties":{"type":"string"}},"unset":{"title":"feature.env.unset {#feature-env-unset}","description":"Allows unsetting environment variables in the executed process.\n\nThis is useful for when some system/user-defined environment like `AWS_PROFILE` make the application behave as if it's running locally, instead of using the remote settings. The unsetting happens from extension (if possible)/CLI and when process initializes. In some cases, such as Go the env might not be able to be modified from the process itself. This is case insensitive, meaning if you'd put `AWS_PROFILE` it'd unset both `AWS_PROFILE` and `Aws_Profile` and other variations.","anyOf":[{"$ref":"#/definitions/VecOrSingle_for_String"},{"type":"null"}]}},"additionalProperties":false},"ExperimentalFileConfig":{"description":"mirrord Experimental features. This shouldn't be used unless someone from MetalBear/mirrord tells you to.","type":"object","properties":{"browser_extension_config":{"title":"_experimental_ browser_extension_config {#experimental-browser_extension_config}","description":"mirrord will either open a URL for initiating mirrord browser extension to automatically inject HTTP header that matches the HTTP filter configured in `feature.network.incoming.http_filter.header_filter`.","type":["boolean","null"]},"disable_reuseaddr":{"title":"_experimental_ disable_reuseaddr {#experimental-disable_reuseaddr}","description":"Disables the `SO_REUSEADDR` socket option on sockets that mirrord steals/mirrors. On macOS the application can use the same address many times but then we don't steal it correctly. This probably should be on by default but we want to gradually roll it out. <https://github.com/metalbear-co/mirrord/issues/2819> This option applies only on macOS.","type":["boolean","null"]},"enable_exec_hooks_linux":{"title":"_experimental_ enable_exec_hooks_linux {#experimental-enable_exec_hooks_linux}","description":"Enables exec hooks on Linux. Enable Linux hooks can fix issues when the application shares sockets with child commands (e.g Python web servers with reload), but the feature is not stable and may cause other issues.","type":["boolean","null"]},"hide_ipv6_interfaces":{"title":"_experimental_ hide_ipv6_interfaces {#experimental-hide_ipv6_interfaces}","description":"Enables `getifaddrs` hook that removes IPv6 interfaces from the list returned by libc.","type":["boolean","null"]},"idle_local_http_connection_timeout":{"title":"_experimental_ idle_local_http_connection_timeout {#experimental-idle_local_http_connection_timeout}","description":"Sets a timeout for idle local HTTP connections (in milliseconds).\n\nHTTP requests stolen with a filter are delivered to the local application from a HTTP connection made from the local machine. Once a request is delivered, the connection is cached for some time, so that it can be reused to deliver the next request.\n\nThis timeout determines for how long such connections are cached.\n\nSet to 0 to disable caching local HTTP connections (connections will be dropped as soon as the request is delivered).\n\nDefaults to 3000ms.","type":["integer","null"],"format":"uint64","minimum":0.0},"ignore_system_proxy_config":{"title":"_experimental_ ignore_system_proxy_config {#experimental-ignore_system_proxy_config}","description":"Disables any system wide proxy configuration for affecting the running application.","type":["boolean","null"]},"readlink":{"title":"_experimental_ readlink {#experimental-readlink}","description":"DEPRECATED, WILL BE REMOVED","type":["boolean","null"]},"readonly_file_buffer":{"title":"_experimental_ readonly_file_buffer {#experimental-readonly_file_buffer}","description":"DEPRECATED, WILL BE REMOVED: moved to `feature.fs.readonly_file_buffer` as part of stabilisation. See <https://github.com/metalbear-co/mirrord/issues/2069>.","type":["integer","null"],"format":"uint64","minimum":0.0},"tcp_ping4_mock":{"title":"_experimental_ tcp_ping4_mock {#experimental-tcp_ping4_mock}","description":"<https://github.com/metalbear-co/mirrord/issues/2421#issuecomment-2093200904>","type":["boolean","null"]},"trust_any_certificate":{"title":"_experimental_ trust_any_certificate {#experimental-trust_any_certificate}","description":"Enables trusting any certificate on macOS, useful for <https://github.com/golang/go/issues/51991#issuecomment-2059588252>","type":["boolean","null"]},"use_dev_null":{"title":"_experimental_ use_dev_null {#experimental-use_dev_null}","description":"Uses /dev/null for creating local fake files (should be better than using /tmp)","type":["boolean","null"]}},"additionalProperties":false},"ExternalProxyFileConfig":{"description":"Configuration for the external proxy mirrord spawns when using the `mirrord container` command. This proxy is used to allow the internal proxy running in sidecar to connect to the mirrord agent.\n\nIf you get `ConnectionRefused` errors, increasing the timeouts a bit might solve the issue.\n\n```json { \"external_proxy\": { \"start_idle_timeout\": 30, \"idle_timeout\": 5 } } ```","type":"object","properties":{"host_ip":{"title":"external_proxy.host_ip {#external_proxy-host_ip}","description":"Specify a custom host ip addr to listen on.\n\nThis address must be accessible from within the container. If not specified, mirrord will try and resolve a local address to use.\n\n- If you're running inside WSL, and encountering problems, try setting this to `0.0.0.0`, and `container.override_host_ip` to the internal container runtime address (for docker, this would be what `host.docker.internal` resolved to, which by default is `192.168.65.254`).","type":["string","null"],"format":"ip"},"idle_timeout":{"title":"external_proxy.idle_timeout {#external_proxy-idle_timeout}","description":"How much time to wait while we don't have any active connections before exiting.\n\nCommon cases would be running a chain of processes that skip using the layer and don't connect to the proxy.\n\n```json { \"external_proxy\": { \"idle_timeout\": 30 } } ```","type":["integer","null"],"format":"uint64","minimum":0.0},"json_log":{"title":"external_proxy.json_log {#external_proxy-json_log}","description":"Whether the proxy should output logs in JSON format. If false, logs are output in human-readable format.\n\nDefaults to true.","type":["boolean","null"]},"log_destination":{"title":"external_proxy.log_destination {#external_proxy-log_destination}","description":"Set the log file destination for the external proxy.\n\nDefaults to a randomized path inside the temporary directory.","type":["string","null"]},"log_level":{"title":"external_proxy.log_level {#external_proxy-log_level}","description":"Set the log level for the external proxy.\n\nThe value should follow the RUST_LOG convention (i.e `mirrord=trace`).\n\nDefaults to `mirrord=info,warn`.","type":["string","null"]},"start_idle_timeout":{"title":"external_proxy.start_idle_timeout {#external_proxy-start_idle_timeout}","description":"How much time to wait for the first connection to the external proxy in seconds.\n\nCommon cases would be running with dlv or any other debugger, which sets a breakpoint on process execution, delaying the layer startup and connection to the external proxy.\n\n```json { \"external_proxy\": { \"start_idle_timeout\": 60 } } ```","type":["integer","null"],"format":"uint64","minimum":0.0},"tls_enable":{"description":"<!--${internal}-->\n\nWhether to use TLS or a plain TCP when accepting a connection from the internal proxy sidecar.","type":["boolean","null"]}},"additionalProperties":false},"FeatureFileConfig":{"description":"Controls mirrord features.\n\nSee the [technical reference, Technical Reference](https://metalbear.co/mirrord/docs/reference/) to learn more about what each feature does.\n\nThe [`env`](#feature-env), [`fs`](#feature-fs) and [`network`](#feature-network) options have support for a shortened version, that you can see [here](#root-shortened).\n\n```json { \"feature\": { \"env\": { \"include\": \"DATABASE_USER;PUBLIC_ENV\", \"exclude\": \"DATABASE_PASSWORD;SECRET_ENV\", \"override\": { \"DATABASE_CONNECTION\": \"db://localhost:7777/my-db\", \"LOCAL_BEAR\": \"panda\" } }, \"fs\": { \"mode\": \"write\", \"read_write\": \".+\\\\.json\" , \"read_only\": [ \".+\\\\.yaml\", \".+important-file\\\\.txt\" ], \"local\": [ \".+\\\\.js\", \".+\\\\.mjs\" ] }, \"network\": { \"incoming\": { \"mode\": \"steal\", \"http_filter\": { \"header_filter\": \"host: api\\\\..+\" }, \"port_mapping\": [[ 7777, 8888 ]], \"ignore_localhost\": false, \"ignore_ports\": [9999, 10000] }, \"outgoing\": { \"tcp\": true, \"udp\": true, \"filter\": { \"local\": [\"tcp://1.1.1.0/24:1337\", \"1.1.5.0/24\", \"google.com\", \":53\"] }, \"ignore_localhost\": false, \"unix_streams\": \"bear.+\" }, \"dns\": false }, \"copy_target\": false, \"hostname\": true } } ```","type":"object","properties":{"copy_target":{"title":"feature.copy_target {#feature-copy_target}","description":"Creates a new copy of the target. mirrord will use this copy instead of the original target (e.g. intercept network traffic). This feature requires a [mirrord operator](https://metalbear.co/mirrord/docs/overview/teams/?utm_source=copytarget).\n\nThis feature is not compatible with rollout targets and running without a target (`targetless` mode).","anyOf":[{"$ref":"#/definitions/CopyTargetFileConfig"},{"type":"null"}]},"env":{"title":"feature.env {#feature-env}","anyOf":[{"$ref":"#/definitions/ToggleableConfig_for_EnvFileConfig"},{"type":"null"}]},"fs":{"title":"feature.fs {#feature-fs}","anyOf":[{"$ref":"#/definitions/ToggleableConfig_for_FsUserConfig"},{"type":"null"}]},"hostname":{"title":"feature.hostname {#feature-hostname}","description":"Should mirrord return the hostname of the target pod when calling `gethostname`","type":["boolean","null"]},"network":{"title":"feature.network {#feature-network}","anyOf":[{"$ref":"#/definitions/ToggleableConfig_for_NetworkFileConfig"},{"type":"null"}]},"split_queues":{"title":"feature.split_queues {#feature-split_queues}","description":"Define filters to split queues by, and make your local application consume only messages that match those filters. If you don't specify any filter for a queue that is however declared in the `MirrordWorkloadQueueRegistry` of the target you're using, a match-nothing filter will be used, and your local application will not receive any messages from that queue.","anyOf":[{"$ref":"#/definitions/SplitQueuesConfig"},{"type":"null"}]}},"additionalProperties":false},"FileAgentDnsConfig":{"type":"object","properties":{"attempts":{"title":"agent.dns.attempts {#agent-dns-attempts}","description":"When agent resolves DNS, how many attempts before failing. If the value is too high, it might cause internal proxy to timeout and exit.","type":["integer","null"],"format":"uint32","minimum":0.0},"timeout":{"title":"agent.dns.timeout {#agent-dns-timeout}","description":"When agent resolves DNS, how long to wait for a response before timeout By default this is set to 1 (in the agent). If the value is too high, it might cause internal proxy to timeout and exit.","type":["integer","null"],"format":"uint32","minimum":0.0}},"additionalProperties":false},"FsModeConfig":{"description":"Configuration for enabling read-only or read-write file operations.\n\nThese options are overriden by user specified overrides and mirrord default overrides.\n\nIf you set [`\"localwithoverrides\"`](#feature-fs-mode-localwithoverrides) then some files can be read/write remotely based on our default/user specified. Default option for general file configuration.\n\nThe accepted values are: `\"local\"`, `\"localwithoverrides`, `\"read\"`, or `\"write`.","oneOf":[{"title":"feature.fs.mode.local {#feature-fs-mode-local}","description":"mirrord won't do anything fs-related, all operations will be local.","type":"string","enum":["local"]},{"title":"feature.fs.mode.localwithoverrides {#feature-fs-mode-localwithoverrides}","description":"mirrord will run overrides on some file operations, but most will be local.","type":"string","enum":["localwithoverrides"]},{"title":"feature.fs.mode.read {#feature-fs-mode-read}","description":"mirrord will read files from the remote, but won't write to them.","type":"string","enum":["read"]},{"title":"feature.fs.mode.write {#feature-fs-mode-write}","description":"mirrord will read/write from the remote.","type":"string","enum":["write"]}]},"FsUserConfig":{"title":"feature.fs {#fs}","description":"Changes file operations behavior based on user configuration.\n\nSee the file operations [reference](https://metalbear.co/mirrord/docs/reference/fileops/) for more details, and [fs advanced](#fs-advanced) for more information on how to fully setup mirrord file operations.\n\n### Minimal `fs` config {#fs-minimal}\n\n```json { \"feature\": { \"fs\": \"read\" } } ```\n\n### Advanced `fs` config {#fs-advanced}\n\n```json { \"feature\": { \"fs\": { \"mode\": \"write\", \"read_write\": \".+\\\\.json\" , \"read_only\": [ \".+\\\\.yaml\", \".+important-file\\\\.txt\" ], \"local\": [ \".+\\\\.js\", \".+\\\\.mjs\" ] } } } ```","anyOf":[{"description":"<!--${internal}--> Basic configuration that controls the env vars `MIRRORD_FILE_OPS` and `MIRRORD_FILE_RO_OPS` (default).","allOf":[{"$ref":"#/definitions/FsModeConfig"}]},{"description":"<!--${internal}--> Allows the user to specify both [`FsModeConfig`] (as above), and configuration for the overrides.","allOf":[{"$ref":"#/definitions/AdvancedFsUserConfig"}]}]},"HttpFilterFileConfig":{"description":"Filter configuration for the HTTP traffic stealer feature.\n\nAllows the user to set a filter (regex) for the HTTP headers, so that the stealer traffic feature only captures HTTP requests that match the specified filter, forwarding unmatched requests to their original destinations.\n\nOnly does something when [`feature.network.incoming.mode`](#feature-network-incoming-mode) is set as `\"steal\"`, ignored otherwise.\n\nFor example, to filter based on header: ```json { \"header_filter\": \"host: api\\\\..+\" } ``` Setting that filter will make mirrord only steal requests with the `host` header set to hosts that start with \"api\", followed by a dot, and then at least one more character.\n\nFor example, to filter based on path: ```json { \"path_filter\": \"^/api/\" } ``` Setting this filter will make mirrord only steal requests to URIs starting with \"/api/\".\n\nThis can be useful for filtering out Kubernetes liveness, readiness and startup probes. For example, for avoiding stealing any probe sent by kubernetes, you can set this filter: ```json { \"header_filter\": \"^User-Agent: (?!kube-probe)\" } ``` Setting this filter will make mirrord only steal requests that **do** have a user agent that **does not** begin with \"kube-probe\".\n\nSimilarly, you can exclude certain paths using a negative look-ahead: ```json { \"path_filter\": \"^(?!/health/)\" } ``` Setting this filter will make mirrord only steal requests to URIs that do not start with \"/health/\".\n\nWith `all_of` and `any_of`, you can use multiple HTTP filters at the same time.\n\nIf you want to steal HTTP requests that match **every** pattern specified, use `all_of`. For example, this filter steals only HTTP requests to endpoint `/api/my-endpoint` that contain header `x-debug-session` with value `121212`. ```json { \"all_of\": [ { \"header\": \"^x-debug-session: 121212$\" }, { \"path\": \"^/api/my-endpoint$\" } ] } ```\n\nIf you want to steal HTTP requests that match **any** of the patterns specified, use `any_of`. For example, this filter steals HTTP requests to endpoint `/api/my-endpoint` **and** HTTP requests that contain header `x-debug-session` with value `121212`. ```json { \"any_of\": [ { \"path\": \"^/api/my-endpoint$\"}, { \"header\": \"^x-debug-session: 121212$\" } ] } ```","type":"object","properties":{"all_of":{"title":"feature.network.incoming.http_filter.all_of {#feature-network-incoming-http_filter-all_of}","description":"An array of HTTP filters.\n\nEach inner filter specifies either header or path regex. Requests must match all of the filters to be stolen.\n\nCannot be an empty list.\n\nExample: ```json { \"all_of\": [ { \"header\": \"x-user: my-user$\" }, { \"path\": \"^/api/v1/my-endpoint\" } ] } ```","type":["array","null"],"items":{"$ref":"#/definitions/InnerFilter"}},"any_of":{"title":"feature.network.incoming.http_filter.any_of {#feature-network-incoming-http_filter-any_of}","description":"An array of HTTP filters.\n\nEach inner filter specifies either header or path regex. Requests must match at least one of the filters to be stolen.\n\nCannot be an empty list.\n\nExample: ```json { \"any_of\": [ { \"header\": \"^x-user: my-user$\" }, { \"path\": \"^/api/v1/my-endpoint\" } ] } ```","type":["array","null"],"items":{"$ref":"#/definitions/InnerFilter"}},"header_filter":{"title":"feature.network.incoming.http_filter.header_filter {#feature-network-incoming-http-header-filter}","description":"Supports regexes validated by the [`fancy-regex`](https://docs.rs/fancy-regex/latest/fancy_regex/) crate.\n\nThe HTTP traffic feature converts the HTTP headers to `HeaderKey: HeaderValue`, case-insensitive.","type":["string","null"]},"path_filter":{"title":"feature.network.incoming.http_filter.path_filter {#feature-network-incoming-http-path-filter}","description":"Supports regexes validated by the [`fancy-regex`](https://docs.rs/fancy-regex/latest/fancy_regex/) crate.\n\nCase-insensitive. Tries to find match in the path (without query) and path+query. If any of the two matches, the request is stolen.","type":["string","null"]},"ports":{"title":"feature.network.incoming.http_filter.ports {#feature-network-incoming-http_filter-ports}","description":"Activate the HTTP traffic filter only for these ports.\n\nOther ports will *not* be stolen, unless listed in [`feature.network.incoming.ports`](#feature-network-incoming-ports).\n\nWe check the pod's health probe ports and automatically add them here, as they're usually the same ports your app might be listening on. If your app ports and the health probe ports don't match, then setting this option will override this behavior.\n\nSet to [80, 8080] by default.","anyOf":[{"$ref":"#/definitions/PortList"},{"type":"null"}]}},"additionalProperties":false},"HttpsDeliveryProtocol":{"oneOf":[{"description":"HTTPS requests will be delivered over TCP, as plain HTTP.","type":"string","enum":["tcp"]},{"description":"HTTPS requests will be delivered over TLS, as HTTPS.","type":"string","enum":["tls"]}]},"IncomingAdvancedFileConfig":{"title":"incoming (advanced setup)","description":"Advanced user configuration for network incoming traffic.","type":"object","properties":{"http_filter":{"title":"HTTP Filter","description":"Sets up the HTTP traffic filter (currently, only useful when `incoming: steal`).\n\nSee [`filter`](##filter) for details.","anyOf":[{"$ref":"#/definitions/ToggleableConfig_for_HttpFilterFileConfig"},{"type":"null"}]},"https_delivery":{"title":"https_delivery","description":"(Operator Only): configures how mirrord delivers stolen HTTPS requests to the local application.","default":{"protocol":"tls","server_cert":null,"server_name":null,"trust_roots":null},"allOf":[{"$ref":"#/definitions/LocalHttpsDelivery"}]},"ignore_localhost":{"title":"ignore_localhost","description":"Consider removing when adding <https://github.com/metalbear-co/mirrord/issues/702>","type":["boolean","null"]},"ignore_ports":{"title":"ignore_ports","description":"Ports to ignore when mirroring/stealing traffic. Useful if you want specific ports to be used locally only.\n\nMutually exclusive with [`ports`](###ports).","type":["array","null"],"items":{"type":"integer","format":"uint16","minimum":0.0}},"listen_ports":{"title":"listen_ports","description":"Mapping for local ports to actually used local ports. When application listens on a port while steal/mirror is active we fallback to random ports to avoid port conflicts. Using this configuration will always use the specified port. If this configuration doesn't exist, mirrord will try to listen on the original port and if it fails it will assign a random port\n\nThis is useful when you want to access ports exposed by your service locally For example, if you have a service that listens on port `80` and you want to access it, you probably can't listen on `80` without sudo, so you can use `[[80, 4480]]` then access it on `4480` while getting traffic from remote `80`. The value of `port_mapping` doesn't affect this.","type":["array","null"],"items":{"type":"array","items":[{"type":"integer","format":"uint16","minimum":0.0},{"type":"integer","format":"uint16","minimum":0.0}],"maxItems":2,"minItems":2}},"mode":{"title":"mode","description":"Allows selecting between mirrorring or stealing traffic.\n\nSee [`mode`](##mode (incoming)) for details.","anyOf":[{"$ref":"#/definitions/IncomingMode"},{"type":"null"}]},"on_concurrent_steal":{"title":"on_concurrent_steal","description":"(Operator Only): if value of override will force close any other connections on requested target","anyOf":[{"$ref":"#/definitions/ConcurrentSteal"},{"type":"null"}]},"port_mapping":{"title":"port_mapping","description":"Mapping for local ports to remote ports.\n\nThis is useful when you want to mirror/steal a port to a different port on the remote machine. For example, your local process listens on port `9333` and the container listens on port `80`. You'd use `[[9333, 80]]`","type":["array","null"],"items":{"type":"array","items":[{"type":"integer","format":"uint16","minimum":0.0},{"type":"integer","format":"uint16","minimum":0.0}],"maxItems":2,"minItems":2}},"ports":{"title":"ports","description":"List of ports to mirror/steal traffic from. Other ports will remain local.\n\nMutually exclusive with [`ignore_ports`](###ignore_ports).","type":["array","null"],"items":{"type":"integer","format":"uint16","minimum":0.0}}},"additionalProperties":false},"IncomingFileConfig":{"title":"incoming (network)","description":"Controls the incoming TCP traffic feature.\n\nSee the incoming [reference](https://metalbear.co/mirrord/docs/reference/traffic/#incoming) for more details.\n\nIncoming traffic supports 2 modes of operation:\n\n1. Mirror (**default**): Sniffs the TCP data from a port, and forwards a copy to the interested listeners;\n\n2. Steal: Captures the TCP data from a port, and forwards it to the local process, see [`steal`](##steal);\n\n### Minimal `incoming` config\n\n```json { \"feature\": { \"network\": { \"incoming\": \"steal\" } } } ```\n\n### Advanced `incoming` config\n\n```json { \"feature\": { \"network\": { \"incoming\": { \"mode\": \"steal\", \"http_filter\": { \"header_filter\": \"host: api\\\\..+\" }, \"port_mapping\": [[ 7777, 8888 ]], \"ignore_localhost\": false, \"ignore_ports\": [9999, 10000], \"listen_ports\": [[80, 8111]] } } } } ```","anyOf":[{"anyOf":[{"$ref":"#/definitions/IncomingMode"},{"type":"null"}]},{"$ref":"#/definitions/IncomingAdvancedFileConfig"}]},"IncomingMode":{"description":"Allows selecting between mirrorring or stealing traffic.\n\nCan be set to either `\"mirror\"` (default), `\"steal\"` or `\"off\"`.\n\n- `\"mirror\"`: Sniffs on TCP port, and send a copy of the data to listeners. - `\"off\"`: Disables the incoming network feature. - `\"steal\"`: Supports 2 modes of operation:\n\n1. Port traffic stealing: Steals all TCP data from a port, which is selected whenever the user listens in a TCP socket (enabling the feature is enough to make this work, no additional configuration is needed);\n\n2. HTTP traffic stealing: Steals only HTTP traffic, mirrord tries to detect if the incoming data on a port is HTTP (in a best-effort kind of way, not guaranteed to be HTTP), and steals the traffic on the port if it is HTTP;","oneOf":[{"description":"<!--${internal}--> ### mirror\n\nSniffs on TCP port, and send a copy of the data to listeners.","type":"string","enum":["mirror"]},{"description":"<!--${internal}--> ### steal\n\nStealer supports 2 modes of operation:\n\n1. Port traffic stealing: Steals all TCP data from a port, which is selected whenever the user listens in a TCP socket (enabling the feature is enough to make this work, no additional configuration is needed);\n\n2. HTTP traffic stealing: Steals only HTTP traffic, mirrord tries to detect if the incoming data on a port is HTTP (in a best-effort kind of way, not guaranteed to be HTTP), and steals the traffic on the port if it is HTTP;","type":"string","enum":["steal"]},{"description":"<!--${internal}--> ### Off\n\nDisables the incoming network feature.","type":"string","enum":["off"]}]},"InnerFilter":{"anyOf":[{"title":"feature.network.incoming.inner_filter.header_filter {#feature-network-incoming-inner-header-filter}","description":"Supports regexes validated by the [`fancy-regex`](https://docs.rs/fancy-regex/latest/fancy_regex/) crate.\n\nThe HTTP traffic feature converts the HTTP headers to `HeaderKey: HeaderValue`, case-insensitive.","type":"object","required":["header"],"properties":{"header":{"type":"string"}}},{"title":"feature.network.incoming.inner_filter.path_filter {#feature-network-incoming-inner-path-filter}","description":"Supports regexes validated by the [`fancy-regex`](https://docs.rs/fancy-regex/latest/fancy_regex/) crate.\n\nCase-insensitive. Tries to find match in the path (without query) and path+query. If any of the two matches, the request is stolen.","type":"object","required":["path"],"properties":{"path":{"type":"string"}}}]},"InternalProxyFileConfig":{"description":"Configuration for the internal proxy mirrord spawns for each local mirrord session that local layers use to connect to the remote agent\n\nThis is seldom used, but if you get `ConnectionRefused` errors, you might want to increase the timeouts a bit.\n\n```json { \"internal_proxy\": { \"start_idle_timeout\": 30, \"idle_timeout\": 5 } } ```","type":"object","properties":{"idle_timeout":{"title":"internal_proxy.idle_timeout {#internal_proxy-idle_timeout}","description":"How much time to wait while we don't have any active connections before exiting.\n\nCommon cases would be running a chain of processes that skip using the layer and don't connect to the proxy.\n\n```json { \"internal_proxy\": { \"idle_timeout\": 30 } } ```","type":["integer","null"],"format":"uint64","minimum":0.0},"json_log":{"title":"internal_proxy.json_log {#internal_proxy-json_log}","description":"Whether the proxy should output logs in JSON format. If false, logs are output in human-readable format.\n\nDefaults to true.","type":["boolean","null"]},"log_destination":{"title":"internal_proxy.log_destination {#internal_proxy-log_destination}","description":"Set the log file destination for the internal proxy.\n\nDefaults to a randomized path inside the temporary directory.","type":["string","null"]},"log_level":{"title":"internal_proxy.log_level {#internal_proxy-log_level}","description":"Set the log level for the internal proxy.\n\nThe value should follow the RUST_LOG convention (i.e `mirrord=trace`).\n\nDefaults to `mirrord=info,warn`.","type":["string","null"]},"socket_timeout":{"description":"<!--${internal}-->\n\nSometimes the cpu is too busy with other tasks and the internal proxy sockets end up timing out. It's set at a ridiculous high value to prevent this from happening when a user hits a breakpoint while debugging, and stays stopped for a while, which sometimes results in mirrord not working when they resume.\n\n```json { \"internal_proxy\": { \"socket_timeout\": 31536000 } } ```","type":["integer","null"],"format":"uint64","minimum":0.0},"start_idle_timeout":{"title":"internal_proxy.start_idle_timeout {#internal_proxy-start_idle_timeout}","description":"How much time to wait for the first connection to the proxy in seconds.\n\nCommon cases would be running with dlv or any other debugger, which sets a breakpoint on process execution, delaying the layer startup and connection to proxy.\n\n```json { \"internal_proxy\": { \"start_idle_timeout\": 60 } } ```","type":["integer","null"],"format":"uint64","minimum":0.0}},"additionalProperties":false},"JobTarget":{"type":"object","required":["job"],"properties":{"container":{"type":["string","null"]},"job":{"type":"string"}},"additionalProperties":false},"LinuxCapability":{"type":"string","enum":["SYS_ADMIN","SYS_PTRACE","NET_RAW","NET_ADMIN"]},"LocalHttpsDelivery":{"description":"Stolen HTTPS requests can be delivered to the local application either as HTTPS or as plain HTTP requests. Note that stealing HTTPS requests requires mirrord Operator support.\n\nTo have the stolen HTTPS requests delivered with plain HTTP, use:\n\n```json { \"protocol\": \"tcp\" } ```\n\nTo have the requests delivered with HTTPS, use: ```json { \"protocol\": \"tls\" } ```\n\nBy default, the local mirrord TLS client will trust any certificate presented by the local application's HTTP server. To override this behavior, you can either:\n\n1. Specify a list of paths to trust roots. These paths can lead either to PEM files or PEM file directories. Each found certificate will be used as a trust anchor. 2. Specify a path to the cartificate chain used by the server.\n\nExample with trust roots: ```json { \"protocol\": \"tls\", \"trust_roots\": [\"/path/to/cert.pem\", \"/path/to/cert/dir\"] } ```\n\nExample with certificate chain: ```json { \"protocol\": \"tls\", \"server_cert\": \"/path/to/cert.pem\" } ```\n\nTo make a TLS connection to the local application's HTTPS server, mirrord's TLS client needs a server name. You can supply it manually like this: ```json { \"protocol\": \"tls\", \"server_name\": \"my.test.server.name\" } ```\n\nIf you don't supply the server name:\n\n1. If `server_cert` is given, and the found end-entity certificate contains a valid server name, this server name will be used; 2. Otherwise, if the original client supplied an SNI extension, the server name from that extension will be used; 3. Otherwise, if the stolen request's URL contains a valid server name, that server name will be used; 4. Otherwise, `localhost` will be used.","type":"object","required":["protocol"],"properties":{"protocol":{"title":"feature.network.incoming.https_delivery.protocol {#feature-network-incoming-https_delivery-protocol}","description":"Protocol to use when delivering the HTTPS requests locally.","allOf":[{"$ref":"#/definitions/HttpsDeliveryProtocol"}]},"server_cert":{"description":"Path to a PEM file containing the certificate chain used by the local application's HTTPS server.\n\nThis file must contain at least one certificate. It can contain entries of other types, e.g private keys, which are ignored.","type":["string","null"]},"server_name":{"title":"feature.network.incoming.https_delivery.server_name {#feature-network-incoming-https_delivery-server_name}","description":"Server name to use when making a connection.\n\nMust be a valid DNS name or an IP address.","type":["string","null"]},"trust_roots":{"title":"feature.network.incoming.https_delivery.trust_roots {#feature-network-incoming-https_delivery-trust_roots}","description":"Paths to PEM files and directories with PEM files containing allowed root certificates.\n\nDirectories are not traversed recursively.\n\nEach certificate found in the files is treated as an allowed root. The files can contain entries of other types, e.g private keys, which are ignored.","type":["array","null"],"items":{"type":"string"}}}},"NetworkFileConfig":{"description":"Controls mirrord network operations.\n\nSee the network traffic [reference](https://metalbear.co/mirrord/docs/reference/traffic/) for more details.\n\n```json { \"feature\": { \"network\": { \"incoming\": { \"mode\": \"steal\", \"http_filter\": { \"header_filter\": \"host: api\\\\..+\" }, \"port_mapping\": [[ 7777, 8888 ]], \"ignore_localhost\": false, \"ignore_ports\": [9999, 10000] }, \"outgoing\": { \"tcp\": true, \"udp\": true, \"filter\": { \"local\": [\"tcp://1.1.1.0/24:1337\", \"1.1.5.0/24\", \"google.com\", \":53\"] }, \"ignore_localhost\": false, \"unix_streams\": \"bear.+\" }, \"dns\": { \"enabled\": true, \"filter\": { \"local\": [\"1.1.1.0/24:1337\", \"1.1.5.0/24\", \"google.com\"] } } } } } ```","type":"object","properties":{"dns":{"title":"feature.network.dns {#feature-network-dns}","anyOf":[{"$ref":"#/definitions/ToggleableConfig_for_DnsFileConfig"},{"type":"null"}]},"incoming":{"title":"feature.network.incoming {#feature-network-incoming}","anyOf":[{"$ref":"#/definitions/ToggleableConfig_for_IncomingFileConfig"},{"type":"null"}]},"ipv6":{"title":"feature.network.ipv6 {#feature-network-ipv6}","description":"Enable ipv6 support. Turn on if your application listens to incoming traffic over IPv6, or connects to other services over IPv6.","type":["boolean","null"]},"outgoing":{"title":"feature.network.outgoing {#feature-network-outgoing}","anyOf":[{"$ref":"#/definitions/ToggleableConfig_for_OutgoingFileConfig"},{"type":"null"}]}},"additionalProperties":false},"OutgoingFileConfig":{"description":"Tunnel outgoing network operations through mirrord.\n\nSee the outgoing [reference](https://metalbear.co/mirrord/docs/reference/traffic/#outgoing) for more details.\n\nYou can use either the `remote` or `local` value to turn outgoing traffic tunneling on or off.\n\n```json { \"feature\": { \"network\": { \"outgoing\": \"remote\" } } } ```\n\nAlternatively, you can use more fine-grained configuration. The `remote` and `local` config for this feature are **mutually** exclusive.\n\n```json { \"feature\": { \"network\": { \"outgoing\": { \"tcp\": true, \"udp\": true, \"ignore_localhost\": false, \"filter\": { \"local\": [\"tcp://1.1.1.0/24:1337\", \"1.1.5.0/24\", \"google.com\", \":53\"] }, \"unix_streams\": \"bear.+\" } } } } ```","type":"object","properties":{"filter":{"title":"feature.network.outgoing.filter {#feature.network.outgoing.filter}","description":"Filters that are used to send specific traffic from either the remote pod or the local app","anyOf":[{"$ref":"#/definitions/OutgoingFilterConfig"},{"type":"null"}]},"ignore_localhost":{"title":"feature.network.outgoing.ignore_localhost {#feature.network.outgoing.ignore_localhost}","description":"Defaults to `false`.","type":["boolean","null"]},"tcp":{"title":"feature.network.outgoing.tcp {#feature.network.outgoing.tcp}","description":"Defaults to `true`.","type":["boolean","null"]},"udp":{"title":"feature.network.outgoing.udp {#feature.network.outgoing.udp}","description":"Defaults to `true`.","type":["boolean","null"]},"unix_streams":{"title":"feature.network.outgoing.unix_streams {#feature.network.outgoing.unix_streams}","description":"Connect to these unix streams remotely (and to all other paths locally).\n\nYou can either specify a single value or an array of values. Each value is interpreted as a regular expression ([Supported Syntax](https://docs.rs/regex/1.7.1/regex/index.html#syntax)).\n\nWhen your application connects to a unix socket, the target address will be converted to a string (non-utf8 bytes are replaced by a placeholder character) and matched against the set of regexes specified here. If there is a match, mirrord will connect your application with the target unix socket address on the target pod. Otherwise, it will leave the connection to happen locally on your machine.","anyOf":[{"$ref":"#/definitions/VecOrSingle_for_String"},{"type":"null"}]}},"additionalProperties":false},"OutgoingFilterConfig":{"description":"List of addresses/ports/subnets that should be sent through either the remote pod or local app, depending how you set this up with either `remote` or `local`.\n\nYou may use this option to specify when outgoing traffic is sent from the remote pod (which is the default behavior when you enable outgoing traffic), or from the local app (default when you have outgoing traffic disabled).\n\nTakes a list of values, such as:\n\n- Only UDP traffic on subnet `1.1.1.0/24` on port 1337 will go through the remote pod.\n\n```json { \"remote\": [\"udp://1.1.1.0/24:1337\"] } ```\n\n- Only UDP and TCP traffic on resolved address of `google.com` on port `1337` and `7331` will go through the remote pod. ```json { \"remote\": [\"google.com:1337\", \"google.com:7331\"] } ```\n\n- Only TCP traffic on `localhost` on port 1337 will go through the local app, the rest will be emmited remotely in the cluster.\n\n```json { \"local\": [\"tcp://localhost:1337\"] } ```\n\n- Only outgoing traffic on port `1337` and `7331` will go through the local app. ```json { \"local\": [\":1337\", \":7331\"] } ```\n\nValid values follow this pattern: `[protocol]://[name|address|subnet/mask]:[port]`.","oneOf":[{"description":"Traffic that matches what's specified here will go through the remote pod, everything else will go through local.","type":"object","required":["remote"],"properties":{"remote":{"$ref":"#/definitions/VecOrSingle_for_String"}},"additionalProperties":false},{"description":"Traffic that matches what's specified here will go through the local app, everything else will go through the remote pod.","type":"object","required":["local"],"properties":{"local":{"$ref":"#/definitions/VecOrSingle_for_String"}},"additionalProperties":false}]},"PodTarget":{"description":"<!--${internal}--> Mirror the pod specified by [`PodTarget::pod`].","type":"object","required":["pod"],"properties":{"container":{"type":["string","null"]},"pod":{"description":"<!--${internal}--> Pod to mirror.","type":"string"}},"additionalProperties":false},"PortList":{"description":"<!--${internal}--> Helper struct for setting up ports configuration (part of the HTTP traffic stealer feature).\n\nDefaults to a list of ports `[80, 8080]`.\n\nWe use this to allow implementing a custom [`Default`] initialization, as the [`MirrordConfig`] macro (currently) doesn't support more intricate expressions.","allOf":[{"$ref":"#/definitions/VecOrSingle_for_uint16"}]},"QueueFilter":{"description":"More queue types might be added in the future.","oneOf":[{"description":"Amazon Simple Queue Service.","type":"object","required":["message_filter","queue_type"],"properties":{"message_filter":{"description":"A filter is a mapping between message attribute names and regexes they should match. The local application will only receive messages that match **all** of the given patterns. This means, only messages that have **all** of the attributes in the filter, with values of those attributes matching the respective patterns.","type":"object","additionalProperties":{"type":"string"}},"queue_type":{"type":"string","enum":["SQS"]}}},{"description":"Kafka.","type":"object","required":["message_filter","queue_type"],"properties":{"message_filter":{"description":"A filter is a mapping between message header names and regexes they should match. The local application will only receive messages that match **all** of the given patterns. This means, only messages that have **all** of the headers in the filter, with values of those headers matching the respective patterns.","type":"object","additionalProperties":{"type":"string"}},"queue_type":{"type":"string","enum":["Kafka"]}}}]},"ReplicaSetTarget":{"type":"object","required":["replica_set"],"properties":{"container":{"type":["string","null"]},"replica_set":{"type":"string"}},"additionalProperties":false},"RolloutTarget":{"description":"<!--${internal}--> Mirror the rollout specified by [`RolloutTarget::rollout`].","type":"object","required":["rollout"],"properties":{"container":{"type":["string","null"]},"rollout":{"description":"<!--${internal}--> Rollout to mirror.","type":"string"}},"additionalProperties":false},"ServiceTarget":{"type":"object","required":["service"],"properties":{"container":{"type":["string","null"]},"service":{"type":"string"}},"additionalProperties":false},"SplitQueuesConfig":{"description":"```json { \"feature\": { \"split_queues\": { \"first-queue\": { \"queue_type\": \"SQS\", \"message_filter\": { \"wows\": \"so wows\", \"coolz\": \"^very\" } }, \"second-queue\": { \"queue_type\": \"SQS\", \"message_filter\": { \"who\": \"you$\" } }, \"third-queue\": { \"queue_type\": \"Kafka\", \"message_filter\": { \"who\": \"you$\" } }, \"fourth-queue\": { \"queue_type\": \"Kafka\", \"message_filter\": { \"wows\": \"so wows\", \"coolz\": \"^very\" } }, } } } ```","type":"object","additionalProperties":{"$ref":"#/definitions/QueueFilter"}},"StatefulSetTarget":{"type":"object","required":["stateful_set"],"properties":{"container":{"type":["string","null"]},"stateful_set":{"type":"string"}},"additionalProperties":false},"Target":{"description":"<!--${internal}--> ## path\n\nSpecifies the running pod (or deployment) to mirror.\n\nSupports: - `targetless` - `pod/{pod-name}[/container/{container-name}]`; - `deployment/{deployment-name}[/container/{container-name}]`; - `rollout/{rollout-name}[/container/{container-name}]`; - `job/{job-name}[/container/{container-name}]`; - `cronjob/{cronjob-name}[/container/{container-name}]`; - `statefulset/{statefulset-name}[/container/{container-name}]`; - `service/{service-name}[/container/{container-name}]`; - `replicaset/{replicaset-name}[/container/{container-name}]`;\n\nUsed to derive `TargetType` via the strum crate","anyOf":[{"description":"<!--${internal}--> [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/).","allOf":[{"$ref":"#/definitions/DeploymentTarget"}]},{"description":"<!--${internal}--> [Pod](https://kubernetes.io/docs/concepts/workloads/pods/).","allOf":[{"$ref":"#/definitions/PodTarget"}]},{"description":"<!--${internal}--> [Argo Rollout](https://argoproj.github.io/argo-rollouts/#how-does-it-work).","allOf":[{"$ref":"#/definitions/RolloutTarget"}]},{"description":"<!--${internal}--> [Job](https://kubernetes.io/docs/concepts/workloads/controllers/job/).\n\nOnly supported when `copy_target` is enabled.","allOf":[{"$ref":"#/definitions/JobTarget"}]},{"description":"<!--${internal}--> [CronJob](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/).\n\nOnly supported when `copy_target` is enabled.","allOf":[{"$ref":"#/definitions/CronJobTarget"}]},{"description":"<!--${internal}--> [StatefulSet](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/).","allOf":[{"$ref":"#/definitions/StatefulSetTarget"}]},{"description":"<!--${internal}--> [Service](https://kubernetes.io/docs/concepts/services-networking/service/).","allOf":[{"$ref":"#/definitions/ServiceTarget"}]},{"description":"<!--${internal}--> [ReplicaSet](https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/).","allOf":[{"$ref":"#/definitions/ReplicaSetTarget"}]}]},"TargetFileConfig":{"anyOf":[{"anyOf":[{"$ref":"#/definitions/Target"},{"type":"null"},{"type":"string"}]},{"type":"object","properties":{"namespace":{"type":["string","null"]},"path":{"description":"<!--${internal}--> Path is optional so that it can also be specified via env var instead of via conf file, but it is not optional in a resulting [`TargetConfig`] object - either there is a path, or the target configuration is `None`.","default":null,"anyOf":[{"$ref":"#/definitions/Target"},{"type":"null"}]}},"additionalProperties":false}]},"ToggleableConfig_for_DnsFileConfig":{"anyOf":[{"type":"boolean"},{"$ref":"#/definitions/DnsFileConfig"}]},"ToggleableConfig_for_EnvFileConfig":{"anyOf":[{"type":"boolean"},{"$ref":"#/definitions/EnvFileConfig"}]},"ToggleableConfig_for_FsUserConfig":{"anyOf":[{"type":"boolean"},{"$ref":"#/definitions/FsUserConfig"}]},"ToggleableConfig_for_HttpFilterFileConfig":{"anyOf":[{"type":"boolean"},{"$ref":"#/definitions/HttpFilterFileConfig"}]},"ToggleableConfig_for_IncomingFileConfig":{"anyOf":[{"type":"boolean"},{"$ref":"#/definitions/IncomingFileConfig"}]},"ToggleableConfig_for_NetworkFileConfig":{"anyOf":[{"type":"boolean"},{"$ref":"#/definitions/NetworkFileConfig"}]},"ToggleableConfig_for_OutgoingFileConfig":{"anyOf":[{"type":"boolean"},{"$ref":"#/definitions/OutgoingFileConfig"}]},"VecOrSingle_for_String":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"VecOrSingle_for_uint16":{"anyOf":[{"type":"integer","format":"uint16","minimum":0.0},{"type":"array","items":{"type":"integer","format":"uint16","minimum":0.0}}]},"io.k8s.api.core.v1.ResourceClaim":{"description":"ResourceClaim references one entry in PodSpec.ResourceClaims.","type":"object","required":["name"],"properties":{"name":{"description":"Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container.","type":"string"}}},"io.k8s.api.core.v1.ResourceRequirements":{"description":"ResourceRequirements describes the compute resource requirements.","type":"object","properties":{"claims":{"description":"Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container.\n\nThis is an alpha field and requires enabling the DynamicResourceAllocation feature gate.\n\nThis field is immutable. It can only be set for containers.","type":"array","items":{"$ref":"#/definitions/io.k8s.api.core.v1.ResourceClaim"}},"limits":{"description":"Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/","type":"object","additionalProperties":{"$ref":"#/definitions/io.k8s.apimachinery.pkg.api.resource.Quantity"}},"requests":{"description":"Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/","type":"object","additionalProperties":{"$ref":"#/definitions/io.k8s.apimachinery.pkg.api.resource.Quantity"}}}},"io.k8s.api.core.v1.Toleration":{"description":"The pod this Toleration is attached to tolerates any taint that matches the triple <key,value,effect> using the matching operator <operator>.","type":"object","properties":{"effect":{"description":"Effect indicates the taint effect to match. Empty means match all taint effects. When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute.","type":"string"},"key":{"description":"Key is the taint key that the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists; this combination means to match all values and all keys.","type":"string"},"operator":{"description":"Operator represents a key's relationship to the value. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category.","type":"string"},"tolerationSeconds":{"description":"TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system.","type":"integer","format":"int64"},"value":{"description":"Value is the taint value the toleration matches to. If the operator is Exists, the value should be empty, otherwise just a regular string.","type":"string"}}},"io.k8s.apimachinery.pkg.api.resource.Quantity":{"description":"Quantity is a fixed-point representation of a number. It provides convenient marshaling/unmarshaling in JSON and YAML, in addition to String() and AsInt64() accessors.\n\nThe serialization format is:\n\n``` <quantity>        ::= <signedNumber><suffix>\n\n\t(Note that <suffix> may be empty, from the \"\" case in <decimalSI>.)\n\n<digit>           ::= 0 | 1 | ... | 9 <digits>          ::= <digit> | <digit><digits> <number>          ::= <digits> | <digits>.<digits> | <digits>. | .<digits> <sign>            ::= \"+\" | \"-\" <signedNumber>    ::= <number> | <sign><number> <suffix>          ::= <binarySI> | <decimalExponent> | <decimalSI> <binarySI>        ::= Ki | Mi | Gi | Ti | Pi | Ei\n\n\t(International System of units; See: http://physics.nist.gov/cuu/Units/binary.html)\n\n<decimalSI>       ::= m | \"\" | k | M | G | T | P | E\n\n\t(Note that 1024 = 1Ki but 1000 = 1k; I didn't choose the capitalization.)\n\n<decimalExponent> ::= \"e\" <signedNumber> | \"E\" <signedNumber> ```\n\nNo matter which of the three exponent forms is used, no quantity may represent a number greater than 2^63-1 in magnitude, nor may it have more than 3 decimal places. Numbers larger or more precise will be capped or rounded up. (E.g.: 0.1m will rounded up to 1m.) This may be extended in the future if we require larger or smaller quantities.\n\nWhen a Quantity is parsed from a string, it will remember the type of suffix it had, and will use the same type again when it is serialized.\n\nBefore serializing, Quantity will be put in \"canonical form\". This means that Exponent/suffix will be adjusted up or down (with a corresponding increase or decrease in Mantissa) such that:\n\n- No precision is lost - No fractional digits will be emitted - The exponent (or suffix) is as large as possible.\n\nThe sign will be omitted unless the number is negative.\n\nExamples:\n\n- 1.5 will be serialized as \"1500m\" - 1.5Gi will be serialized as \"1536Mi\"\n\nNote that the quantity will NEVER be internally represented by a floating point number. That is the whole point of this exercise.\n\nNon-canonical values will still parse as long as they are well formed, but will be re-emitted in their canonical form. (So always use canonical form, or don't diff.)\n\nThis format is intended to make it difficult to use these numbers without writing some sort of special handling code in the hopes that that will cause implementors to also use a fixed point implementation.","type":"string"}}}
</schema>

[User] Provide a JSON object that satisfies the schema "LayerFileConfig". Here are the required top‑level fields: none (all optional). Return only the valid JSON object.

LayerFileConfig

mirrord allows for a high degree of customization when it comes to which features you want to enable, and how they should function.

All of the configuration fields have a default value, so a minimal configuration would be no configuration at all.

The configuration supports templating using the [Tera](https://keats.github.io/tera/docs/) template engine. Currently we don't provide additional values to the context, if you have anything you want us to provide please let us know.

To use a configuration file in the CLI, use the `-f <CONFIG_PATH>` flag. Or if using VSCode Extension or JetBrains plugin, simply create a `.mirrord/mirrord.json` file or use the UI.

To help you get started, here are examples of a basic configuration file, and a complete configuration file containing all fields.

### Basic `config.json` {#root-basic}

```json { "target": "pod/bear-pod", "feature": { "env": true, "fs": "read", "network": true } } ```

### Basic `config.json` with templating {#root-basic-templating}

```json { "target": "{{ get_env(name="TARGET", default="pod/fallback") }}", "feature": { "env": true, "fs": "read", "network": true } } ```

### Complete `config.json` {#root-complete}

Don't use this example as a starting point, it's just here to show you all the available options. ```json { "accept_invalid_certificates": false, "skip_processes": "ide-debugger", "target": { "path": "pod/bear-pod", "namespace": "default" }, "connect_tcp": null, "agent": { "log_level": "info", "json_log": false, "labels": { "user": "meow" }, "annotations": { "cats.io/inject": "enabled" }, "namespace": "default", "image": "ghcr.io/metalbear-co/mirrord:latest", "image_pull_policy": "IfNotPresent", "image_pull_secrets": [ { "secret-key": "secret" } ], "ttl": 30, "ephemeral": false, "communication_timeout": 30, "startup_timeout": 360, "network_interface": "eth0", "flush_connections": true, "metrics": "0.0.0.0:9000", }, "feature": { "env": { "include": "DATABASE_USER;PUBLIC_ENV", "exclude": "DATABASE_PASSWORD;SECRET_ENV", "override": { "DATABASE_CONNECTION": "db://localhost:7777/my-db", "LOCAL_BEAR": "panda" }, "mapping": { ".+_TIMEOUT": "1000" } }, "fs": { "mode": "write", "read_write": ".+\\.json" , "read_only": [ ".+\\.yaml", ".+important-file\\.txt" ], "local": [ ".+\\.js", ".+\\.mjs" ] }, "network": { "incoming": { "mode": "steal", "http_filter": { "header_filter": "host: api\\..+" }, "port_mapping": [[ 7777, 8888 ]], "ignore_localhost": false, "ignore_ports": [9999, 10000] }, "outgoing": { "tcp": true, "udp": true, "filter": { "local": ["tcp://1.1.1.0/24:1337", "1.1.5.0/24", "google.com", ":53"] }, "ignore_localhost": false, "unix_streams": "bear.+" }, "dns": { "enabled": true, "filter": { "local": ["1.1.1.0/24:1337", "1.1.5.0/24", "google.com"] } } }, "copy_target": { "scale_down": false } }, "operator": true, "kubeconfig": "~/.kube/config", "sip_binaries": "bash", "telemetry": true, "kube_context": "my-cluster" } ```

# Options {#root-options}

accept_invalid_certificates {#root-accept_invalid_certificates}

Controls whether or not mirrord accepts invalid TLS certificates (e.g. self-signed certificates).

If not provided, mirrord will use value from the kubeconfig.

agent {#root-agent}

container {#root-container}

experimental {#root-experimental}

external_proxy {#root-external_proxy}

feature {#root-feature}

internal_proxy {#root-internal_proxy}

kube_context {#root-kube_context}

Kube context to use from the kubeconfig file. Will use current context if not specified.

```json { "kube_context": "mycluster" } ```

kubeconfig {#root-kubeconfig}

Path to a kubeconfig file, if not specified, will use `KUBECONFIG`, or `~/.kube/config`, or the in-cluster config.

```json { "kubeconfig": "~/bear/kube-config" } ```

operator {#root-operator}

Whether mirrord should use the operator. If not set, mirrord will first attempt to use the operator, but continue without it in case of failure.

profile {#root-profile}

Name of the mirrord profile to use.

To select a cluster-wide profile

```json { "profile": "my-profile-name" } ```

To select a namespaced profile

```json { "profile": "my-namespace/my-profile-name" } ```

sip_binaries {#root-sip_binaries}

Binaries to patch (macOS SIP).

Use this when mirrord isn't loaded to protected binaries that weren't automatically patched.

Runs `endswith` on the binary path (so `bash` would apply to any binary ending with `bash` while `/usr/bin/bash` would apply only for that binary).

```json { "sip_binaries": ["bash", "python"] } ```

skip_build_tools {#root-skip_build_tools}

Allows mirrord to skip build tools. Useful when running command lines that build and run the application in a single command.

Defaults to `true`.

Build-Tools: `["as", "cc", "ld", "go", "air", "asm", "cc1", "cgo", "dlv", "gcc", "git", "link", "math", "cargo", "hpack", "rustc", "compile", "collect2", "cargo-watch", "debugserver"]`

skip_extra_build_tools {#root-skip_build_tools}

Allows mirrord to skip the specified build tools. Useful when running command lines that build and run the application in a single command.

Must also enable [`skip_build_tools`](#root-skip_build_tools) for this to take an effect.

It's similar to [`skip_processes`](#root-skip_processes), except that here it also skips SIP patching.

Accepts a single value, or an array of values.

```json { "skip_extra_build_tools": ["bash", "node"] } ```

skip_processes {#root-skip_processes}

Allows mirrord to skip unwanted processes.

Useful when process A spawns process B, and the user wants mirrord to operate only on process B. Accepts a single value, or an array of values.

```json { "skip_processes": ["bash", "node"] } ```

skip_sip {#root-skip_sip}

Allows mirrord to skip patching (macOS SIP) unwanted processes.

When patching is skipped, mirrord will no longer be able to load into the process and its child processes.

Defaults to `{ "skip_sip": "git" }`

When specified, the given value will replace the default list rather than being added to.

target {#root-target}

telemetry {#root-telemetry}

Controls whether or not mirrord sends telemetry data to MetalBear cloud. Telemetry sent doesn't contain personal identifiers or any data that should be considered sensitive. It is used to improve the product. [For more information](https://github.com/metalbear-co/mirrord/blob/main/TELEMETRY.md)

use_proxy {#root-use_proxy}

When disabled, mirrord will remove `HTTP[S]_PROXY` env variables before doing any network requests. This is useful when the system sets a proxy but you don't want mirrord to use it. This also applies to the mirrord process (as it just removes the env). If the remote pod sets this env, the mirrord process will still use it.

Allows the user to specify the default behavior for file operations:

1. `"read"` or `true` - Read from the remote file system (default) 2. `"write"` - Read/Write from the remote file system. 3. `"local"` or `false` - Read from the local file system. 4. `"localwithoverrides"` - perform fs operation locally, unless the path matches a pre-defined or user-specified exception.

> Note: by default, some paths are read locally or remotely, regardless of the selected FS mode. > This is described in further detail below.

Besides the default behavior, the user can specify behavior for specific regex patterns. Case insensitive.

1. `"read_write"` - List of patterns that should be read/write remotely. 2. `"read_only"` - List of patterns that should be read only remotely. 3. `"local"` - List of patterns that should be read locally. 4. `"not_found"` - List of patters that should never be read nor written. These files should be treated as non-existent. 4. `"mapping"` - Map of patterns and their corresponding replacers. The replacement happens before any specific behavior as defined above or mode (uses [`Regex::replace`](https://docs.rs/regex/latest/regex/struct.Regex.html#method.replace))

The logic for choosing the behavior is as follows:

1. Check agains "mapping" if path needs to be replaced, if matched then continue to next step with new path after replacements otherwise continue as usual. 2. Check if one of the patterns match the file path, do the corresponding action. There's no specified order if two lists match the same path, we will use the first one (and we do not guarantee what is first).

**Warning**: Specifying the same path in two lists is unsupported and can lead to undefined behaviour.

3. There are pre-defined exceptions to the set FS mode. 1. Paths that match [the patterns defined here](https://github.com/metalbear-co/mirrord/tree/latest/mirrord/layer/src/file/filter/read_local_by_default.rs) are read locally by default. 2. Paths that match [the patterns defined here](https://github.com/metalbear-co/mirrord/tree/latest/mirrord/layer/src/file/filter/read_remote_by_default.rs) are read remotely by default when the mode is `localwithoverrides`. 3. Paths that match [the patterns defined here](https://github.com/metalbear-co/mirrord/tree/latest/mirrord/layer/src/file/filter/not_found_by_default.rs) under the running user's home directory will not be found by the application when the mode is not `local`.

In order to override that default setting for a path, or a pattern, include it the appropriate pattern set from above. E.g. in order to read files under `/etc/` remotely even though it is covered by [the set of patterns that are read locally by default](https://github.com/metalbear-co/mirrord/tree/latest/mirrord/layer/src/file/filter/read_local_by_default.rs), add `"^/etc/."` to the `read_only` set.

4. If none of the above match, use the default behavior (mode).

For more information, check the file operations [technical reference](https://metalbear.co/mirrord/docs/reference/fileops/).

```json { "feature": { "fs": { "mode": "write", "read_write": ".+\\.json" , "read_only": [ ".+\\.yaml", ".+important-file\\.txt" ], "local": [ ".+\\.js", ".+\\.mjs" ], "not_found": [ "\\.config/gcloud" ] } } } ```

feature.fs.local {#feature-fs-local}

Specify file path patterns that if matched will be opened locally.

feature.fs.mapping {#feature-fs-mapping}

Specify map of patterns that if matched will replace the path according to specification.

*Capture groups are allowed.*

Example: ```json { "^/home/(?<user>\\S+)/dev/tomcat": "/etc/tomcat" "^/home/(?<user>\\S+)/dev/config/(?<app>\\S+)": "/mnt/configs/${user}-$app" } ``` Will do the next replacements for any io operaton

`/home/johndoe/dev/tomcat/context.xml` => `/etc/tomcat/context.xml` `/home/johndoe/dev/config/api/app.conf` => `/mnt/configs/johndoe-api/app.conf`

- Relative paths: this feature (currently) does not apply mappings to relative paths, e.g. `../dev`.

feature.fs.mode {#feature-fs-mode}

feature.fs.not_found {#feature-fs-not_found}

Specify file path patterns that if matched will be treated as non-existent.

feature.fs.read_only {#feature-fs-read_only}

Specify file path patterns that if matched will be read from the remote. if file matching the pattern is opened for writing or read/write it will be opened locally.

feature.fs.read_write {#feature-fs-read_write}

Specify file path patterns that if matched will be read and written to the remote.

feature.fs.readonly_file_buffer {#feature-fs-readonly_file_buffer}

Sets buffer size for read-only remote files in bytes. By default, the value is 128000 bytes, or 128 kB.

Setting the value to 0 disables file buffering. Otherwise, read-only remote files will be read in chunks and buffered locally. This improves performance when the user application reads data in small portions.

Configuration for the mirrord-agent pod that is spawned in the Kubernetes cluster.

**Note:** this configuration is ignored when using the mirrord Operator. Agent configuration is done by the cluster admin.

We provide sane defaults for this option, so you don't have to set up anything here.

```json { "agent": { "log_level": "info", "json_log": false, "namespace": "default", "image": "ghcr.io/metalbear-co/mirrord:latest", "image_pull_policy": "IfNotPresent", "image_pull_secrets": [ { "secret-key": "secret" } ], "ttl": 30, "ephemeral": false, "communication_timeout": 30, "startup_timeout": 360, "network_interface": "eth0", "flush_connections": false, "exclude_from_mesh": false } } ```

agent.annotations {#agent-annotations}

Allows setting up custom annotations for the agent Job and Pod.

```json { "annotations": { "cats.io/inject": "enabled" "prometheus.io/scrape": "true", "prometheus.io/port": "9000" } } ```

agent.check_out_of_pods {#agent-check_out_of_pods}

Determine if to check whether there is room for agent job in target node. (Not applicable when using ephemeral containers feature)

Can be disabled if the check takes too long and you are sure there is enough resources on each node

agent.communication_timeout {#agent-communication_timeout}

Controls how long the agent lives when there are no connections.

Each connection has its own heartbeat mechanism, so even if the local application has no messages, the agent stays alive until there are no more heartbeat messages.

agent.disabled_capabilities {#agent-disabled_capabilities}

Disables specified Linux capabilities for the agent container. If nothing is disabled here, agent uses `NET_ADMIN`, `NET_RAW`, `SYS_PTRACE` and `SYS_ADMIN`.

Has no effect when using the targetless mode, as targetless agent containers have no capabilities.

agent.dns {#agent-dns}

agent.ephemeral {#agent-ephemeral}

Runs the agent as an [ephemeral container](https://kubernetes.io/docs/concepts/workloads/pods/ephemeral-containers/).

Not compatible with targetless runs.

Defaults to `false`.

agent.exclude_from_mesh {#agent-exclude_from_mesh}

When running the agent as an ephemeral container, use this option to exclude the agent's port from the service mesh sidecar proxy.

agent.flush_connections {#agent-flush_connections}

Flushes existing connections when starting to steal, might fix issues where connections aren't stolen (due to being already established)

Defaults to `true`.

agent.image {#agent-image}

Name of the agent's docker image.

Useful when a custom build of mirrord-agent is required, or when using an internal registry.

Defaults to the latest stable image `"ghcr.io/metalbear-co/mirrord:latest"`.

```json { "image": "internal.repo/images/mirrord:latest" } ```

Complete setup:

```json { "image": { "registry": "internal.repo/images/mirrord", "tag": "latest" } } ```

agent.image_pull_policy {#agent-image_pull_policy}

Controls when a new agent image is downloaded.

Supports `"IfNotPresent"`, `"Always"`, `"Never"`, or any valid kubernetes [image pull policy](https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy)

Defaults to `"IfNotPresent"`

agent.image_pull_secrets {#agent-image_pull_secrets}

List of secrets the agent pod has access to.

Takes an array of entries with the format `{ name: <secret-name> }`.

Read more [here](https://kubernetes.io/docs/concepts/containers/images/#referring-to-an-imagepullsecrets-on-a-pod).

```json { "agent": { "image_pull_secrets": [ { "name": "secret-key-1" }, { "name": "secret-key-2" } ] } } ```

agent.json_log {#agent-json_log}

Controls whether the agent produces logs in a human-friendly format, or json.

```json { "agent": { "json_log": true } } ```

agent.labels {#agent-labels}

Allows setting up custom labels for the agent Job and Pod.

```json { "labels": { "user": "meow", "state": "asleep" } } ```

agent.log_level {#agent-log_level}

Log level for the agent.

Supports `"trace"`, `"debug"`, `"info"`, `"warn"`, `"error"`, or any string that would work with `RUST_LOG`.

```json { "agent": { "log_level": "mirrord=debug,warn" } } ```

agent.metrics {#agent-metrics}

Enables prometheus metrics for the agent pod.

You might need to add annotations to the agent pod depending on how prometheus is configured to scrape for metrics.

```json { "metrics": "0.0.0.0:9000" } ```

agent.namespace {#agent-namespace}

Namespace where the agent shall live.

**Note:** ignored in targetless runs or when the agent is run as an ephemeral container.

Defaults to the current kubernetes namespace.

agent.network_interface {#agent-network_interface}

Which network interface to use for mirroring.

The default behavior is try to access the internet and use that interface. If that fails it uses `eth0`.

agent.nftables {#agent-nftables}

Use iptables-nft instead of iptables-legacy. Defaults to `false`.

Needed if your mesh uses nftables instead of iptables-legacy,

agent.node_selector {#agent-node_selector}

Allows setting up custom node selector for the agent Pod. Applies only to targetless runs, as targeted agent always runs on the same node as its target container.

```json { "node_selector": { "kubernetes.io/hostname": "node1" } } ```

agent.priority_class {#agent-priority_class}

Specifies the priority class to assign to the agent pod.

This option is only applicable when running in the targetless mode.

```json { "priority_class": "my-priority-class-name" } ```

In some cases, the targetless agent pod may fail to schedule due to node resource constraints. Setting a priority class allows you to explicitly assign an existing priority class from your cluster to the agent pod, increasing its priority relative to other workloads.

agent.privileged {#agent-privileged}

Run the mirror agent as privileged container. Defaults to `false`.

Might be needed in strict environments such as Bottlerocket.

Has no effect when using the targetless mode, as targetless agent containers are never privileged.

agent.resources {#agent-resources}

Set pod resource reqirements. (not with ephemeral agents) Default is ```json { "requests": { "cpu": "1m", "memory": "1Mi" }, "limits": { "cpu": "100m", "memory": "100Mi" } } ```

agent.service_account {#agent-service_account}

Allows setting up custom Service Account for the agent Job and Pod.

```json { "service_account": "my-service-account" } ```

agent.startup_timeout {#agent-startup_timeout}

Controls how long to wait for the agent to finish initialization.

If initialization takes longer than this value, mirrord exits.

Defaults to `60`.

agent.tolerations {#agent-tolerations}

Set pod tolerations. (not with ephemeral agents).

Defaults to `operator: Exists`.

```json [ { "key": "meow", "operator": "Exists", "effect": "NoSchedule" } ] ```

Set to an empty array to have no tolerations at all

agent.ttl {#agent-ttl}

Controls how long the agent pod persists for after the agent exits (in seconds).

Can be useful for collecting logs.

Defaults to `1`.

<!--${internal}--> Allows us to support the dual configuration for the agent image.

Whatever values missing are replaced with our defaults.

The shortened version of: `image: "repo/mirrord:latest"`.

Expanded version: `image: { registry: "repo/mirrord", tag: "latest" }`.

<!--${internal}--> Specifies a secret reference for the agent pod.

Name of the secret.

(Operator Only): Allows overriding port locks

Can be set to either `"continue"` or `"override"`.

- `"continue"`: Continue with normal execution - `"override"`: If port lock detected then override it with new lock and force close the original locking connection.

<!--${internal}--> ### override

Override any port lock and force close the original lock connection

<!--${internal}--> ### continue

Continue with normal execution

<!--${internal}--> ### abort

Abort Execution when trying to steal traffic from a target whose traffic is already being stolen.

Unstable: `mirrord container` command specific config.

container.cli_extra_args {#container-cli_extra_args}

Any extra args to use when creating the sidecar mirrord-cli container.

This is useful when you want to use portforwarding, passing `-p local:container` won't work for main command but adding them here will work ```json { "container": { "cli_extra_args": ["-p", "local:container"] } } ```

container.cli_image {#container-cli_image}

Tag of the `mirrord-cli` image you want to use.

Defaults to `"ghcr.io/metalbear-co/mirrord-cli:<cli version>"`.

container.cli_image_lib_path {#container-cli_image}

Path of the mirrord-layer lib inside the specified mirrord-cli image.

Defaults to `"/opt/mirrord/lib/libmirrord_layer.so"`.

container.cli_prevent_cleanup {#container-cli_extra_args}

Don't add `--rm` to sidecar command to prevent cleanup.

container.override_host_ip {#container-override_host_ip}

Allows to override the IP address for the internal proxy to use when connecting to the host machine from within the container.

```json5 { "container": { "override_host_ip": "172.17.0.1" // usual resolution of value from `host.docker.internal` } } ```

This should be useful if your host machine is exposed with a different IP address than the one bound as host.

- If you're running inside WSL, and encountering problems, try setting `external_proxy.host_ip` T `0.0.0.0`, and this to the internal container runtime address (for docker, this  would be what `host.docker.internal` resolved to, which by default is `192.168.65.254`). You can find this ip by resolving it from inside a running container, e.g. `docker run --rm -it {image-with-nslookup} nslookup host.docker.internal`

<!--${internal}--> Mirror the deployment specified by [`DeploymentTarget::deployment`].

<!--${internal}--> Deployment to mirror.

Resolve DNS via the remote pod.

Defaults to `true`.

Mind that: - DNS resolving can be done in multiple ways. Some frameworks use `getaddrinfo`/`gethostbyname` functions, while others communicate directly with the DNS server at port `53` and perform a sort of manual resolution. Just enabling the `dns` feature in mirrord might not be enough. If you see an address resolution error, try enabling the [`fs`](#feature-fs) feature, and setting `read_only: ["/etc/resolv.conf"]`. - DNS filter currently works only with frameworks that use `getaddrinfo`/`gethostbyname` functions.

feature.network.dns.filter {#feature-network-dns-filter}

Unstable: the precise syntax of this config is subject to change.

List of addresses/ports/subnets that should be resolved through either the remote pod or local app, depending how you set this up with either `remote` or `local`.

You may use this option to specify when DNS resolution is done from the remote pod (which is the default behavior when you enable remote DNS), or from the local app (default when you have remote DNS disabled).

Takes a list of values, such as:

- Only queries for hostname `my-service-in-cluster` will go through the remote pod.

```json { "remote": ["my-service-in-cluster"] } ```

- Only queries for addresses in subnet `1.1.1.0/24` with service port `1337`` will go through the remote pod.

```json { "remote": ["1.1.1.0/24:1337"] } ```

- Only queries for hostname `google.com` with service port `1337` or `7331` will go through the remote pod.

```json { "remote": ["google.com:1337", "google.com:7331"] } ```

- Only queries for `localhost` with service port `1337` will go through the local app.

```json { "local": ["localhost:1337"] } ```

- Only queries with service port `1337` or `7331` will go through the local app.

```json { "local": [":1337", ":7331"] } ```

Valid values follow this pattern: `[name|address|subnet/mask][:port]`.

DNS queries matching what is specified here will go through the remote pod, everything else will go through local.

DNS queries matching what is specified here will go through the local app, everything else will go through the remote pod.

Allows the user to set or override the local process' environment variables with the ones from the remote pod.

Can be set to one of the options:

1. `false` - Disables the feature, won't have remote environment variables. 2. `true` - Enables the feature, will obtain remote environment variables. 3. object - see below (means `true` + additional configuration).

Which environment variables to load from the remote pod are controlled by setting either [`include`](#feature-env-include) or [`exclude`](#feature-env-exclude).

See the environment variables [reference](https://metalbear.co/mirrord/docs/reference/env/) for more details.

```json { "feature": { "env": { "include": "DATABASE_USER;PUBLIC_ENV;MY_APP_*", "exclude": "DATABASE_PASSWORD;SECRET_ENV", "override": { "DATABASE_CONNECTION": "db://localhost:7777/my-db", "LOCAL_BEAR": "panda" }, "mapping": { ".+_TIMEOUT": "1000" } } } } ```

feature.env_file {#feature-env-file}

Allows for passing environment variables from an env file.

These variables will override environment fetched from the remote target.

feature.env.exclude {#feature-env-exclude}

Include the remote environment variables in the local process that are **NOT** specified by this option. Variable names can be matched using `*` and `?` where `?` matches exactly one occurrence of any character and `*` matches arbitrary many (including zero) occurrences of any character.

Some of the variables that are excluded by default: `PATH`, `HOME`, `HOMEPATH`, `CLASSPATH`, `JAVA_EXE`, `JAVA_HOME`, `PYTHONPATH`.

Can be passed as a list or as a semicolon-delimited string (e.g. `"VAR;OTHER_VAR"`).

feature.env.include {#feature-env-include}

Include only these remote environment variables in the local process. Variable names can be matched using `*` and `?` where `?` matches exactly one occurrence of any character and `*` matches arbitrary many (including zero) occurrences of any character.

Can be passed as a list or as a semicolon-delimited string (e.g. `"VAR;OTHER_VAR"`).

Some environment variables are excluded by default (`PATH` for example), including these requires specifying them with `include`

feature.env.load_from_process {#feature-env-load_from_process}

Allows for changing the way mirrord loads remote environment variables. If set, the variables are fetched after the user application is started.

This setting is meant to resolve issues when using mirrord via the IntelliJ plugin on WSL and the remote environment contains a lot of variables.

feature.env.mapping {#feature-env-mapping}

Specify map of patterns that if matched will replace the value according to specification.

*Capture groups are allowed.*

Example: ```json { ".+_TIMEOUT": "10000" "LOG_.+_VERBOSITY": "debug" "(\w+)_(\d+)": "magic-value" } ```

Will do the next replacements for environment variables that match:

* `CONNECTION_TIMEOUT: 500` => `CONNECTION_TIMEOUT: 10000`

* `LOG_FILE_VERBOSITY: info` => `LOG_FILE_VERBOSITY: debug`

* `DATA_1234: common-value` => `DATA_1234: magic-value`

feature.env.override {#feature-env-override}

Allows setting or overriding environment variables (locally) with a custom value.

For example, if the remote pod has an environment variable `REGION=1`, but this is an undesirable value, it's possible to use `override` to set `REGION=2` (locally) instead.

Environment specified here will also override variables passed via the env file.

feature.env.unset {#feature-env-unset}

Allows unsetting environment variables in the executed process.

This is useful for when some system/user-defined environment like `AWS_PROFILE` make the application behave as if it's running locally, instead of using the remote settings. The unsetting happens from extension (if possible)/CLI and when process initializes. In some cases, such as Go the env might not be able to be modified from the process itself. This is case insensitive, meaning if you'd put `AWS_PROFILE` it'd unset both `AWS_PROFILE` and `Aws_Profile` and other variations.

mirrord Experimental features. This shouldn't be used unless someone from MetalBear/mirrord tells you to.

_experimental_ browser_extension_config {#experimental-browser_extension_config}

mirrord will either open a URL for initiating mirrord browser extension to automatically inject HTTP header that matches the HTTP filter configured in `feature.network.incoming.http_filter.header_filter`.

_experimental_ disable_reuseaddr {#experimental-disable_reuseaddr}

Disables the `SO_REUSEADDR` socket option on sockets that mirrord steals/mirrors. On macOS the application can use the same address many times but then we don't steal it correctly. This probably should be on by default but we want to gradually roll it out. <https://github.com/metalbear-co/mirrord/issues/2819> This option applies only on macOS.

_experimental_ enable_exec_hooks_linux {#experimental-enable_exec_hooks_linux}

Enables exec hooks on Linux. Enable Linux hooks can fix issues when the application shares sockets with child commands (e.g Python web servers with reload), but the feature is not stable and may cause other issues.

_experimental_ hide_ipv6_interfaces {#experimental-hide_ipv6_interfaces}

Enables `getifaddrs` hook that removes IPv6 interfaces from the list returned by libc.

_experimental_ idle_local_http_connection_timeout {#experimental-idle_local_http_connection_timeout}

Sets a timeout for idle local HTTP connections (in milliseconds).

HTTP requests stolen with a filter are delivered to the local application from a HTTP connection made from the local machine. Once a request is delivered, the connection is cached for some time, so that it can be reused to deliver the next request.

This timeout determines for how long such connections are cached.

Set to 0 to disable caching local HTTP connections (connections will be dropped as soon as the request is delivered).

Defaults to 3000ms.

_experimental_ ignore_system_proxy_config {#experimental-ignore_system_proxy_config}

Disables any system wide proxy configuration for affecting the running application.

_experimental_ readlink {#experimental-readlink}

DEPRECATED, WILL BE REMOVED

_experimental_ readonly_file_buffer {#experimental-readonly_file_buffer}

DEPRECATED, WILL BE REMOVED: moved to `feature.fs.readonly_file_buffer` as part of stabilisation. See <https://github.com/metalbear-co/mirrord/issues/2069>.

_experimental_ tcp_ping4_mock {#experimental-tcp_ping4_mock}

_experimental_ trust_any_certificate {#experimental-trust_any_certificate}

Enables trusting any certificate on macOS, useful for <https://github.com/golang/go/issues/51991#issuecomment-2059588252>

_experimental_ use_dev_null {#experimental-use_dev_null}

Uses /dev/null for creating local fake files (should be better than using /tmp)

Configuration for the external proxy mirrord spawns when using the `mirrord container` command. This proxy is used to allow the internal proxy running in sidecar to connect to the mirrord agent.

If you get `ConnectionRefused` errors, increasing the timeouts a bit might solve the issue.

```json { "external_proxy": { "start_idle_timeout": 30, "idle_timeout": 5 } } ```

external_proxy.host_ip {#external_proxy-host_ip}

Specify a custom host ip addr to listen on.

This address must be accessible from within the container. If not specified, mirrord will try and resolve a local address to use.

- If you're running inside WSL, and encountering problems, try setting this to `0.0.0.0`, and `container.override_host_ip` to the internal container runtime address (for docker, this would be what `host.docker.internal` resolved to, which by default is `192.168.65.254`).

external_proxy.idle_timeout {#external_proxy-idle_timeout}

How much time to wait while we don't have any active connections before exiting.

Common cases would be running a chain of processes that skip using the layer and don't connect to the proxy.

```json { "external_proxy": { "idle_timeout": 30 } } ```

external_proxy.json_log {#external_proxy-json_log}

Whether the proxy should output logs in JSON format. If false, logs are output in human-readable format.

Defaults to true.

external_proxy.log_destination {#external_proxy-log_destination}

Set the log file destination for the external proxy.

Defaults to a randomized path inside the temporary directory.

external_proxy.log_level {#external_proxy-log_level}

Set the log level for the external proxy.

The value should follow the RUST_LOG convention (i.e `mirrord=trace`).

Defaults to `mirrord=info,warn`.

external_proxy.start_idle_timeout {#external_proxy-start_idle_timeout}

How much time to wait for the first connection to the external proxy in seconds.

Common cases would be running with dlv or any other debugger, which sets a breakpoint on process execution, delaying the layer startup and connection to the external proxy.

```json { "external_proxy": { "start_idle_timeout": 60 } } ```

<!--${internal}-->

Whether to use TLS or a plain TCP when accepting a connection from the internal proxy sidecar.

Controls mirrord features.

See the [technical reference, Technical Reference](https://metalbear.co/mirrord/docs/reference/) to learn more about what each feature does.

The [`env`](#feature-env), [`fs`](#feature-fs) and [`network`](#feature-network) options have support for a shortened version, that you can see [here](#root-shortened).

```json { "feature": { "env": { "include": "DATABASE_USER;PUBLIC_ENV", "exclude": "DATABASE_PASSWORD;SECRET_ENV", "override": { "DATABASE_CONNECTION": "db://localhost:7777/my-db", "LOCAL_BEAR": "panda" } }, "fs": { "mode": "write", "read_write": ".+\\.json" , "read_only": [ ".+\\.yaml", ".+important-file\\.txt" ], "local": [ ".+\\.js", ".+\\.mjs" ] }, "network": { "incoming": { "mode": "steal", "http_filter": { "header_filter": "host: api\\..+" }, "port_mapping": [[ 7777, 8888 ]], "ignore_localhost": false, "ignore_ports": [9999, 10000] }, "outgoing": { "tcp": true, "udp": true, "filter": { "local": ["tcp://1.1.1.0/24:1337", "1.1.5.0/24", "google.com", ":53"] }, "ignore_localhost": false, "unix_streams": "bear.+" }, "dns": false }, "copy_target": false, "hostname": true } } ```

feature.copy_target {#feature-copy_target}

Creates a new copy of the target. mirrord will use this copy instead of the original target (e.g. intercept network traffic). This feature requires a [mirrord operator](https://metalbear.co/mirrord/docs/overview/teams/?utm_source=copytarget).

This feature is not compatible with rollout targets and running without a target (`targetless` mode).

feature.env {#feature-env}

feature.fs {#feature-fs}

feature.hostname {#feature-hostname}

Should mirrord return the hostname of the target pod when calling `gethostname`

feature.network {#feature-network}

feature.split_queues {#feature-split_queues}

Define filters to split queues by, and make your local application consume only messages that match those filters. If you don't specify any filter for a queue that is however declared in the `MirrordWorkloadQueueRegistry` of the target you're using, a match-nothing filter will be used, and your local application will not receive any messages from that queue.

agent.dns.attempts {#agent-dns-attempts}

When agent resolves DNS, how many attempts before failing. If the value is too high, it might cause internal proxy to timeout and exit.

agent.dns.timeout {#agent-dns-timeout}

When agent resolves DNS, how long to wait for a response before timeout By default this is set to 1 (in the agent). If the value is too high, it might cause internal proxy to timeout and exit.

Configuration for enabling read-only or read-write file operations.

These options are overriden by user specified overrides and mirrord default overrides.

If you set [`"localwithoverrides"`](#feature-fs-mode-localwithoverrides) then some files can be read/write remotely based on our default/user specified. Default option for general file configuration.

The accepted values are: `"local"`, `"localwithoverrides`, `"read"`, or `"write`.

feature.fs.mode.local {#feature-fs-mode-local}

mirrord won't do anything fs-related, all operations will be local.

feature.fs.mode.localwithoverrides {#feature-fs-mode-localwithoverrides}

mirrord will run overrides on some file operations, but most will be local.

feature.fs.mode.read {#feature-fs-mode-read}

mirrord will read files from the remote, but won't write to them.

feature.fs.mode.write {#feature-fs-mode-write}

mirrord will read/write from the remote.

feature.fs {#fs}

Changes file operations behavior based on user configuration.

See the file operations [reference](https://metalbear.co/mirrord/docs/reference/fileops/) for more details, and [fs advanced](#fs-advanced) for more information on how to fully setup mirrord file operations.

### Minimal `fs` config {#fs-minimal}

```json { "feature": { "fs": "read" } } ```

### Advanced `fs` config {#fs-advanced}

```json { "feature": { "fs": { "mode": "write", "read_write": ".+\\.json" , "read_only": [ ".+\\.yaml", ".+important-file\\.txt" ], "local": [ ".+\\.js", ".+\\.mjs" ] } } } ```

<!--${internal}--> Basic configuration that controls the env vars `MIRRORD_FILE_OPS` and `MIRRORD_FILE_RO_OPS` (default).

<!--${internal}--> Allows the user to specify both [`FsModeConfig`] (as above), and configuration for the overrides.

Filter configuration for the HTTP traffic stealer feature.

Allows the user to set a filter (regex) for the HTTP headers, so that the stealer traffic feature only captures HTTP requests that match the specified filter, forwarding unmatched requests to their original destinations.

Only does something when [`feature.network.incoming.mode`](#feature-network-incoming-mode) is set as `"steal"`, ignored otherwise.

For example, to filter based on header: ```json { "header_filter": "host: api\\..+" } ``` Setting that filter will make mirrord only steal requests with the `host` header set to hosts that start with "api", followed by a dot, and then at least one more character.

For example, to filter based on path: ```json { "path_filter": "^/api/" } ``` Setting this filter will make mirrord only steal requests to URIs starting with "/api/".

This can be useful for filtering out Kubernetes liveness, readiness and startup probes. For example, for avoiding stealing any probe sent by kubernetes, you can set this filter: ```json { "header_filter": "^User-Agent: (?!kube-probe)" } ``` Setting this filter will make mirrord only steal requests that **do** have a user agent that **does not** begin with "kube-probe".

Similarly, you can exclude certain paths using a negative look-ahead: ```json { "path_filter": "^(?!/health/)" } ``` Setting this filter will make mirrord only steal requests to URIs that do not start with "/health/".

With `all_of` and `any_of`, you can use multiple HTTP filters at the same time.

If you want to steal HTTP requests that match **every** pattern specified, use `all_of`. For example, this filter steals only HTTP requests to endpoint `/api/my-endpoint` that contain header `x-debug-session` with value `121212`. ```json { "all_of": [ { "header": "^x-debug-session: 121212$" }, { "path": "^/api/my-endpoint$" } ] } ```

If you want to steal HTTP requests that match **any** of the patterns specified, use `any_of`. For example, this filter steals HTTP requests to endpoint `/api/my-endpoint` **and** HTTP requests that contain header `x-debug-session` with value `121212`. ```json { "any_of": [ { "path": "^/api/my-endpoint$"}, { "header": "^x-debug-session: 121212$" } ] } ```

feature.network.incoming.http_filter.all_of {#feature-network-incoming-http_filter-all_of}

An array of HTTP filters.

Each inner filter specifies either header or path regex. Requests must match all of the filters to be stolen.

Cannot be an empty list.

Example: ```json { "all_of": [ { "header": "x-user: my-user$" }, { "path": "^/api/v1/my-endpoint" } ] } ```

feature.network.incoming.http_filter.any_of {#feature-network-incoming-http_filter-any_of}

An array of HTTP filters.

Each inner filter specifies either header or path regex. Requests must match at least one of the filters to be stolen.

Cannot be an empty list.

Example: ```json { "any_of": [ { "header": "^x-user: my-user$" }, { "path": "^/api/v1/my-endpoint" } ] } ```

feature.network.incoming.http_filter.header_filter {#feature-network-incoming-http-header-filter}

Supports regexes validated by the [`fancy-regex`](https://docs.rs/fancy-regex/latest/fancy_regex/) crate.

The HTTP traffic feature converts the HTTP headers to `HeaderKey: HeaderValue`, case-insensitive.

feature.network.incoming.http_filter.path_filter {#feature-network-incoming-http-path-filter}

Supports regexes validated by the [`fancy-regex`](https://docs.rs/fancy-regex/latest/fancy_regex/) crate.

Case-insensitive. Tries to find match in the path (without query) and path+query. If any of the two matches, the request is stolen.

feature.network.incoming.http_filter.ports {#feature-network-incoming-http_filter-ports}

Activate the HTTP traffic filter only for these ports.

Other ports will *not* be stolen, unless listed in [`feature.network.incoming.ports`](#feature-network-incoming-ports).

We check the pod's health probe ports and automatically add them here, as they're usually the same ports your app might be listening on. If your app ports and the health probe ports don't match, then setting this option will override this behavior.

Set to [80, 8080] by default.

HTTPS requests will be delivered over TCP, as plain HTTP.

HTTPS requests will be delivered over TLS, as HTTPS.

incoming (advanced setup)

Advanced user configuration for network incoming traffic.

HTTP Filter

Sets up the HTTP traffic filter (currently, only useful when `incoming: steal`).

See [`filter`](##filter) for details.

https_delivery

(Operator Only): configures how mirrord delivers stolen HTTPS requests to the local application.

ignore_localhost

Consider removing when adding <https://github.com/metalbear-co/mirrord/issues/702>

ignore_ports

Ports to ignore when mirroring/stealing traffic. Useful if you want specific ports to be used locally only.

Mutually exclusive with [`ports`](###ports).

listen_ports

Mapping for local ports to actually used local ports. When application listens on a port while steal/mirror is active we fallback to random ports to avoid port conflicts. Using this configuration will always use the specified port. If this configuration doesn't exist, mirrord will try to listen on the original port and if it fails it will assign a random port

This is useful when you want to access ports exposed by your service locally For example, if you have a service that listens on port `80` and you want to access it, you probably can't listen on `80` without sudo, so you can use `[[80, 4480]]` then access it on `4480` while getting traffic from remote `80`. The value of `port_mapping` doesn't affect this.

mode

Allows selecting between mirrorring or stealing traffic.

See [`mode`](##mode (incoming)) for details.

on_concurrent_steal

(Operator Only): if value of override will force close any other connections on requested target

port_mapping

Mapping for local ports to remote ports.

This is useful when you want to mirror/steal a port to a different port on the remote machine. For example, your local process listens on port `9333` and the container listens on port `80`. You'd use `[[9333, 80]]`

ports

List of ports to mirror/steal traffic from. Other ports will remain local.

Mutually exclusive with [`ignore_ports`](###ignore_ports).

incoming (network)

Controls the incoming TCP traffic feature.

See the incoming [reference](https://metalbear.co/mirrord/docs/reference/traffic/#incoming) for more details.

Incoming traffic supports 2 modes of operation:

1. Mirror (**default**): Sniffs the TCP data from a port, and forwards a copy to the interested listeners;

2. Steal: Captures the TCP data from a port, and forwards it to the local process, see [`steal`](##steal);

### Minimal `incoming` config

```json { "feature": { "network": { "incoming": "steal" } } } ```

### Advanced `incoming` config

```json { "feature": { "network": { "incoming": { "mode": "steal", "http_filter": { "header_filter": "host: api\\..+" }, "port_mapping": [[ 7777, 8888 ]], "ignore_localhost": false, "ignore_ports": [9999, 10000], "listen_ports": [[80, 8111]] } } } } ```

Allows selecting between mirrorring or stealing traffic.

Can be set to either `"mirror"` (default), `"steal"` or `"off"`.

- `"mirror"`: Sniffs on TCP port, and send a copy of the data to listeners. - `"off"`: Disables the incoming network feature. - `"steal"`: Supports 2 modes of operation:

1. Port traffic stealing: Steals all TCP data from a port, which is selected whenever the user listens in a TCP socket (enabling the feature is enough to make this work, no additional configuration is needed);

2. HTTP traffic stealing: Steals only HTTP traffic, mirrord tries to detect if the incoming data on a port is HTTP (in a best-effort kind of way, not guaranteed to be HTTP), and steals the traffic on the port if it is HTTP;

<!--${internal}--> ### mirror

Sniffs on TCP port, and send a copy of the data to listeners.

<!--${internal}--> ### steal

Stealer supports 2 modes of operation:

1. Port traffic stealing: Steals all TCP data from a port, which is selected whenever the user listens in a TCP socket (enabling the feature is enough to make this work, no additional configuration is needed);

2. HTTP traffic stealing: Steals only HTTP traffic, mirrord tries to detect if the incoming data on a port is HTTP (in a best-effort kind of way, not guaranteed to be HTTP), and steals the traffic on the port if it is HTTP;

<!--${internal}--> ### Off

Disables the incoming network feature.

feature.network.incoming.inner_filter.header_filter {#feature-network-incoming-inner-header-filter}

Supports regexes validated by the [`fancy-regex`](https://docs.rs/fancy-regex/latest/fancy_regex/) crate.

The HTTP traffic feature converts the HTTP headers to `HeaderKey: HeaderValue`, case-insensitive.

feature.network.incoming.inner_filter.path_filter {#feature-network-incoming-inner-path-filter}

Supports regexes validated by the [`fancy-regex`](https://docs.rs/fancy-regex/latest/fancy_regex/) crate.

Case-insensitive. Tries to find match in the path (without query) and path+query. If any of the two matches, the request is stolen.

Configuration for the internal proxy mirrord spawns for each local mirrord session that local layers use to connect to the remote agent

This is seldom used, but if you get `ConnectionRefused` errors, you might want to increase the timeouts a bit.

```json { "internal_proxy": { "start_idle_timeout": 30, "idle_timeout": 5 } } ```

internal_proxy.idle_timeout {#internal_proxy-idle_timeout}

How much time to wait while we don't have any active connections before exiting.

Common cases would be running a chain of processes that skip using the layer and don't connect to the proxy.

```json { "internal_proxy": { "idle_timeout": 30 } } ```

internal_proxy.json_log {#internal_proxy-json_log}

Whether the proxy should output logs in JSON format. If false, logs are output in human-readable format.

Defaults to true.

internal_proxy.log_destination {#internal_proxy-log_destination}

Set the log file destination for the internal proxy.

Defaults to a randomized path inside the temporary directory.

internal_proxy.log_level {#internal_proxy-log_level}

Set the log level for the internal proxy.

The value should follow the RUST_LOG convention (i.e `mirrord=trace`).

Defaults to `mirrord=info,warn`.

<!--${internal}-->

Sometimes the cpu is too busy with other tasks and the internal proxy sockets end up timing out. It's set at a ridiculous high value to prevent this from happening when a user hits a breakpoint while debugging, and stays stopped for a while, which sometimes results in mirrord not working when they resume.

```json { "internal_proxy": { "socket_timeout": 31536000 } } ```

internal_proxy.start_idle_timeout {#internal_proxy-start_idle_timeout}

How much time to wait for the first connection to the proxy in seconds.

Common cases would be running with dlv or any other debugger, which sets a breakpoint on process execution, delaying the layer startup and connection to proxy.

```json { "internal_proxy": { "start_idle_timeout": 60 } } ```

Stolen HTTPS requests can be delivered to the local application either as HTTPS or as plain HTTP requests. Note that stealing HTTPS requests requires mirrord Operator support.

To have the stolen HTTPS requests delivered with plain HTTP, use:

```json { "protocol": "tcp" } ```

To have the requests delivered with HTTPS, use: ```json { "protocol": "tls" } ```

By default, the local mirrord TLS client will trust any certificate presented by the local application's HTTP server. To override this behavior, you can either:

1. Specify a list of paths to trust roots. These paths can lead either to PEM files or PEM file directories. Each found certificate will be used as a trust anchor. 2. Specify a path to the cartificate chain used by the server.

Example with trust roots: ```json { "protocol": "tls", "trust_roots": ["/path/to/cert.pem", "/path/to/cert/dir"] } ```

Example with certificate chain: ```json { "protocol": "tls", "server_cert": "/path/to/cert.pem" } ```

To make a TLS connection to the local application's HTTPS server, mirrord's TLS client needs a server name. You can supply it manually like this: ```json { "protocol": "tls", "server_name": "my.test.server.name" } ```

If you don't supply the server name:

1. If `server_cert` is given, and the found end-entity certificate contains a valid server name, this server name will be used; 2. Otherwise, if the original client supplied an SNI extension, the server name from that extension will be used; 3. Otherwise, if the stolen request's URL contains a valid server name, that server name will be used; 4. Otherwise, `localhost` will be used.

feature.network.incoming.https_delivery.protocol {#feature-network-incoming-https_delivery-protocol}

Protocol to use when delivering the HTTPS requests locally.

Path to a PEM file containing the certificate chain used by the local application's HTTPS server.

This file must contain at least one certificate. It can contain entries of other types, e.g private keys, which are ignored.

feature.network.incoming.https_delivery.server_name {#feature-network-incoming-https_delivery-server_name}

Server name to use when making a connection.

Must be a valid DNS name or an IP address.

feature.network.incoming.https_delivery.trust_roots {#feature-network-incoming-https_delivery-trust_roots}

Paths to PEM files and directories with PEM files containing allowed root certificates.

Directories are not traversed recursively.

Each certificate found in the files is treated as an allowed root. The files can contain entries of other types, e.g private keys, which are ignored.

Controls mirrord network operations.

See the network traffic [reference](https://metalbear.co/mirrord/docs/reference/traffic/) for more details.

```json { "feature": { "network": { "incoming": { "mode": "steal", "http_filter": { "header_filter": "host: api\\..+" }, "port_mapping": [[ 7777, 8888 ]], "ignore_localhost": false, "ignore_ports": [9999, 10000] }, "outgoing": { "tcp": true, "udp": true, "filter": { "local": ["tcp://1.1.1.0/24:1337", "1.1.5.0/24", "google.com", ":53"] }, "ignore_localhost": false, "unix_streams": "bear.+" }, "dns": { "enabled": true, "filter": { "local": ["1.1.1.0/24:1337", "1.1.5.0/24", "google.com"] } } } } } ```

feature.network.dns {#feature-network-dns}

feature.network.incoming {#feature-network-incoming}

feature.network.ipv6 {#feature-network-ipv6}

Enable ipv6 support. Turn on if your application listens to incoming traffic over IPv6, or connects to other services over IPv6.

feature.network.outgoing {#feature-network-outgoing}

Tunnel outgoing network operations through mirrord.

See the outgoing [reference](https://metalbear.co/mirrord/docs/reference/traffic/#outgoing) for more details.

You can use either the `remote` or `local` value to turn outgoing traffic tunneling on or off.

```json { "feature": { "network": { "outgoing": "remote" } } } ```

Alternatively, you can use more fine-grained configuration. The `remote` and `local` config for this feature are **mutually** exclusive.

```json { "feature": { "network": { "outgoing": { "tcp": true, "udp": true, "ignore_localhost": false, "filter": { "local": ["tcp://1.1.1.0/24:1337", "1.1.5.0/24", "google.com", ":53"] }, "unix_streams": "bear.+" } } } } ```

feature.network.outgoing.filter {#feature.network.outgoing.filter}

Filters that are used to send specific traffic from either the remote pod or the local app

feature.network.outgoing.ignore_localhost {#feature.network.outgoing.ignore_localhost}

Defaults to `false`.

feature.network.outgoing.tcp {#feature.network.outgoing.tcp}

Defaults to `true`.

feature.network.outgoing.udp {#feature.network.outgoing.udp}

Defaults to `true`.

feature.network.outgoing.unix_streams {#feature.network.outgoing.unix_streams}

Connect to these unix streams remotely (and to all other paths locally).

You can either specify a single value or an array of values. Each value is interpreted as a regular expression ([Supported Syntax](https://docs.rs/regex/1.7.1/regex/index.html#syntax)).

When your application connects to a unix socket, the target address will be converted to a string (non-utf8 bytes are replaced by a placeholder character) and matched against the set of regexes specified here. If there is a match, mirrord will connect your application with the target unix socket address on the target pod. Otherwise, it will leave the connection to happen locally on your machine.

List of addresses/ports/subnets that should be sent through either the remote pod or local app, depending how you set this up with either `remote` or `local`.

You may use this option to specify when outgoing traffic is sent from the remote pod (which is the default behavior when you enable outgoing traffic), or from the local app (default when you have outgoing traffic disabled).

Takes a list of values, such as:

- Only UDP traffic on subnet `1.1.1.0/24` on port 1337 will go through the remote pod.

```json { "remote": ["udp://1.1.1.0/24:1337"] } ```

- Only UDP and TCP traffic on resolved address of `google.com` on port `1337` and `7331` will go through the remote pod. ```json { "remote": ["google.com:1337", "google.com:7331"] } ```

- Only TCP traffic on `localhost` on port 1337 will go through the local app, the rest will be emmited remotely in the cluster.

```json { "local": ["tcp://localhost:1337"] } ```

- Only outgoing traffic on port `1337` and `7331` will go through the local app. ```json { "local": [":1337", ":7331"] } ```

Valid values follow this pattern: `[protocol]://[name|address|subnet/mask]:[port]`.

Traffic that matches what's specified here will go through the remote pod, everything else will go through local.

Traffic that matches what's specified here will go through the local app, everything else will go through the remote pod.

<!--${internal}--> Mirror the pod specified by [`PodTarget::pod`].

<!--${internal}--> Pod to mirror.

<!--${internal}--> Helper struct for setting up ports configuration (part of the HTTP traffic stealer feature).

Defaults to a list of ports `[80, 8080]`.

We use this to allow implementing a custom [`Default`] initialization, as the [`MirrordConfig`] macro (currently) doesn't support more intricate expressions.

More queue types might be added in the future.

Amazon Simple Queue Service.

A filter is a mapping between message attribute names and regexes they should match. The local application will only receive messages that match **all** of the given patterns. This means, only messages that have **all** of the attributes in the filter, with values of those attributes matching the respective patterns.

Kafka.

A filter is a mapping between message header names and regexes they should match. The local application will only receive messages that match **all** of the given patterns. This means, only messages that have **all** of the headers in the filter, with values of those headers matching the respective patterns.

<!--${internal}--> Mirror the rollout specified by [`RolloutTarget::rollout`].

<!--${internal}--> Rollout to mirror.

```json { "feature": { "split_queues": { "first-queue": { "queue_type": "SQS", "message_filter": { "wows": "so wows", "coolz": "^very" } }, "second-queue": { "queue_type": "SQS", "message_filter": { "who": "you$" } }, "third-queue": { "queue_type": "Kafka", "message_filter": { "who": "you$" } }, "fourth-queue": { "queue_type": "Kafka", "message_filter": { "wows": "so wows", "coolz": "^very" } }, } } } ```

<!--${internal}--> ## path

Specifies the running pod (or deployment) to mirror.

Supports: - `targetless` - `pod/{pod-name}[/container/{container-name}]`; - `deployment/{deployment-name}[/container/{container-name}]`; - `rollout/{rollout-name}[/container/{container-name}]`; - `job/{job-name}[/container/{container-name}]`; - `cronjob/{cronjob-name}[/container/{container-name}]`; - `statefulset/{statefulset-name}[/container/{container-name}]`; - `service/{service-name}[/container/{container-name}]`; - `replicaset/{replicaset-name}[/container/{container-name}]`;

Used to derive `TargetType` via the strum crate

<!--${internal}--> [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/).

<!--${internal}--> [Pod](https://kubernetes.io/docs/concepts/workloads/pods/).

<!--${internal}--> [Argo Rollout](https://argoproj.github.io/argo-rollouts/#how-does-it-work).

<!--${internal}--> [Job](https://kubernetes.io/docs/concepts/workloads/controllers/job/).

Only supported when `copy_target` is enabled.

<!--${internal}--> [CronJob](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/).

Only supported when `copy_target` is enabled.

<!--${internal}--> [StatefulSet](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/).

<!--${internal}--> [Service](https://kubernetes.io/docs/concepts/services-networking/service/).

<!--${internal}--> [ReplicaSet](https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/).

<!--${internal}--> Path is optional so that it can also be specified via env var instead of via conf file, but it is not optional in a resulting [`TargetConfig`] object - either there is a path, or the target configuration is `None`.

ResourceClaim references one entry in PodSpec.ResourceClaims.

Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container.

ResourceRequirements describes the compute resource requirements.

Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container.

This is an alpha field and requires enabling the DynamicResourceAllocation feature gate.

This field is immutable. It can only be set for containers.

Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

The pod this Toleration is attached to tolerates any taint that matches the triple <key,value,effect> using the matching operator <operator>.

Effect indicates the taint effect to match. Empty means match all taint effects. When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute.

Key is the taint key that the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists; this combination means to match all values and all keys.

Operator represents a key's relationship to the value. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category.

TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system.

Value is the taint value the toleration matches to. If the operator is Exists, the value should be empty, otherwise just a regular string.

Quantity is a fixed-point representation of a number. It provides convenient marshaling/unmarshaling in JSON and YAML, in addition to String() and AsInt64() accessors.

The serialization format is:

``` <quantity>        ::= <signedNumber><suffix>

	(Note that <suffix> may be empty, from the "" case in <decimalSI>.)

<digit>           ::= 0 | 1 | ... | 9 <digits>          ::= <digit> | <digit><digits> <number>          ::= <digits> | <digits>.<digits> | <digits>. | .<digits> <sign>            ::= "+" | "-" <signedNumber>    ::= <number> | <sign><number> <suffix>          ::= <binarySI> | <decimalExponent> | <decimalSI> <binarySI>        ::= Ki | Mi | Gi | Ti | Pi | Ei

	(International System of units; See: http://physics.nist.gov/cuu/Units/binary.html)

<decimalSI>       ::= m | "" | k | M | G | T | P | E

	(Note that 1024 = 1Ki but 1000 = 1k; I didn't choose the capitalization.)

<decimalExponent> ::= "e" <signedNumber> | "E" <signedNumber> ```

No matter which of the three exponent forms is used, no quantity may represent a number greater than 2^63-1 in magnitude, nor may it have more than 3 decimal places. Numbers larger or more precise will be capped or rounded up. (E.g.: 0.1m will rounded up to 1m.) This may be extended in the future if we require larger or smaller quantities.

When a Quantity is parsed from a string, it will remember the type of suffix it had, and will use the same type again when it is serialized.

Before serializing, Quantity will be put in "canonical form". This means that Exponent/suffix will be adjusted up or down (with a corresponding increase or decrease in Mantissa) such that:

- No precision is lost - No fractional digits will be emitted - The exponent (or suffix) is as large as possible.

The sign will be omitted unless the number is negative.

Examples:

- 1.5 will be serialized as "1500m" - 1.5Gi will be serialized as "1536Mi"

Note that the quantity will NEVER be internally represented by a floating point number. That is the whole point of this exercise.

Non-canonical values will still parse as long as they are well formed, but will be re-emitted in their canonical form. (So always use canonical form, or don't diff.)

This format is intended to make it difficult to use these numbers without writing some sort of special handling code in the hopes that that will cause implementors to also use a fixed point implementation.

Provide a JSON object that satisfies the schema "LayerFileConfig". Here are the required top‑level fields: none (all optional). Return only the valid JSON object.