diff --git a/docs/config/federation.md b/docs/config/federation.md
index 097bc75..c32b256 100644
--- a/docs/config/federation.md
+++ b/docs/config/federation.md
@@ -184,6 +184,56 @@ The `organization_uri` option is used to set a URI to the organization's website
organization_uri: https://organization.example.com
```
+## `publish_informational_claims_in_federation_entity`
+boolean
+`true`
+optional
+
+The `publish_informational_claims_in_federation_entity` option controls whether informational metadata claims
+(such as `organization_name`, `display_name`, `contacts`, `policy_uri`, etc.) are published in both the
+`openid_relying_party` and `federation_entity` metadata sections of the Entity Configuration, or only in the
+`openid_relying_party` section.
+
+When set to `true` (default), OFFA automatically copies consistent informational claims from the relying party
+metadata to the federation entity metadata. This ensures that these claims are available at both levels of the
+federation hierarchy.
+
+When set to `false`, informational claims are only published in the `openid_relying_party` metadata section and
+are not duplicated in the `federation_entity` section. This can be useful if you want to keep the federation
+entity metadata minimal or if you want to explicitly control what appears in each metadata section separately.
+
+??? file "config.yaml"
+
+ ```yaml
+ federation:
+ # Publish informational claims in both relying_party and federation_entity (default)
+ publish_informational_claims_in_federation_entity: true
+ ```
+
+ ```yaml
+ federation:
+ # Only publish informational claims in relying_party, not in federation_entity
+ publish_informational_claims_in_federation_entity: false
+ ```
+
+!!! info "Informational Claims"
+
+ The following informational claims are affected by this setting:
+
+ - `organization_name`
+ - `display_name`
+ - `description`
+ - `logo_uri`
+ - `policy_uri`
+ - `information_uri`
+ - `tos_uri`
+ - `contacts` (list)
+ - `keywords` (list)
+
+ These claims are only copied to the federation entity metadata if they have consistent values across all
+ metadata types that define them. If different values are specified for different metadata types, the claims
+ are not copied to avoid conflicts.
+
## `extra_rp_metadata`
mapping / object
optional
diff --git a/go.mod b/go.mod
index a37bcca..b93d196 100644
--- a/go.mod
+++ b/go.mod
@@ -6,7 +6,7 @@ require (
github.com/adam-hanna/arrayOperations v1.0.1
github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf
github.com/coreos/go-oidc/v3 v3.18.0
- github.com/go-oidfed/lib v0.10.5
+ github.com/go-oidfed/lib v0.10.7
github.com/go-resty/resty/v2 v2.17.2
github.com/gofiber/fiber/v2 v2.52.13
github.com/gofiber/template/mustache/v2 v2.0.14
@@ -57,8 +57,8 @@ require (
github.com/valyala/fastjson v1.6.10 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
- golang.org/x/crypto v0.50.0 // indirect
- golang.org/x/net v0.53.0 // indirect
- golang.org/x/sys v0.43.0 // indirect
- golang.org/x/text v0.36.0 // indirect
+ golang.org/x/crypto v0.51.0 // indirect
+ golang.org/x/net v0.54.0 // indirect
+ golang.org/x/sys v0.44.0 // indirect
+ golang.org/x/text v0.37.0 // indirect
)
diff --git a/go.sum b/go.sum
index 061afd5..6be5f00 100644
--- a/go.sum
+++ b/go.sum
@@ -32,8 +32,8 @@ github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA=
github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
-github.com/go-oidfed/lib v0.10.5 h1:FTgr2LDX7skLBe+6C31fXp8tUPQJZDd1u8jtdoAPqqg=
-github.com/go-oidfed/lib v0.10.5/go.mod h1:t8DHic6OC1tI7cCXSh+WpLkxEJpCkj8HZcaOkgbKi1k=
+github.com/go-oidfed/lib v0.10.7 h1:hXFEJkO9ivi9/Lq8w3XFunXfGuAZJmpq6FJPhBCs+Jc=
+github.com/go-oidfed/lib v0.10.7/go.mod h1:IG5ddCeYACoZbABR1J6QR42XTUXxH9g/dxA2u1RssAo=
github.com/go-resty/resty/v2 v2.17.2 h1:FQW5oHYcIlkCNrMD2lloGScxcHJ0gkjshV3qcQAyHQk=
github.com/go-resty/resty/v2 v2.17.2/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA=
github.com/goccy/go-json v0.10.6 h1:p8HrPJzOakx/mn/bQtjgNjdTcN+/S6FcG2CTtQOrHVU=
@@ -132,16 +132,16 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI=
-golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q=
+golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI=
+golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
-golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
+golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w=
+golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ=
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -153,8 +153,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
-golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
+golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ=
+golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@@ -163,8 +163,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
-golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
-golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
+golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
+golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
diff --git a/internal/config/config.go b/internal/config/config.go
index 66944a3..9707da8 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -80,14 +80,15 @@ type federationConf struct {
ExtraRPMetadata map[string]any `yaml:"extra_rp_metadata"`
ExtraEntityConfigurationData map[string]any `yaml:"extra_entity_configuration_data"`
- ConfigurationLifetime duration.DurationOption `yaml:"configuration_lifetime"`
- KeyStorage string `yaml:"key_storage"`
- ClientRegistrationTypes []string `yaml:"client_registration_types"`
- TrustMarks []*oidfed.EntityConfigurationTrustMarkConfig `yaml:"trust_marks"`
- UseResolveEndpoint bool `yaml:"use_resolve_endpoint"`
- UseEntityCollectionEndpoint bool `yaml:"use_entity_collection_endpoint"`
- EntityCollectionInterval duration.DurationOption `yaml:"entity_collection_interval"`
- RequiredOPTrustMarks []string `yaml:"required_op_trust_marks"`
+ ConfigurationLifetime duration.DurationOption `yaml:"configuration_lifetime"`
+ KeyStorage string `yaml:"key_storage"`
+ ClientRegistrationTypes []string `yaml:"client_registration_types"`
+ TrustMarks []*oidfed.EntityConfigurationTrustMarkConfig `yaml:"trust_marks"`
+ UseResolveEndpoint bool `yaml:"use_resolve_endpoint"`
+ UseEntityCollectionEndpoint bool `yaml:"use_entity_collection_endpoint"`
+ EntityCollectionInterval duration.DurationOption `yaml:"entity_collection_interval"`
+ RequiredOPTrustMarks []string `yaml:"required_op_trust_marks"`
+ PublishInformationalClaimsInFederationEntity bool `yaml:"publish_informational_claims_in_federation_entity"`
}
type sessionConf struct {
@@ -347,6 +348,7 @@ func MustLoadConfig() {
oidfedconst.ClientRegistrationTypeAutomatic,
oidfedconst.ClientRegistrationTypeExplicit,
},
+ PublishInformationalClaimsInFederationEntity: true,
},
OPDiscovery: opDiscoveryConf{
Local: localOPDiscoveryConf{
diff --git a/internal/server/server.go b/internal/server/server.go
index 48ae99e..5829642 100644
--- a/internal/server/server.go
+++ b/internal/server/server.go
@@ -144,6 +144,9 @@ func initFederationEntity() {
Extra: func() (map[string]any, []string, error) {
return fedConfig.ExtraEntityConfigurationData, nil, nil
},
+ ShouldApplyInformationalClaims: func() (bool, error) {
+ return config.Get().Federation.PublishInformationalClaimsInFederationEntity, nil
+ },
}
}