You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/3.1-federation-discovery.md
+57-28Lines changed: 57 additions & 28 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,19 +1,26 @@
1
1
# Federation Discovery and Entity Collection
2
2
3
-
This library provides a high-performance, specification-compliant toolkit for discovering entities within an OpenID Federation and interacting with Entity Collection Endpoints.
3
+
This library provides a high-performance, specification-compliant toolkit for
4
+
discovering entities within an OpenID Federation and interacting with Entity
5
+
Collection Endpoints.
4
6
5
7
The functionality is split into two main operational modes:
6
8
7
-
1.**Federation Discovery** — A top-down, recursive traversal of a federation hierarchy starting from a Trust Anchor.
8
-
2.**Entity Collection** — A specialized protocol for optimized bulk-fetching of entities, featuring support for server-side filtering, sorting, and cursor-based pagination.
9
+
1.**Federation Discovery** — A top-down, recursive traversal of a federation
10
+
hierarchy starting from a Trust Anchor.
11
+
2.**Entity Collection** — A specialized protocol for optimized bulk-fetching
12
+
of entities, featuring support for server-side filtering, sorting, and
13
+
cursor-based pagination.
9
14
10
-
All components are integrated and accessible through the `\SimpleSAML\OpenID\Federation` facade.
15
+
All components are integrated and accessible through the
16
+
`\SimpleSAML\OpenID\Federation` facade.
11
17
12
18
---
13
19
14
20
## Setup and Configuration
15
21
16
-
To enable federation discovery, initialize the `Federation` facade with a cache and (optionally) a logger.
22
+
To enable federation discovery, initialize the `Federation` facade with a
23
+
cache and (optionally) a logger.
17
24
18
25
```php
19
26
<?php
@@ -31,9 +38,12 @@ $federationTools = new Federation(
31
38
32
39
### Custom Entity Collection Store
33
40
34
-
By default, the library persists discovered entity payloads using the configured PSR-16 cache (`CacheEntityCollectionStore`). If no cache is provided, it falls back to an `InMemoryEntityCollectionStore` (ephemeral).
41
+
By default, the library persists discovered entity payloads using the
42
+
configured PSR-16 cache (`CacheEntityCollectionStore`). If no cache is
43
+
provided, it falls back to an `InMemoryEntityCollectionStore` (ephemeral).
35
44
36
-
For production environments requiring persistent storage (e.g., Database, Redis), you should implement the `EntityCollectionStoreInterface`:
45
+
For production environments requiring persistent storage
46
+
(e.g., Database, Redis), you should implement the `EntityCollectionStoreInterface`:
37
47
38
48
```php
39
49
use SimpleSAML\OpenID\Federation\EntityCollection\EntityCollectionStoreInterface;
@@ -43,8 +53,6 @@ class MyDatabaseStore implements EntityCollectionStoreInterface
43
53
public function store(string $trustAnchorId, array $entities, int $ttl): void { /* ... */ }
44
54
public function get(string $trustAnchorId): ?array { /* ... */ }
45
55
public function clear(string $trustAnchorId): void { /* ... */ }
46
-
47
-
// New in v2.0: Track last update time for 'last_updated' response field
48
56
public function storeLastUpdated(string $trustAnchorId, int $timestamp, int $ttl): void { /* ... */ }
49
57
public function getLastUpdated(string $trustAnchorId): ?int { /* ... */ }
50
58
public function clearLastUpdated(string $trustAnchorId): void { /* ... */ }
@@ -56,13 +64,17 @@ $federationTools = new Federation(
56
64
```
57
65
58
66
> [!NOTE]
59
-
> The store caches the **JWT payload arrays** of discovered entities. Actual JWS signatures and original JWT strings are managed by the `EntityStatementFetcher` which handles its own caching and validation logic.
67
+
> The store caches the **JWT payload arrays** of discovered entities. Actual
68
+
> JWS signatures and original JWT strings are managed by the
69
+
> `EntityStatementFetcher` which handles its own caching and validation logic.
60
70
61
71
---
62
72
63
73
## Federation Discovery (Top-Down)
64
74
65
-
Federation Discovery performs a recursive traversal of the hierarchy. It starts at the Trust Anchor and follows `federation_list_endpoint` links to discover all subordinates.
75
+
Federation Discovery performs a recursive traversal of the hierarchy.
76
+
It starts at the Trust Anchor and follows `federation_list_endpoint` links
77
+
to discover all subordinates.
66
78
67
79
### Discovering Entities
68
80
@@ -88,14 +100,20 @@ try {
88
100
### Discovery Logic & Loop Protection
89
101
90
102
1.**Trust Anchor Config**: Fetches and validates the TA's Entity Configuration.
91
-
2.**Subordinate Listing**: Fetches the `federation_list_endpoint`. If filters are provided, they are passed as query parameters to this endpoint.
92
-
3.**Recursion**: For each discovered subordinate, it fetches its configuration and repeats the process.
93
-
4.**Loop Protection**: The algorithm tracks visited IDs to prevent infinite loops and is limited by `maxDiscoveryDepth`.
94
-
5.**Deduplication**: Entities appearing in multiple branches are only stored once.
103
+
2.**Subordinate Listing**: Fetches the `federation_list_endpoint`.
104
+
If filters are provided, they are passed as query parameters to this endpoint.
105
+
3.**Recursion**: For each discovered subordinate, it fetches its
106
+
configuration and repeats the process.
107
+
4.**Loop Protection**: The algorithm tracks visited IDs to prevent
108
+
infinite loops and is limited by `maxDiscoveryDepth`.
109
+
5.**Deduplication**: Entities appearing in multiple branches are only stored
110
+
once.
95
111
96
112
### Applying Filters During Discovery
97
113
98
-
You can pass filters (like `entity_type`) directly to the discovery process. These are passed to the remote `federation_list_endpoint` to optimize the traversal:
114
+
You can pass filters (like `entity_type`) directly to the discovery process.
115
+
These are passed to the remote `federation_list_endpoint` to optimize the
The Entity Collection Client allows fetching pre-filtered lists of entities from a remote `federation_collection_endpoint`. This is much more efficient than full traversal if the remote side supports it.
141
+
The Entity Collection Client allows fetching pre-filtered lists of entities
142
+
from a remote `federation_collection_endpoint`. This is much more efficient
143
+
than full traversal if the remote side supports it.
123
144
124
145
### Bulk Fetching with Filters
125
146
@@ -128,15 +149,15 @@ The client supports all standard OpenID Federation query parameters:
If you are implementing your own `federation_collection_endpoint`, the library provides high-level building blocks to handle filtering, sorting, and pagination.
198
+
If you are implementing your own `federation_collection_endpoint`, the library
199
+
provides high-level building blocks to handle filtering, sorting, and
200
+
pagination.
176
201
177
202
### The Pipeline Pattern
178
203
179
-
The recommended implementation follows this pipeline: **Discover → Filter → Sort → Paginate → Serialize**.
204
+
The recommended implementation follows this pipeline:
@@ -217,7 +243,9 @@ public function __invoke(ServerRequestInterface $request): ResponseInterface
217
243
218
244
### Sorting Technical Details
219
245
220
-
The `sort()` method accepts an array of claim paths relative to the **JWT payload root**. When sorting by metadata claims, you must explicitly include the `metadata` prefix:
246
+
The `sort()` method accepts an array of claim paths relative to the
247
+
**JWT payload root**. When sorting by metadata claims, you must explicitly
248
+
include the `metadata` prefix:
221
249
222
250
```php
223
251
$collection->sort([
@@ -231,7 +259,8 @@ $collection->sort([
231
259
232
260
## Serialized Response Format
233
261
234
-
The `toCollectionEndpointResponseArray()` method produces a structure compatible with the OpenID Federation specification:
262
+
The `toCollectionEndpointResponseArray()` method produces a structure compatible
0 commit comments