Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
58acbe5
fix(tests): eliminate flaky parallel test failures in gorouter suite
hoffmaen Apr 21, 2026
8ec3e04
Fix issues found in code review
hoffmaen Apr 22, 2026
a6974d4
Add per-domain mTLS configuration support to GoRouter config
rkoster Mar 4, 2026
9b5cbcd
Implement per-domain TLS configuration via GetConfigForClient
rkoster Mar 4, 2026
e2d9e11
Make clientcert handler domain-aware
rkoster Mar 4, 2026
8d480e9
Add BOSH configuration support for mTLS domains
rkoster Mar 4, 2026
7857076
Add AllowedSources support for mTLS authorization (Phase 1b partial)
rkoster Mar 4, 2026
a9a79e4
Copy AllowedSourceAppGUIDs in NewEndpoint constructor
rkoster Mar 4, 2026
178d426
Add identity extraction handler for mTLS caller identification
rkoster Mar 4, 2026
4e28812
Add mTLS authorization handler for app-to-app access control
rkoster Mar 4, 2026
a83a624
Wire identity and authorization handlers into proxy chain
rkoster Mar 4, 2026
67d32ce
Add AllowedSourceAppGUIDs support to route-registrar
rkoster Mar 4, 2026
5a3f0dd
Fix domain names to match RFC specification
rkoster Mar 4, 2026
2a45b06
Expand AllowedSources to full RFC specification
rkoster Mar 4, 2026
c057ea5
Add comprehensive integration tests for mTLS app-to-app routing
rkoster Mar 4, 2026
401a9de
Fix vendor dependencies broken by commit 0a13b3ed3
rkoster Mar 4, 2026
dae0b01
Fix mTLS authorization to use RoutePool instead of RouteEndpoint
rkoster Mar 5, 2026
0f66e3d
Support allowed_sources nested in options for CAPI/Diego integration
rkoster Mar 5, 2026
5f37057
Fix identity extraction to handle GoRouter XFCC format (raw base64)
rkoster Mar 5, 2026
6d3858b
Rename AllowedSources to MtlsAllowedSources for clarity
rkoster Mar 5, 2026
25eeb5c
Add configurable XFCC format support (raw/envoy)
rkoster Mar 5, 2026
af9a2da
Emit RTR access logs for denied mTLS requests
rkoster Mar 5, 2026
b52e06d
Refactor mTLS route options to RFC-0027 compliant flat format
rkoster Mar 5, 2026
8d85a88
Implement RFC domain-scoped mTLS app-to-app routing in GoRouter
rkoster Apr 3, 2026
50c0994
feat(gorouter): implement RFC-compliant post-selection mTLS authoriza…
rkoster Apr 16, 2026
edd5adc
refactor: rename MtlsAuthError to AuthError for future extensibility
rkoster Apr 16, 2026
f091b56
refactor: extract shared mTLS helper functions to mtls_helpers.go
rkoster Apr 16, 2026
a9e10aa
refactor: remove deprecated mtls_authorization handler
rkoster Apr 16, 2026
595cf4f
refactor: move helper functions to their respective handlers
rkoster Apr 16, 2026
70adac9
refactor: introduce AuthResult and remove mTLS-specific naming
rkoster Apr 17, 2026
b6a5e26
refactor: rename test variable mtlsErr to authErr for consistency
rkoster Apr 17, 2026
1acb329
refactor: rename mtlsAllowedSources parameter to allowedSources in te…
rkoster Apr 17, 2026
9db55f7
refactor: align integration test naming with RFC terminology
rkoster Apr 17, 2026
f514463
refactor: remove unused EndpointPool methods from deprecated pre-sele…
rkoster Apr 17, 2026
ca5673f
refactor: remove identity-aware routing fields from route-registrar
rkoster Apr 17, 2026
62accac
chore: add devbox files to .gitignore
rkoster Apr 17, 2026
b5b7eed
fix: remove routing-api from go.mod dependencies
rkoster Apr 17, 2026
3bd3c7c
chore: update go.sum and vendor/modules.txt after rebase
rkoster Apr 17, 2026
a932c36
fix: run gofmt on post_selection_pipeline_test.go
rkoster Apr 17, 2026
4ce7b94
fix: run gofmt on all modified Go files
rkoster Apr 17, 2026
08afc4e
fix: resolve go vet and staticcheck issues
rkoster Apr 17, 2026
9f5e4de
fix: resolve integration test failures for identity-aware routing
rkoster Apr 20, 2026
e036406
fix: run gofmt on modified files
rkoster Apr 20, 2026
28d2754
chore: trigger CI after rebase on develop
rkoster Apr 20, 2026
1908903
fix: stop router before NATS in integration test cleanup
rkoster Apr 20, 2026
5769288
chore: trigger CI for port conflict fix
rkoster Apr 20, 2026
7b7b9b1
refactor: rebrand access rules to route policies terminology
rkoster Apr 21, 2026
957dae9
fix: apply gofmt to test files for CI compliance
rkoster Apr 21, 2026
d756508
fix: update integration test to use renamed struct fields
rkoster Apr 21, 2026
c8243e7
fix: route policy enforcement on routes without enforcement enabled
rkoster Apr 22, 2026
ac790f0
fix: strip port from Host header before mTLS domain matching
rkoster Apr 22, 2026
0db7359
fix: apply gofmt to mtls_route_policies_auth_test.go
rkoster Apr 23, 2026
d528bad
fix(test): correct expectations for routes without enforcement enabled
rkoster Apr 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,8 @@ tags
src/golang.org/x/tools/
src/github.com/kisielk/
src/golang.org/x/sync/

# Devbox local development environment
devbox.json
devbox.lock
.devbox/
25 changes: 25 additions & 0 deletions jobs/gorouter/spec
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,31 @@ properties:
router.only_trust_client_ca_certs:
description: "When router.only_trust_client_ca_certs is true, router.client_ca_certs are the only trusted CA certs for client requests. When router.only_trust_client_ca_certs is false, router.client_ca_certs are trusted in addition to router.ca_certs and the CA certificates installed on the filesystem. This will have no affect if the `router.client_cert_validation` property is set to none."
default: false
router.domains:
description: |
Array of domains requiring mutual TLS authentication. Each domain can have its own CA certificate pool, forwarded_client_cert mode, and xfcc_format.
For non-wildcard domains, the domain must match the request host exactly.
For wildcard domains (e.g., *.apps.identity), the wildcard must be the leftmost label and matches any single label.

xfcc_format controls the format of the X-Forwarded-Client-Cert header:
- "raw" (default): Full base64-encoded certificate (~1.5KB)
- "envoy": Compact Hash=<sha256>;Subject="<DN>" format (~300 bytes)
default: []
example:
- name: "*.apps.identity"
ca_certs: |
-----BEGIN CERTIFICATE-----
<CA certificate for apps.identity domain>
-----END CERTIFICATE-----
forwarded_client_cert: sanitize_set
xfcc_format: envoy
- name: "secure.example.com"
ca_certs: |
-----BEGIN CERTIFICATE-----
<CA certificate for secure.example.com>
-----END CERTIFICATE-----
forwarded_client_cert: forward
xfcc_format: raw
router.backends.max_attempts:
description: |
Maximum number of attempts on failing requests against backend routes.
Expand Down
48 changes: 48 additions & 0 deletions jobs/gorouter/templates/gorouter.yml.erb
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,54 @@ if p('router.client_ca_certs')
params['client_ca_certs'] = client_ca_certs
end

if_p('router.domains') do |domains|
if !domains.is_a?(Array)
raise 'router.domains must be provided as an array'
end

processed_domains = []
domains.each do |domain_config|
if !domain_config.is_a?(Hash)
raise 'Each entry in router.domains must be a hash'
end

if !domain_config.key?('name') || domain_config['name'].nil? || domain_config['name'].strip.empty?
raise 'Each entry in router.domains must have a "name" key'
end

if !domain_config.key?('ca_certs') || domain_config['ca_certs'].nil? || domain_config['ca_certs'].strip.empty?
raise 'Each entry in router.domains must have a "ca_certs" key with certificate content'
end

processed_entry = {
'domain' => domain_config['name'],
'ca_certs' => domain_config['ca_certs']
}

if domain_config.key?('forwarded_client_cert') && !domain_config['forwarded_client_cert'].nil?
valid_modes = ['always_forward', 'forward', 'sanitize_set']
mode = domain_config['forwarded_client_cert']
unless valid_modes.include?(mode)
raise "Invalid forwarded_client_cert mode '#{mode}' for domain '#{domain_config['name']}'. Must be one of: #{valid_modes.join(', ')}"
end
processed_entry['forwarded_client_cert'] = mode
end

if domain_config.key?('xfcc_format') && !domain_config['xfcc_format'].nil?
valid_formats = ['raw', 'envoy']
format = domain_config['xfcc_format']
unless valid_formats.include?(format)
raise "Invalid xfcc_format '#{format}' for domain '#{domain_config['name']}'. Must be one of: #{valid_formats.join(', ')}"
end
processed_entry['xfcc_format'] = format
end

processed_domains << processed_entry
end

params['domains'] = processed_domains
end

if_p('router.http_rewrite') do |r|
params['http_rewrite'] = r
end
Expand Down
30 changes: 15 additions & 15 deletions src/code.cloudfoundry.org/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ go 1.25.0
replace github.com/cactus/go-statsd-client => github.com/cactus/go-statsd-client v2.0.2-0.20150911070441-6fa055a7b594+incompatible

require (
code.cloudfoundry.org/cfhttp/v2 v2.74.0
code.cloudfoundry.org/clock v1.66.0
code.cloudfoundry.org/debugserver v0.92.0
code.cloudfoundry.org/diego-logging-client v0.101.0
code.cloudfoundry.org/eventhub v0.69.0
code.cloudfoundry.org/cfhttp/v2 v2.73.0
code.cloudfoundry.org/clock v1.65.0
code.cloudfoundry.org/debugserver v0.91.0
code.cloudfoundry.org/diego-logging-client v0.100.0
code.cloudfoundry.org/eventhub v0.68.0
code.cloudfoundry.org/go-loggregator/v9 v9.2.1
code.cloudfoundry.org/go-metric-registry v0.0.0-20260409052016-6e68d03a192f
code.cloudfoundry.org/lager/v3 v3.66.0
code.cloudfoundry.org/localip v0.68.0
code.cloudfoundry.org/lager/v3 v3.65.0
code.cloudfoundry.org/localip v0.67.0
code.cloudfoundry.org/locket v0.0.0-20251117222557-be612341b29d
code.cloudfoundry.org/tlsconfig v0.51.0
code.cloudfoundry.org/tlsconfig v0.50.0
github.com/armon/go-proxyproto v0.1.0
github.com/cactus/go-statsd-client v3.2.1+incompatible
github.com/cloudfoundry-community/go-uaa v0.3.6
Expand All @@ -28,14 +28,14 @@ require (
github.com/jinzhu/gorm v1.9.16
github.com/kisielk/errcheck v1.10.0
github.com/lib/pq v1.12.3
github.com/nats-io/nats-server/v2 v2.12.7
github.com/nats-io/nats.go v1.51.0
github.com/nats-io/nats-server/v2 v2.12.6
github.com/nats-io/nats.go v1.50.0
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d
github.com/onsi/ginkgo/v2 v2.28.1
github.com/onsi/gomega v1.39.1
github.com/openzipkin/zipkin-go v0.4.3
github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9
github.com/tedsuo/ifrit v0.0.0-20260418191334-846868129986
github.com/tedsuo/ifrit v0.0.0-20230516164442-7862c310ad26
github.com/tedsuo/rata v1.0.0
github.com/urfave/cli v1.22.17
github.com/urfave/negroni/v3 v3.1.1
Expand All @@ -54,7 +54,7 @@ require (

require (
code.cloudfoundry.org/bbs v0.0.0-20260323203855-1402bd61fc46 // indirect
code.cloudfoundry.org/durationjson v0.69.0 // indirect
code.cloudfoundry.org/durationjson v0.68.0 // indirect
code.cloudfoundry.org/go-diodes v0.0.0-20260209061029-a81ffbc46978 // indirect
code.cloudfoundry.org/inigo v0.0.0-20210615140442-4bdc4f6e44d5 // indirect
filippo.io/edwards25519 v1.2.0 // indirect
Expand All @@ -74,10 +74,10 @@ require (
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/go-tpm v0.9.8 // indirect
github.com/google/pprof v0.0.0-20260402051712-545e8a4df936 // indirect
github.com/honeycombio/libhoney-go v1.27.1 // indirect
github.com/honeycombio/libhoney-go v1.26.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/pgx/v5 v5.9.2 // indirect
github.com/jackc/pgx/v5 v5.9.1 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/klauspost/compress v1.18.5 // indirect
Expand All @@ -103,6 +103,6 @@ require (
golang.org/x/sys v0.43.0 // indirect
golang.org/x/text v0.36.0 // indirect
golang.org/x/time v0.15.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260406210006-6f92a3bedf2d // indirect
gopkg.in/alexcesaro/statsd.v2 v2.0.0 // indirect
)
61 changes: 31 additions & 30 deletions src/code.cloudfoundry.org/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -594,18 +594,18 @@ cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT
cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw=
code.cloudfoundry.org/bbs v0.0.0-20260323203855-1402bd61fc46 h1:LdeIKJdg/mlH4nKyGyBMFg6IzuqeL+39zpBbAx5Lrcs=
code.cloudfoundry.org/bbs v0.0.0-20260323203855-1402bd61fc46/go.mod h1:XKlGVVXFi5EcHHMPzw3xgONK9PeEZuUbIC43XNwxD10=
code.cloudfoundry.org/cfhttp/v2 v2.74.0 h1:U8OIpXEi0tjpx6upeQzC4IVse7lfPFf5APqdiql0B04=
code.cloudfoundry.org/cfhttp/v2 v2.74.0/go.mod h1:isgxk/v6y29WDjwnLcuIqF1kVT2BjJ4lZcJSj6jpSM4=
code.cloudfoundry.org/clock v1.66.0 h1:hX7B+4EREnSf2T0xpq2gQGV5LI5LYRqwB331M9OhqW4=
code.cloudfoundry.org/clock v1.66.0/go.mod h1:tiZfotIRQkAjmhlD4rtSNU8mV15Kpvgdir4Vgejnv4k=
code.cloudfoundry.org/debugserver v0.92.0 h1:8vOe2PiaxaFswszaZ0jZd2dwb3c9jp4wQ7ZyHYR1zFo=
code.cloudfoundry.org/debugserver v0.92.0/go.mod h1:qnW5PYSM6GePGU69MED+5Dk25Pcy/sxaDwg6RTuVgGc=
code.cloudfoundry.org/diego-logging-client v0.101.0 h1:h/RqVy9EbM0/XEa+80VuuU4QfnSfFuti++cWPx0W19E=
code.cloudfoundry.org/diego-logging-client v0.101.0/go.mod h1:Z2jLQZRUfMji6tDWsvU/ZF1+5qGteswFotxwHEpIhhI=
code.cloudfoundry.org/durationjson v0.69.0 h1:kHakzF7A+ykfZqhP9+e52RVKPkwt77wxvIf83BERMIM=
code.cloudfoundry.org/durationjson v0.69.0/go.mod h1:E/V7DjnjNr3dykRKIVxiQFySo1um00Dtn8BPzHwdY28=
code.cloudfoundry.org/eventhub v0.69.0 h1:RWpHkFnwMGyK0BITLRlOURO3CiZqEwrBpc8bihEv9GQ=
code.cloudfoundry.org/eventhub v0.69.0/go.mod h1:BwZEwSb7jFYZvj1md8nk7wswTmjooIMMPoz9uZ2IwFg=
code.cloudfoundry.org/cfhttp/v2 v2.73.0 h1:yJ6/98S6Hk7+O1pSqYS7VdPwvSu8rN7ZvARjCPLaDzY=
code.cloudfoundry.org/cfhttp/v2 v2.73.0/go.mod h1:acl6VWNCkPN8L92/nBL/JlLTKsFPnW4F0fuGbfsoAkM=
code.cloudfoundry.org/clock v1.65.0 h1:r3QNfdjq8sxzAnuTf24FAh7A+7KVbCOJ4ZSMBMPd/1M=
code.cloudfoundry.org/clock v1.65.0/go.mod h1:vHjVDAJB13nKjOzbIBtrCoVGt8q/91o7d2h+6WysXas=
code.cloudfoundry.org/debugserver v0.91.0 h1:GS/EPXyMIy9PiS3hUuAhEsQUwI1DqhBVuZ1rLAdp8aw=
code.cloudfoundry.org/debugserver v0.91.0/go.mod h1:QFDX6EWyYl/N4+UhyG+7Jr8ex6G2qp0uc3AaX4GZHis=
code.cloudfoundry.org/diego-logging-client v0.100.0 h1:Xhc0finEO6nV5ix0+zMI1ZLyiG6Ug1vOi8sVW03VGH8=
code.cloudfoundry.org/diego-logging-client v0.100.0/go.mod h1:xE3jDwFN2ixn4IKkaVMGaOSEX8pXGvaMDSCHgg1Qepg=
code.cloudfoundry.org/durationjson v0.68.0 h1:6Ay0kK5XpxuZ5cWyzFX52oiIO6Atv0nG87a0xY8JBUQ=
code.cloudfoundry.org/durationjson v0.68.0/go.mod h1:GNKEsRSGjaZd4ED8d/17Kr+ttpZne22hAkaWQPUbxtE=
code.cloudfoundry.org/eventhub v0.68.0 h1:o47FFA/ffB57qMEGHCH9JsaT0p+f6J7V321fp8FaQHE=
code.cloudfoundry.org/eventhub v0.68.0/go.mod h1:tCx1f+4W2vVJa3v2oP/YRz679g31crtFxbU6erN551M=
code.cloudfoundry.org/go-diodes v0.0.0-20260209061029-a81ffbc46978 h1:uZ6UIz7zl39FMy5GybKzI83zD35c4fvkU8sQEZDH/x8=
code.cloudfoundry.org/go-diodes v0.0.0-20260209061029-a81ffbc46978/go.mod h1:ZZMgJNANhsfqeXF//d5qDK0dNnQ4jTBsib4WR0xbWJQ=
code.cloudfoundry.org/go-loggregator/v9 v9.2.1 h1:S6Lgg5UJbhh2bt2TGQxs6R00CF8PrUA3GFPYDxy56Fk=
Expand All @@ -614,14 +614,14 @@ code.cloudfoundry.org/go-metric-registry v0.0.0-20260409052016-6e68d03a192f h1:z
code.cloudfoundry.org/go-metric-registry v0.0.0-20260409052016-6e68d03a192f/go.mod h1:0IMHt7ZlRV53qzyPdjWnh37L0Itkvrlen7czr+Qbm84=
code.cloudfoundry.org/inigo v0.0.0-20210615140442-4bdc4f6e44d5 h1:XVhLtnvbIlLQh7L0KADVFjd2dfgXVcOpqPLpMtg/IZA=
code.cloudfoundry.org/inigo v0.0.0-20210615140442-4bdc4f6e44d5/go.mod h1:1ZB1JCh2FAp+SqX79ve6dc8YREvbsziULEOncAilX4Q=
code.cloudfoundry.org/lager/v3 v3.66.0 h1:OM9Zy+KCTUpanOfIlL4ac87po7VlBZEq+Mdf32VBi/g=
code.cloudfoundry.org/lager/v3 v3.66.0/go.mod h1:d+HET0t/G9vf8+sxAzhauv313xbfv8molPzY4uNb7vo=
code.cloudfoundry.org/localip v0.68.0 h1:PvXGssaG2ENu/Ux6Fm69qWmn6mTecATrhkG37BHN2Rs=
code.cloudfoundry.org/localip v0.68.0/go.mod h1:Gek6kZZfONg7T27yO1/xh/n90bsQA8WDPE2gKwhYYNg=
code.cloudfoundry.org/lager/v3 v3.65.0 h1:Z/euENq42rULCPl65R4tdNDWav9AJ6OoZkKfjIkQ3JM=
code.cloudfoundry.org/lager/v3 v3.65.0/go.mod h1:reJ2m/UwSmkU/eJkrgHf4ZEhAMnBuXGiGzLmuDR3D5s=
code.cloudfoundry.org/localip v0.67.0 h1:LwTdyXZLy4UA+6JkYHKjbI77JUU2KDllFhkgKhkVGAY=
code.cloudfoundry.org/localip v0.67.0/go.mod h1:mfTYuX8W6lSPXwaBrPc72BubNlBMmpowBwDWkYrca2M=
code.cloudfoundry.org/locket v0.0.0-20251117222557-be612341b29d h1:UQBC4hxKpaSc0lNcVafX71I8NLBncxDoWdSX2JTtRBA=
code.cloudfoundry.org/locket v0.0.0-20251117222557-be612341b29d/go.mod h1:AwHLRkdXtttLXNB8RHgLfErJ2kKafH62AR2OClhy6xI=
code.cloudfoundry.org/tlsconfig v0.51.0 h1:thK329gjMwbx+Cj0ZG/9c6jiWTeMAUOekPD3Qwx9g6w=
code.cloudfoundry.org/tlsconfig v0.51.0/go.mod h1:K7hANtU0m+X/IGEF6IA83KPEE6gKcL/efpltoKVfw+M=
code.cloudfoundry.org/tlsconfig v0.50.0 h1:HzbNSzYcM+c8V1ql1pYaXZGGUGsk6XgLjWSVidHvEIc=
code.cloudfoundry.org/tlsconfig v0.50.0/go.mod h1:esGzvjLioIRanToEWKLyNMo04xjiH3tX52irs0jjs98=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo=
filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc=
Expand Down Expand Up @@ -896,8 +896,8 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4Zs
github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/honeycombio/libhoney-go v1.27.1 h1:79FR19fVpaeDMqTDfpXtMxd90vzsxhZnIOSysMrUSQQ=
github.com/honeycombio/libhoney-go v1.27.1/go.mod h1:qLZO8Q3ep/hISEoVC7m8N9ZOvn2eqaGdoJg9XXXasqM=
github.com/honeycombio/libhoney-go v1.26.0 h1:fdwS7c/5h6ifJqQZ178nm4UEZha04GTbwJMZ7xkShhk=
github.com/honeycombio/libhoney-go v1.26.0/go.mod h1:cR+t7pq9heP00+1/+TNWCrAfjSA74xKWI8YGOANlzYY=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
Expand All @@ -906,8 +906,8 @@ github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsI
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.9.2 h1:3ZhOzMWnR4yJ+RW1XImIPsD1aNSz4T4fyP7zlQb56hw=
github.com/jackc/pgx/v5 v5.9.2/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4=
github.com/jackc/pgx/v5 v5.9.1 h1:uwrxJXBnx76nyISkhr33kQLlUqjv7et7b9FjCen/tdc=
github.com/jackc/pgx/v5 v5.9.1/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4=
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o=
Expand Down Expand Up @@ -967,10 +967,10 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/nats-io/jwt/v2 v2.8.1 h1:V0xpGuD/N8Mi+fQNDynXohVvp7ZztevW5io8CUWlPmU=
github.com/nats-io/jwt/v2 v2.8.1/go.mod h1:nWnOEEiVMiKHQpnAy4eXlizVEtSfzacZ1Q43LIRavZg=
github.com/nats-io/nats-server/v2 v2.12.7 h1:prQ9cPiWHcnwfT81Wi5lU9LL8TLY+7pxDru6fQYLCQQ=
github.com/nats-io/nats-server/v2 v2.12.7/go.mod h1:dOnmkprKMluTmTF7/QHZioxlau3sKHUM/LBPy9AiBPw=
github.com/nats-io/nats.go v1.51.0 h1:ByW84XTz6W03GSSsygsZcA+xgKK8vPGaa/FCAAEHnAI=
github.com/nats-io/nats.go v1.51.0/go.mod h1:26HypzazeOkyO3/mqd1zZd53STJN0EjCYF9Uy2ZOBno=
github.com/nats-io/nats-server/v2 v2.12.6 h1:Egbx9Vl7Ch8wTtpXPGqbehkZ+IncKqShUxvrt1+Enc8=
github.com/nats-io/nats-server/v2 v2.12.6/go.mod h1:4HPlrvtmSO3yd7KcElDNMx9kv5EBJBnJJzQPptXlheo=
github.com/nats-io/nats.go v1.50.0 h1:5zAeQrTvyrKrWLJ0fu02W3br8ym57qf7csDzgLOpcds=
github.com/nats-io/nats.go v1.50.0/go.mod h1:26HypzazeOkyO3/mqd1zZd53STJN0EjCYF9Uy2ZOBno=
github.com/nats-io/nkeys v0.4.15 h1:JACV5jRVO9V856KOapQ7x+EY8Jo3qw1vJt/9Jpwzkk4=
github.com/nats-io/nkeys v0.4.15/go.mod h1:CpMchTXC9fxA5zrMo4KpySxNjiDVvr8ANOSZdiNfUrs=
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
Expand Down Expand Up @@ -1078,8 +1078,9 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/tedsuo/ifrit v0.0.0-20260418191334-846868129986 h1:etGVMUNp4ZYI0EoO7MxUKTG187RK8tbwIijDcXtSeL4=
github.com/tedsuo/ifrit v0.0.0-20260418191334-846868129986/go.mod h1:b0WkuWMdITecmKiTvZnmIffiXD+P1TUysIxv8Mm4m/s=
github.com/tedsuo/ifrit v0.0.0-20230330192023-5cba443a66c4/go.mod h1:eyZnKCc955uh98WQvzOm0dgAeLnf2O0Rz0LPoC5ze+0=
github.com/tedsuo/ifrit v0.0.0-20230516164442-7862c310ad26 h1:mWCRvpoEMVlslxEvvptKgIUb35va9yj9Oq5wGw/er5I=
github.com/tedsuo/ifrit v0.0.0-20230516164442-7862c310ad26/go.mod h1:0uD3VMXkZ7Bw0ojGCwDzebBBzPBXtzEZeXai+56BLX4=
github.com/tedsuo/rata v1.0.0 h1:Sf9aZrYy6ElSTncjnGkyC2yuVvz5YJetBIUKJ4CmeKE=
github.com/tedsuo/rata v1.0.0/go.mod h1:X47ELzhOoLbfFIY0Cql9P6yo3Cdwf2CMX3FVZxRzJPc=
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
Expand Down Expand Up @@ -1748,8 +1749,8 @@ google.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOl
google.golang.org/genproto v0.0.0-20230330154414-c0448cd141ea/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak=
google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak=
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260406210006-6f92a3bedf2d h1:wT2n40TBqFY6wiwazVK9/iTWbsQrgk5ZfCSVFLO9LQA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260406210006-6f92a3bedf2d/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,20 @@ type AccessLogRecord struct {
GorouterTime float64

LocalAddress string

// Identity-aware routing authorization fields.
// AuthOutcome is "allowed" or "denied"; empty if no authorization was performed.
AuthOutcome string
// AuthRule identifies the rule that matched or caused denial.
AuthRule string
// AuthDeniedReason is a human-readable denial explanation (empty on allow).
AuthDeniedReason string
// CallerApp/Space/Org are the CF identity fields from the client certificate.
CallerApp string
CallerSpace string
CallerOrg string
// TlsSNI is the SNI used during TLS (logged on 421 rejections).
TlsSNI string
}

func (r *AccessLogRecord) formatStartedAt() string {
Expand Down Expand Up @@ -316,6 +330,43 @@ func (r *AccessLogRecord) makeRecord(performTruncate bool) []byte {
b.WriteString(`x_cf_routererror:`)
b.WriteDashOrStringValue(r.RouterError)

// mTLS identity and authorization fields (only emitted when present)
if r.TlsSNI != "" {
// #nosec G104
b.WriteString(` tls_sni:`)
b.WriteDashOrStringValue(r.TlsSNI)
}
if r.CallerApp != "" {
// #nosec G104
b.WriteString(` caller_app:`)
b.WriteDashOrStringValue(r.CallerApp)
}
if r.CallerSpace != "" {
// #nosec G104
b.WriteString(` caller_space:`)
b.WriteDashOrStringValue(r.CallerSpace)
}
if r.CallerOrg != "" {
// #nosec G104
b.WriteString(` caller_org:`)
b.WriteDashOrStringValue(r.CallerOrg)
}
if r.AuthOutcome != "" {
// #nosec G104
b.WriteString(` auth:`)
b.WriteDashOrStringValue(r.AuthOutcome)
}
if r.AuthRule != "" {
// #nosec G104
b.WriteString(` auth_rule:`)
b.WriteDashOrStringValue(r.AuthRule)
}
if r.AuthDeniedReason != "" {
// #nosec G104
b.WriteString(` auth_denied_reason:`)
b.WriteDashOrStringValue(r.AuthDeniedReason)
}

r.addExtraHeaders(b, performTruncate)

return b.Bytes()
Expand Down
Loading
Loading