Skip to Content
ReferenceConfiguration

Configuration

iron-proxy is configured via a single YAML file, passed at startup with the -config flag:

iron-proxy -config /etc/iron-proxy/proxy.yaml

Below is a complete reference for every configuration option.

Full Example

dns: listen: ":53" proxy_ip: "172.20.0.2" upstream_resolver: "8.8.8.8:53" passthrough: - "*.internal.corp" records: - name: "custom.local" type: A value: "10.0.0.5" proxy: http_listen: ":80" https_listen: ":443" tunnel_listen: ":1080" max_request_body_bytes: 1048576 max_response_body_bytes: 0 tls: mode: "mitm" ca_cert: "/certs/ca.crt" ca_key: "/certs/ca.key" cert_cache_size: 1000 leaf_cert_expiry_hours: 72 transforms: - name: allowlist config: domains: - "registry.npmjs.org" cidrs: - "10.0.0.0/8" rules: - host: "api.openai.com" methods: ["POST"] paths: ["/v1/*"] - host: "*.anthropic.com" methods: ["POST"] paths: ["/v1/messages", "/v1/complete"] - name: secrets config: secrets: - source: type: env var: OPENAI_API_KEY inject: header: "Authorization" formatter: "Bearer {{ .Value }}" rules: - host: "api.openai.com" methods: ["POST"] paths: ["/v1/*"] - source: type: aws_sm secret_id: "arn:aws:secretsmanager:us-west-1:123456789:secret:anthropic-key" region: "us-west-1" ttl: 5m replace: proxy_value: "pk-proxy-anthropic-xyz" match_headers: ["x-api-key"] require: true rules: - host: "api.anthropic.com" - source: type: aws_ssm name: "/myapp/openai-key" region: "us-east-1" ttl: 15m replace: proxy_value: "pk-proxy-openai-param" match_headers: ["Authorization"] rules: - host: "api.openai.com" - name: annotate config: annotations: - rules: - host: "api.openai.com" methods: ["POST"] paths: ["/v1/*"] headers: ["x-request-id"] - name: grpc config: name: "policy-engine" target: "localhost:9500" send_request_body: true send_response_body: true rules: - host: "api.openai.com" methods: ["POST"] paths: ["/v1/*"] tls: enabled: true ca_cert: "/etc/iron-proxy/grpc-ca.pem" cert: "/etc/iron-proxy/grpc-client.pem" key: "/etc/iron-proxy/grpc-client-key.pem" metrics: listen: ":9090" log: level: "info"

dns

Configures the built-in DNS server. The DNS server returns proxy_ip for all lookups so that outbound traffic routes through the proxy.

FieldTypeDefaultDescription
listenstring":53"Address and port the DNS server binds to.
proxy_ipstringrequiredIP address where iron-proxy is running. All DNS responses resolve to this IP.
upstream_resolverstringOS defaultUpstream DNS resolver address (e.g., "8.8.8.8:53"). When set, both passthrough DNS queries and upstream HTTP connections resolve via this server instead of the OS default. Useful when iron-proxy owns the system DNS.
passthroughstring[][]Domain glob patterns that are forwarded to the upstream resolver instead of being intercepted. Useful for internal DNS names that should not route through the proxy.
recordsobject[][]Static DNS records. These take precedence over interception and passthrough. See below.

dns.records[]

FieldTypeDescription
namestringDomain name for the record.
typestringRecord type: A or CNAME.
valuestringIP address (for A records) or target hostname (for CNAME records).

proxy

Configures the HTTP/HTTPS proxy listeners.

FieldTypeDefaultDescription
http_listenstring":80"Address and port for HTTP traffic.
https_listenstring":443"Address and port for HTTPS traffic.
tunnel_listenstring(disabled)Address and port for the CONNECT/SOCKS5 tunnel listener. Accepts both HTTP CONNECT and SOCKS5 requests. See the SOCKS5 and CONNECT tunnels guide for details.
max_request_body_bytesinteger1048576 (1 MiB)Maximum request body size that the proxy will buffer. Bodies are only buffered when a transform needs to inspect them.
max_response_body_bytesinteger0 (unlimited)Maximum response body size that the proxy will buffer. Set to 0 to disable the limit.

tls

Configures how iron-proxy handles HTTPS traffic. Two modes are supported: mitm (the default), which terminates TLS using a CA you provide and mints leaf certificates on the fly, and sni-only, which passes TLS through without termination.

FieldTypeDefaultDescription
modestring"mitm"TLS handling mode. One of mitm or sni-only. See TLS modes below.
ca_certstringrequired for mitmPath to the CA certificate file (PEM format). Not used in sni-only mode.
ca_keystringrequired for mitmPath to the CA private key file (PEM format). Not used in sni-only mode.
cert_cache_sizeinteger1000Number of generated leaf certificates to keep in the LRU cache. Not used in sni-only mode.
leaf_cert_expiry_hoursinteger72Validity duration (in hours) for generated leaf certificates. Not used in sni-only mode.

TLS Modes

mitm (default): iron-proxy terminates the client TLS connection, inspects the decrypted request, and opens a new TLS connection to the upstream server. Clients must trust iron-proxy’s CA certificate. This is the only mode that lets transforms see request methods, paths, headers, and bodies.

sni-only: iron-proxy peeks at the TLS ClientHello SNI and TCP-passthroughs the connection to the upstream without terminating TLS. Clients do not need to trust a proxy CA. The transform pipeline still runs with a host-only synthetic request: method, path, headers, and body are empty, so host-based allowlist rules are the only things that can match. Body-inspecting transforms like secrets and grpc still run but have nothing to act on. The CONNECT/SOCKS5 tunnel’s TLS branch also switches to passthrough in sni-only mode.

tls: mode: "sni-only"

Use sni-only when you need host-level egress control but cannot distribute a CA certificate to workloads. Use mitm when you need secret injection, body inspection, or method/path allowlists.

transforms

An ordered array of transforms that run on every request. All transforms must pass for the request to be forwarded upstream. Transforms execute in the order they appear in the configuration.

Each transform has a name and a config object. The available transforms are documented below.

allowlist

Controls which destinations are reachable through the proxy. Requests to destinations not in the allowlist receive an HTTP 403 response.

There are two ways to specify allowed destinations: flat lists (domains and cidrs) that allow all methods and paths, and rules that support method and path restrictions. Both can be used together in the same allowlist.

FieldTypeDefaultDescription
domainsstring[][]Hostname glob patterns to allow (e.g., registry.npmjs.org, *.anthropic.com). All methods and paths are permitted.
cidrsstring[][]CIDR ranges to allow (e.g., 10.0.0.0/8). All methods and paths are permitted.
rulesobject[][]Rules with optional method and path restrictions. See below.
warnbooleanfalseWhen true, violations are logged but not blocked. Useful for rolling out allowlists incrementally.

allowlist.rules[]

Each rule matches a single host or CIDR, with optional method and path filters. A request is allowed if it matches any rule (or any flat domains/cidrs entry).

FieldTypeDefaultDescription
hoststringHostname glob pattern. Mutually exclusive with cidr.
cidrstringCIDR range. Mutually exclusive with host.
methodsstring[]allHTTP methods to allow (e.g., ["GET", "POST"]). Omit or set to ["*"] to allow all methods.
pathsstring[]allPath patterns to allow (e.g., ["/v1/*"]). Must start with /. Supports * wildcards. Omit to allow all paths.

secrets

Injects or replaces secret values at the egress boundary so that real credentials are never exposed to sandboxed workloads. Each secret declares its own source and either an inject or replace block.

FieldTypeDefaultDescription
secretsobject[][]List of secret entries. See below.

secrets.secrets[]

FieldTypeDefaultDescription
sourceobjectrequiredWhere to read the secret value. Contains a type field (env, aws_sm, or aws_ssm) plus type-specific fields. See sources below.
injectobjectInject the secret onto matching requests unconditionally. See inject mode. Mutually exclusive with replace.
replaceobjectReplace a proxy token with the real value. See replace mode. Mutually exclusive with inject.
rulesobject[][]Restrict this secret to specific destinations. Uses the same format as allowlist.rules[]. If empty, the secret applies to all destinations.

Secret Sources

env

Read the secret from an environment variable on the iron-proxy process.

FieldTypeDescription
typestringMust be env.
varstringEnvironment variable name containing the real secret value.
source: type: env var: OPENAI_API_KEY
aws_sm

Read the secret from AWS Secrets Manager. The value is cached and refreshed in the background based on the configured TTL.

FieldTypeDefaultDescription
typestringMust be aws_sm.
secret_idstringrequiredSecret ARN or name in AWS Secrets Manager.
regionstringAWS SDK defaultAWS region where the secret is stored.
json_keystringWhen set, parse the fetched value as JSON and extract this field.
ttlduration0 (no refresh)Re-fetch interval. Set to 0 to read the value once at startup.
source: type: aws_sm secret_id: "arn:aws:secretsmanager:us-west-1:123456789:secret:my-key" region: "us-west-1" ttl: 10m
aws_ssm

Read the secret from AWS Systems Manager Parameter Store. Like aws_sm, values are cached and refreshed in the background based on the TTL.

FieldTypeDefaultDescription
typestringMust be aws_ssm.
namestringrequiredParameter name or ARN.
regionstringAWS SDK defaultAWS region where the parameter is stored.
with_decryptionbooleantrueDecrypt SecureString parameters.
json_keystringWhen set, parse the fetched value as JSON and extract this field.
ttlduration0 (no refresh)Re-fetch interval. Set to 0 to read the value once at startup.
source: type: aws_ssm name: "/myapp/api-key" region: "us-east-1" with_decryption: true ttl: 15m

iron-proxy uses the standard AWS credential chain (environment variables, instance profile, ECS task role, etc.) to authenticate with AWS.

Inject Mode

In inject mode, the proxy unconditionally sets a header or query parameter on every request that matches the secret’s rules. The workload never sees or sends any credential. This is useful when sandboxed workloads should have no knowledge of credentials at all.

FieldTypeDescription
headerstringHeader name to set on matching requests. Mutually exclusive with query_param.
query_paramstringQuery parameter name to set on matching requests. Mutually exclusive with header.
formatterstringGo template for the header value. Receives .Value (the resolved secret) and a base64 helper. Not used with query_param.

The formatter field supports Go templates. Use {{ .Value }} to insert the raw secret. The base64 helper concatenates and base64-encodes its arguments:

# Set Authorization: Bearer <secret> inject: header: "Authorization" formatter: "Bearer {{ .Value }}" # Set a query parameter (no formatter needed) inject: query_param: "key"

Replace Mode

In replace mode, the workload sends a proxy token that the proxy swaps for the real value before forwarding upstream. Query parameters are always scanned for proxy tokens.

FieldTypeDefaultDescription
proxy_valuestringrequiredToken that the sandboxed environment sends. The proxy replaces this with the real value before forwarding.
match_headersstring[][]Header names to scan for the proxy token. An empty list scans all headers.
match_bodybooleanfalseWhen true, scan the request body for the proxy token.
requirebooleanfalseWhen true, requests matching a configured rule are rejected with HTTP 403 if the proxy token is not present in any scanned location. Prevents workloads from bypassing secret management.

The proxy_value, match_headers, match_body, and require fields may also be set at the top level of a secret entry for backwards compatibility. New configurations should use the replace block.

annotate

Captures HTTP request header values into audit log annotations based on host, method, and path rules. This is useful for enriching audit logs with request-specific context like request IDs or authorization tokens. This transform never rejects requests.

FieldTypeDefaultDescription
annotationsobject[][]List of annotation groups. See below.

annotate.annotations[]

FieldTypeDescription
rulesobject[]Rules to match requests against. Uses the same format as allowlist.rules[].
headersstring[]Header names to capture from matching requests. Values are written as header:<Name> entries in the transform trace.
- name: annotate config: annotations: - rules: - host: "api.openai.com" methods: ["POST"] paths: ["/v1/*"] headers: ["x-request-id", "authorization"]

Example audit log annotation output:

{ "header:X-Request-Id": "req-abc123", "header:Authorization": "Bearer sk-ant-..." }

grpc

Delegates request and response processing to an external gRPC server implementing the TransformService API. You can define multiple grpc transforms to pipeline through several servers.

FieldTypeDefaultDescription
namestringrequiredIdentifier for this transform, used in logs and error messages.
targetstringrequiredgRPC server address (e.g., localhost:9500).
send_request_bodybooleanfalseWhen true, forward the full request body to the gRPC server. When false, only headers are sent.
send_response_bodybooleanfalseWhen true, forward the full response body to the gRPC server. When false, only headers are sent.
rulesobject[][]Restrict which requests are forwarded to this server. Uses the same rule format as allowlist.rules[]. If empty, all requests are forwarded.
tlsobjectTLS configuration for the gRPC connection. See below.

grpc.tls

FieldTypeDefaultDescription
enabledbooleanfalseEnable TLS for the gRPC connection. When false, the connection uses plaintext.
ca_certstringsystem defaultPath to a custom CA certificate for server verification.
certstringPath to a client certificate for mTLS. Must be set together with key.
keystringPath to the client private key for mTLS. Must be set together with cert.

metrics

Configures the OpenTelemetry/Prometheus metrics endpoint.

FieldTypeDefaultDescription
listenstring":9090"Address and port for the metrics endpoint.

log

Configures logging output.

FieldTypeDefaultDescription
levelstring"info"Log verbosity. One of debug, info, warn, or error.

OpenTelemetry Environment Variables

OTEL log export is configured through environment variables, not the YAML config file. Set OTEL_EXPORTER_OTLP_ENDPOINT to enable it. See the OTEL export guide for usage examples.

VariableTypeDefaultDescription
OTEL_EXPORTER_OTLP_ENDPOINTstring(disabled)OTLP collector URL (e.g., https://otel-collector.example.com:4318). Export is disabled when unset.
OTEL_EXPORTER_OTLP_PROTOCOLstringhttp/protobufTransport protocol: http/protobuf or grpc.
OTEL_EXPORTER_OTLP_HEADERSstring(none)Comma-separated key=value pairs sent as headers on every export request. Typically used for authentication.
OTEL_SERVICE_NAMEstringiron-proxyService name attached to all log records.
OTEL_RESOURCE_ATTRIBUTESstring(none)Comma-separated key=value resource attributes added to all log records (e.g., deployment.environment=staging).
Last updated on