Skip to content

Releases: ironsh/iron-proxy

v0.43.0

11 Jun 19:32
76f8203

Choose a tag to compare

New: Disable Built-In DNS Server

iron-proxy's DNS server can now be disabled entirely via dns.enabled: false (or the IRON_DNS_ENABLED environment variable). When disabled, the proxy skips the :53 listener, drops the dns.proxy_ip requirement, and does not start the DNS server at all. Existing deployments are unaffected: the field defaults to true.

This is useful when clients reach the proxy via explicit HTTP_PROXY or HTTPS_PROXY environment variables rather than DNS interception, removing the need to run a DNS listener in those environments.

dns:
  enabled: false

New: Per-Upstream Postgres Session Settings

Postgres upstreams now support a settings list of session variables (GUCs) the proxy injects at session start, before the SET ROLE downgrade. Settings are applied via set_config with bound parameters (no value quoting), so they are safe to use with untrusted values.

The proxy pins every name in the list: clients may not SET, RESET, or set_config a pinned name afterwards. RESET ALL and DISCARD ALL are now also blocked whenever the proxy manages a role or session settings, closing a gap where those commands could previously undo the managed role. This makes settings suitable as a security boundary, for example passing a tenant identifier that a Row-Level Security policy keys off.

upstreams:
  - database: appdb
    dsn:
      type: env
      var: PG_APPDB_DSN
    role: tenant_role
    settings:
      - name: app.tenant_id
        value: centaur

Names must be bare or dotted GUC identifiers; role and session_authorization are reserved (use the role field for those). Values are static per-upstream. Postgres support is experimental.

Changelog

  • f8b52f1 feat(dns): allow disabling the built-in DNS server (#186)
  • 76f8203 feat(postgres): inject and pin per-upstream session settings (#189)

v0.42.0

08 Jun 18:29
26333fb

Choose a tag to compare

New: Postgres Single-Listener Architecture

The postgres configuration has been redesigned from a list of independent listeners to a single shared listener fronting multiple upstream databases. One bind address serves many upstreams: the client selects the upstream by the dbname it sends in its startup message, and the proxy routes accordingly. A single shared credential handles all client authentication; routing is by database name, so per-database credentials are not required.

Multi-statement Simple Queries are now also supported. The proxy forwards a batch as long as every statement passes the role policy, and rejects the batch only if any statement attempts a role mutation (SET ROLE, set_config('role', ...)) or a DO block.

# Before
postgres:
  - name: primary
    listen: ":5432"
    upstream:
      host: "db.internal"
      port: 5432
      sslmode: "require"
      user_env: "PG_UPSTREAM_USER"
      password_env: "PG_UPSTREAM_PASSWORD"
      database: "appdb"
    client:
      user: "app_user"
      password_env: "PG_PROXY_PASSWORD"
    role: "tenant_role"

# After
postgres:
  listen: ":5432"
  client:
    user: app_user
    password_env: PG_PROXY_PASSWORD
  upstreams:
    - database: appdb
      dsn:
        type: env
        var: PG_APPDB_DSN
      role: tenant_role
    - database: analyticsdb
      dsn:
        type: env
        var: PG_ANALYTICS_DSN
      role: analytics_role

This is a breaking config change for existing Postgres users. Migrate each entry in your postgres: list to an upstream under the new upstreams: key, replacing the per-listener upstream.host/port/... fields with a DSN source block. Postgres support is experimental.

New: File Secret Source

A new file secret source reads the secret from a path on disk. The file is re-read on every POST /v1/reload and on ttl expiry, so a long-lived proxy can pick up a rotated credential without restarting. Write the secret atomically (write-temp + rename) and call reload.

- source:
    type: file
    path: /etc/iron-proxy/secrets/OPENAI_API_KEY
  proxy_value: "proxy-token-123"
  match_headers: ["Authorization"]
  rules:
    - host: "api.openai.com"

Optional ttl and failure_ttl are supported. The value is the exact file contents (no trimming), so the writer controls trailing whitespace. Thanks to @drewstone for the contribution.

New: Outbound Proxy Routing

iron-proxy now routes its own outbound connections through an upstream SOCKS5 or HTTP CONNECT proxy. The standard HTTP_PROXY, HTTPS_PROXY, and NO_PROXY environment variables are honored automatically, so most deployments need no config change. An optional upstream_proxy block is available when environment variables aren't convenient.

proxy:
  upstream_proxy:
    http_proxy: "http://proxy.corp:3128"
    https_proxy: "http://proxy.corp:3128"
    no_proxy: "localhost,127.0.0.1,.internal.example.com"

This covers the HTTP/HTTPS forward data path (including CONNECT in mitm mode) and the OAuth credential-refresh client. Raw TCP tunnels (SNI-only passthrough, WebSocket) still dial directly. Note: when an upstream proxy is in use, upstream_deny_cidrs is enforced against the proxy's address rather than the final target, since the proxy resolves and connects to the target on iron-proxy's behalf.

New: 1Password Config Simplification

The host_env and token_env config fields on the 1password and 1password_connect secret sources have been removed. The SDK environment variable conventions (OP_SERVICE_ACCOUNT_TOKEN for 1password; OP_CONNECT_HOST and OP_CONNECT_TOKEN for 1password_connect) are now the only supported approach.

This is a breaking config change for 1password and 1password_connect users who set host_env or token_env. Remove those fields from your config.

Fixes

  • Fixed aws_auth rejecting HTTPS CONNECT tunnel setup with 400/missing_sigv4 before the signed request was ever sent. The synthetic CONNECT request used for tunnel policy checks can never carry a SigV4 signature; the transform now passes it through and signs the post-MITM request as intended. This affected boto3 and other clients routing HTTPS through a CONNECT proxy. Thanks to @0xdiid for the contribution.
  • Fixed percent-encoded reserved characters (e.g., %2F) being decoded before the upstream request was constructed, breaking APIs like GCS that route on encoded slashes within a path segment.
  • Fixed gcp_auth, hmac_sign, and oauth_token transforms being silently dropped in managed mode at startup and on every reload.

Changelog

  • 57a2cc3 feat(broker): add iron-token-broker for race-free OAuth refresh coordination (#141)
  • 53ec28d build: release iron-token-broker alongside iron-proxy (#142)
  • 5a06a6d feat(secrets): add token_broker source backed by iron-token-broker (#143)
  • 51c3220 refactor(secrets): drop env-name overrides for 1password and 1password_connect (#144)
  • b2d5b9a ci: release iron-token-broker on prefixed iron-token-broker/v* tags (#145)
  • 65276fd ci: split release workflow per binary and allow gumroad egress (#146)
  • 4d96a9f fix(ci): always log in to Docker Hub on release tags (#147)
  • 0c2fc94 fix(release): auto-detect prereleases and scope broker changelog (#148)
  • 510668d fix(release): ignore broker tags when computing iron-proxy previous release (#149)
  • 882726c feat(broker): accept 1Password titles in store secret_ref (#150)
  • be21d37 feat(broker): support token_endpoint_headers on credentials (#151)
  • 96fedf0 docs: add AGENTS.md with Go conventions and review guidance (#152)
  • b396dcc refactor: centralize case-sensitive header handling in internal/headers (#153)
  • ab9e8e0 refactor(integration_test): consolidate shared helpers (#154)
  • 8f1d8ef fix(proxy): preserve percent-encoded reserved chars in upstream path (#156)
  • 7159126 fix(awsauth): let CONNECT through the tunnel policy check (#167)
  • 6326e3f feat(postgres): allow multi-statement queries that pass the role policy (#168)
  • 0de6a1b refactor(controlplane): authenticate with a fixed bearer token (#169)
  • 7e66d72 feat(scripts): add dev-managed boot script and prefix sync path with /api (#170)
  • cfa25af feat(postgres): derive listeners from control-plane sync section (#171)
  • 81a3976 feat(controlplane): apply synced transforms in managed pipeline (#172)
  • f57e475 refactor(secrets): remove token_broker transform (#177)
  • feb3242 feat(postgres): single listener fronting database-routed upstreams (#179)
  • 28f0f80 build(deps): bump github.com/jackc/pgx/v5 from 5.9.2 to 5.10.0 (#175)
  • 93ce7dc build(deps): bump the aws-sdk-go group with 5 updates (#174)
  • 064f6cb build(deps): bump actions/checkout from 6.0.2 to 6.0.3 (#173)
  • cdda920 build(deps): bump go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp (#163)
  • 1163be8 build(deps): bump go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc (#165)
  • 62bc31b build(deps): bump the aws-sdk-go group with 2 updates (#161)
  • 451822e build(deps): bump golangci/golangci-lint-action from 9.2.0 to 9.2.1 (#159)
  • 9e3d739 build(deps): bump docker/setup-buildx-action from 4.0.0 to 4.1.0 (#160)
  • 3a1a2c2 build(deps): bump docker/login-action from 4.1.0 to 4.2.0 (#158)
  • a985a39 build(deps): bump docker/setup-qemu-action from 4.0.0 to 4.1.0 (#157)
  • 7e6a694 feat(secrets): add file source re-read on reload (#181)
  • afdeca2 feat(proxy): route outbound through upstream SOCKS5/HTTP CONNECT proxy (#182)
  • 26333fb chore: remove token broker references from proxy (#183)

v0.42.0-rc.8

05 Jun 17:14
feb3242

Choose a tag to compare

v0.42.0-rc.8 Pre-release
Pre-release

Changelog

  • feb3242 feat(postgres): single listener fronting database-routed upstreams (#179)
  • f57e475 refactor(secrets): remove token_broker transform (#177)

v0.42.0-rc.7

03 Jun 20:20
81a3976

Choose a tag to compare

v0.42.0-rc.7 Pre-release
Pre-release

Changelog

  • cdda920 build(deps): bump go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp (#163)
  • 81a3976 feat(controlplane): apply synced transforms in managed pipeline (#172)

v0.42.0-rc.6

02 Jun 23:20
cfa25af

Choose a tag to compare

v0.42.0-rc.6 Pre-release
Pre-release

Changelog

  • 3a1a2c2 build(deps): bump docker/login-action from 4.1.0 to 4.2.0 (#158)
  • 9e3d739 build(deps): bump docker/setup-buildx-action from 4.0.0 to 4.1.0 (#160)
  • a985a39 build(deps): bump docker/setup-qemu-action from 4.0.0 to 4.1.0 (#157)
  • 1163be8 build(deps): bump go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc (#165)
  • 451822e build(deps): bump golangci/golangci-lint-action from 9.2.0 to 9.2.1 (#159)
  • 62bc31b build(deps): bump the aws-sdk-go group with 2 updates (#161)
  • cfa25af feat(postgres): derive listeners from control-plane sync section (#171)

v0.42.0-rc.5

02 Jun 20:32
7e66d72

Choose a tag to compare

v0.42.0-rc.5 Pre-release
Pre-release

Changelog

  • 7e66d72 feat(scripts): add dev-managed boot script and prefix sync path with /api (#170)
  • 0de6a1b refactor(controlplane): authenticate with a fixed bearer token (#169)

v0.42.0-rc.4

29 May 16:12
7159126

Choose a tag to compare

v0.42.0-rc.4 Pre-release
Pre-release

Changelog

  • 7159126 fix(awsauth): let CONNECT through the tunnel policy check (#167)

v0.42.0-rc.3

29 May 05:06
6326e3f

Choose a tag to compare

v0.42.0-rc.3 Pre-release
Pre-release

Changelog

  • 6326e3f feat(postgres): allow multi-statement queries that pass the role policy (#168)
  • 8f1d8ef fix(proxy): preserve percent-encoded reserved chars in upstream path (#156)
  • ab9e8e0 refactor(integration_test): consolidate shared helpers (#154)

v0.42.0-rc.2

25 May 20:35
b396dcc

Choose a tag to compare

v0.42.0-rc.2 Pre-release
Pre-release

Changelog

  • 96fedf0 docs: add AGENTS.md with Go conventions and review guidance (#152)
  • 882726c feat(broker): accept 1Password titles in store secret_ref (#150)
  • be21d37 feat(broker): support token_endpoint_headers on credentials (#151)
  • 510668d fix(release): ignore broker tags when computing iron-proxy previous release (#149)
  • b396dcc refactor: centralize case-sensitive header handling in internal/headers (#153)

v0.42.0-rc.1

25 May 06:19
0c2fc94

Choose a tag to compare

v0.42.0-rc.1 Pre-release
Pre-release

Changelog

  • 0c2fc94 fix(release): auto-detect prereleases and scope broker changelog (#148)