Skip to content

Commit 871a17c

Browse files
committed
Add WhitelistRegistry and enhance documentation
- Add WhitelistRegistry (pkg/registry/static/whitelist.go) - Simple URL-based whitelist for trusted issuers and verifiers - YAML/JSON configuration file support - Automatic file watching and config reload via fsnotify - Wildcard matching (prefix match and global wildcard) - Role-based lists: issuers, verifiers, trusted_subjects - Runtime management: AddIssuer(), RemoveIssuer(), etc. - 87% test coverage - Update example/config.yaml with comprehensive registry documentation - ETSI TSL, OpenID Federation, DID Web, DID Web VH - mDOC IACA, Whitelist, and static test registries - All configuration options documented - Add mDOC IACA Registry documentation to README.md - Dynamic IACA certificate validation for mDOC/mDL - Architecture and usage examples - Fix static registry examples in README.md to match actual API - Add example/whitelist.yaml configuration template - Update CHANGELOG.md with new features
1 parent 4eb92c2 commit 871a17c

File tree

12 files changed

+1433
-131
lines changed

12 files changed

+1433
-131
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111

12+
- WhitelistRegistry (`pkg/registry/static/whitelist.go`)
13+
- Simple URL-based whitelist for trusted issuers and verifiers
14+
- YAML/JSON configuration file support
15+
- Automatic file watching and config reload via fsnotify
16+
- Wildcard matching: `https://example.com/*` for prefix match, `*` for all
17+
- Role-based lists: `issuers`, `verifiers`, `trusted_subjects`
18+
- Runtime management: `AddIssuer()`, `RemoveIssuer()`, `AddVerifier()`, `RemoveVerifier()`
19+
- 87% test coverage
20+
1221
- Standalone AuthZEN client library (`pkg/authzenclient/`)
1322
- HTTP client for AuthZEN PDPs with discovery support
1423
- Methods: `Discover()`, `Evaluate()`, `Resolve()`, `EvaluateX5C()`, `EvaluateJWK()`
@@ -35,6 +44,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3544

3645
- Enhanced README.md with:
3746
- ETSI TSL Registry section documenting both standalone and server modes
47+
- mDOC IACA Registry section documenting dynamic IACA certificate validation
3848
- Updated package structure diagram
3949
- Configuration options table for TSLConfig
4050

README.md

Lines changed: 87 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,41 @@ Resolves and validates DID Web VH (Verifiable History) identifiers with cryptogr
220220

221221
**Supported resource types:** `did_document`, `jwk`, `verification_method`
222222

223+
#### mDOC IACA Registry
224+
225+
Dynamically validates mDOC/mDL X.509 certificate chains against IACA (Issuing Authority Certificate Authority) certificates fetched from OpenID4VCI issuers.
226+
227+
**Architecture:**
228+
1. Receives trust evaluation with issuer URL (`subject.id`) and X5C chain (`resource.key`)
229+
2. Fetches issuer's OpenID4VCI metadata (discovers `mdoc_iacas_uri` endpoint)
230+
3. Fetches IACA certificates from `mdoc_iacas_uri`
231+
4. Validates X5C chain against fetched IACAs
232+
5. Optionally enforces issuer allowlist
233+
234+
**Supported resource types:** `x5c`
235+
236+
```go
237+
import "github.com/sirosfoundation/go-trust/pkg/registry/mdociaca"
238+
239+
reg, err := mdociaca.New(&mdociaca.Config{
240+
Name: "mdoc-iaca",
241+
IssuerAllowlist: []string{"https://issuer.example.com"}, // Optional
242+
CacheTTL: time.Hour,
243+
})
244+
245+
// Evaluate trust for an mDOC issuer
246+
req := &authzen.EvaluationRequest{
247+
Subject: authzen.Subject{Type: "key", ID: "https://issuer.example.com"},
248+
Resource: authzen.Resource{Type: "x5c", Key: []interface{}{dsB64, iacaB64}},
249+
}
250+
resp, err := reg.Evaluate(ctx, req)
251+
```
252+
253+
**Use cases:**
254+
- Mobile driving license (mDL) issuer validation
255+
- EUDI wallet mDOC credential issuance
256+
- Any OpenID4VCI issuer publishing IACA certificates
257+
223258
### Static Trust Registries
224259

225260
The `pkg/registry/static` package provides simple TrustRegistry implementations for testing, development, and basic use cases:
@@ -229,20 +264,61 @@ The `pkg/registry/static` package provides simple TrustRegistry implementations
229264
| `AlwaysTrustedRegistry` | Always returns `decision=true` | Testing, development, trust-all scenarios |
230265
| `NeverTrustedRegistry` | Always returns `decision=false` | Testing trust rejection, deny-all scenarios |
231266
| `SystemCertPoolRegistry` | Validates X509 against OS CA bundle | Simple TLS trust without ETSI TSL |
267+
| `WhitelistRegistry` | URL-based whitelist with file watching | Simple issuer/verifier allowlisting |
232268

233269
```go
234270
import "github.com/sirosfoundation/go-trust/pkg/registry/static"
235271

236-
// Accept all trust requests
237-
registry := static.NewAlwaysTrustedRegistry()
272+
// Accept all trust requests (testing only!)
273+
registry := static.NewAlwaysTrustedRegistry("test-always-trusted")
238274

239-
// Reject all trust requests
240-
registry := static.NewNeverTrustedRegistry()
275+
// Reject all trust requests (testing only!)
276+
registry := static.NewNeverTrustedRegistry("test-never-trusted")
241277

242278
// Validate against system CA bundle
243-
registry := static.NewSystemCertPoolRegistry()
279+
registry, _ := static.NewSystemCertPoolRegistry(static.SystemCertPoolConfig{
280+
Name: "system-ca",
281+
Description: "System root CA certificates",
282+
})
283+
284+
// URL whitelist from config file (with auto-reload)
285+
registry, _ := static.NewWhitelistRegistryFromFile("/etc/go-trust/whitelist.yaml", true)
286+
defer registry.Close()
287+
288+
// URL whitelist configured programmatically
289+
registry := static.NewWhitelistRegistry()
290+
registry.AddIssuer("https://pid-issuer.example.com")
291+
registry.AddVerifier("https://verifier.example.com")
244292
```
245293

294+
#### WhitelistRegistry Configuration
295+
296+
The whitelist registry supports YAML or JSON configuration files:
297+
298+
```yaml
299+
# whitelist.yaml
300+
issuers:
301+
- https://pid-issuer.example.com
302+
- https://issuer.example.org
303+
- https://trusted-domain.com/* # Wildcard prefix match
304+
305+
verifiers:
306+
- https://verifier.example.com
307+
- https://rp.example.org
308+
309+
trusted_subjects:
310+
- https://any-role.example.com # Matches any role
311+
```
312+
313+
**Features:**
314+
- Role-based matching: `issuers` for credential issuers, `verifiers` for relying parties
315+
- Wildcard support: `https://example.com/*` matches any path under that domain
316+
- Global wildcard: `*` matches all subjects (use with caution)
317+
- File watching: Automatically reloads config when file changes (when `watch=true`)
318+
- Runtime updates: `AddIssuer()`, `RemoveIssuer()`, `AddVerifier()`, `RemoveVerifier()`
319+
320+
**Security Note:** WhitelistRegistry provides URL-based trust only. Signature verification must be performed at the application layer. For cryptographic trust verification, use ETSI TSL, OpenID Federation, or other advanced registries.
321+
246322
## Deployment
247323

248324
### Docker
@@ -397,6 +473,11 @@ srv := testserver.New(testserver.WithRegistry(static.NewNeverTrustedRegistry()))
397473
398474
// Test with system CA validation
399475
srv := testserver.New(testserver.WithRegistry(static.NewSystemCertPoolRegistry()))
476+
477+
// Test with specific whitelist
478+
reg := static.NewWhitelistRegistry()
479+
reg.AddIssuer("https://test-issuer.example.com")
480+
srv := testserver.New(testserver.WithRegistry(reg))
400481
```
401482

402483
## Development
@@ -430,7 +511,7 @@ go-trust/
430511
│ │ ├── oidfed/ # OpenID Federation registry
431512
│ │ ├── didweb/ # DID Web registry
432513
│ │ ├── didwebvh/ # DID Web VH registry
433-
│ │ └── static/ # Static registries (always/never/system)
514+
│ │ └── static/ # Static registries (always/never/system/whitelist)
434515
│ ├── logging/ # Structured logging
435516
│ └── testserver/ # Embedded test server
436517
├── example/ # Example configurations

example/README.md

Lines changed: 88 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,24 @@ This directory contains configuration examples for running go-trust as an AuthZE
66

77
| File | Description |
88
|------|-------------|
9-
| `config.yaml` | Server configuration file example |
9+
| `config.yaml` | Comprehensive server configuration with all registry types documented |
1010
| `docker-compose.yaml` | Docker Compose deployment |
1111
| `kubernetes.yaml` | Kubernetes deployment with Ingress and ServiceMonitor |
1212
| `prometheus.yml` | Prometheus scrape configuration |
1313

14+
## Registry Examples
15+
16+
The `config.yaml` documents all supported registry types:
17+
18+
| Registry | Resource Types | Resolution-Only | Description |
19+
|----------|---------------|-----------------|-------------|
20+
| ETSI TSL | `x5c` | No | X.509 trust via ETSI TS 119612 Trust Status Lists |
21+
| OpenID Federation | `entity_configuration`, `jwk` | Yes | Entity trust chain validation |
22+
| DID Web | `did_document`, `jwk`, `verification_method` | Yes | W3C did:web method |
23+
| DID Web VH | `did_document`, `jwk`, `verification_method` | Yes | did:webvh with verifiable history |
24+
| mDOC IACA | `x5c` | No | Dynamic IACA validation for mDOC/mDL |
25+
| Whitelist | URL-based | No | Simple URL-based trust (testing only) |
26+
1427
## Testing Examples
1528

1629
The `testing/` subdirectory contains Go code examples for integration testing:
@@ -25,11 +38,39 @@ The `testing/` subdirectory contains Go code examples for integration testing:
2538
# Build the binary
2639
make build
2740

28-
# Run with certificate bundle
41+
# Run with ETSI certificate bundle
2942
./gt --etsi-cert-bundle /path/to/trusted-certs.pem
3043

31-
# Run with config file
32-
./gt --config example/config.yaml
44+
# Run with multiple TSL files
45+
./gt --etsi-tsl-files /path/to/eu-lotl.xml,/path/to/se-tsl.xml
46+
47+
# Run with logging configuration
48+
./gt --etsi-cert-bundle certs.pem --log-level debug --log-format json
49+
50+
# Run with external URL (for .well-known discovery)
51+
./gt --etsi-cert-bundle certs.pem --external-url https://pdp.example.com
52+
```
53+
54+
### CLI Options Reference
55+
56+
```
57+
Server options:
58+
--host string API server hostname (default: 127.0.0.1)
59+
--port string API server port (default: 6001)
60+
--external-url string External URL for PDP discovery
61+
62+
ETSI TSL options:
63+
--etsi-cert-bundle string Path to PEM file with trusted CA certificates
64+
--etsi-tsl-files string Comma-separated list of local TSL XML files
65+
66+
Logging options:
67+
--log-level string debug, info, warn, error (default: info)
68+
--log-format string text or json (default: text)
69+
70+
Other:
71+
--config string Configuration file path (YAML format) - partial support
72+
--help Show help message
73+
--version Show version information
3374
```
3475

3576
### Running with Docker
@@ -64,4 +105,47 @@ tsl-tool --output trusted-certs.pem pipeline.yaml
64105
./gt --etsi-cert-bundle trusted-certs.pem
65106
```
66107

108+
## Programmatic Registry Usage
109+
110+
See the testing examples or the main [README](../README.md) for examples of using each registry type programmatically:
111+
112+
```go
113+
// ETSI TSL
114+
reg, _ := etsi.NewTSLRegistry(etsi.TSLConfig{
115+
Name: "ETSI-TSL",
116+
CertBundle: "/path/to/certs.pem",
117+
})
118+
119+
// OpenID Federation
120+
reg, _ := oidfed.NewOIDFedRegistry(oidfed.Config{
121+
Description: "OIDF Registry",
122+
TrustAnchors: []oidfed.TrustAnchorConfig{
123+
{EntityID: "https://federation.example.com"},
124+
},
125+
})
126+
127+
// DID Web
128+
reg, _ := didweb.NewDIDWebRegistry(didweb.Config{
129+
Timeout: 30 * time.Second,
130+
Description: "DID Web Registry",
131+
})
132+
133+
// DID Web VH
134+
reg, _ := didwebvh.NewDIDWebVHRegistry(didwebvh.Config{
135+
Timeout: 30 * time.Second,
136+
Description: "DID Web VH Registry",
137+
})
138+
139+
// mDOC IACA
140+
reg, _ := mdociaca.New(&mdociaca.Config{
141+
Name: "mDOC-IACA",
142+
IssuerAllowlist: []string{"https://issuer.example.com"},
143+
CacheTTL: time.Hour,
144+
})
145+
146+
// Whitelist
147+
reg, _ := static.NewWhitelistRegistryFromFile("/etc/go-trust/whitelist.yaml", true)
148+
defer reg.Close()
149+
```
150+
67151
See the main [README](../README.md) for complete documentation.

0 commit comments

Comments
 (0)