- Introduced AuthorityAdvisoryAiOptions and related classes for managing advisory AI configurations, including remote inference options and tenant-specific settings. - Added AuthorityApiLifecycleOptions to control API lifecycle settings, including legacy OAuth endpoint configurations. - Implemented validation and normalization methods for both advisory AI and API lifecycle options to ensure proper configuration. - Created AuthorityNotificationsOptions and its related classes for managing notification settings, including ack tokens, webhooks, and escalation options. - Developed IssuerDirectoryClient and related models for interacting with the issuer directory service, including caching mechanisms and HTTP client configurations. - Added support for dependency injection through ServiceCollectionExtensions for the Issuer Directory Client. - Updated project file to include necessary package references for the new Issuer Directory Client library.
5.6 KiB
5.6 KiB
Issuer Directory Architecture
Status: Initial service scaffold (Sprint 100 – Identity & Signing)
1. Purpose
Issuer Directory centralises trusted VEX/CSAF publisher metadata so downstream services (VEX Lens, Excititor, Policy Engine) can resolve issuer identity, active keys, and trust weights. The initial milestone delivers tenant-scoped CRUD APIs with audit logging plus bootstrap import for CSAF publishers.
2. Runtime Topology
- Service name:
stellaops/issuer-directory - Framework: ASP.NET Core minimal APIs (
net10.0) - Persistence: MongoDB (
issuer-directory.issuers,issuer-directory.issuer_keys,issuer-directory.issuer_audit) - AuthZ: StellaOps resource server scopes (
issuer-directory:read,issuer-directory:write,issuer-directory:admin) - Audit: Every create/update/delete emits an audit record with actor, reason, and context.
- Bootstrap: On startup, the service imports
data/csaf-publishers.jsoninto the global tenant (@global) and records aseededaudit the first time each publisher is added. - Key lifecycle: API validates Ed25519 public keys, X.509 certificates, and DSSE public keys, enforces future expiries, deduplicates fingerprints, and records audit entries for create/rotate/revoke actions.
Clients ──> Authority (DPoP/JWT) ──> IssuerDirectory WebService ──> MongoDB
│
└─> Audit sink (Mongo)
3. Configuration
Configuration is resolved via IssuerDirectoryWebServiceOptions (section name IssuerDirectory). The default YAML sample lives at etc/issuer-directory.yaml.sample and exposes:
IssuerDirectory:
telemetry:
minimumLogLevel: Information
authority:
enabled: true
issuer: https://authority.example.com/realms/stellaops
requireHttpsMetadata: true
audiences:
- stellaops-platform
readScope: issuer-directory:read
writeScope: issuer-directory:write
adminScope: issuer-directory:admin
tenantHeader: X-StellaOps-Tenant
seedCsafPublishers: true
csafSeedPath: data/csaf-publishers.json
Mongo:
connectionString: mongodb://localhost:27017
database: issuer-directory
issuersCollection: issuers
issuerKeysCollection: issuer_keys
auditCollection: issuer_audit
4. API Surface (v0)
| Method | Route | Scope | Description |
|---|---|---|---|
GET |
/issuer-directory/issuers |
issuer-directory:read |
List tenant issuers (optionally include global seeds). |
GET |
/issuer-directory/issuers/{id} |
issuer-directory:read |
Fetch a single issuer by identifier. |
POST |
/issuer-directory/issuers |
issuer-directory:write |
Create a tenant issuer. Requires X-StellaOps-Tenant header and optional X-StellaOps-Reason. |
PUT |
/issuer-directory/issuers/{id} |
issuer-directory:write |
Update issuer metadata/endpoints/tags. |
DELETE |
/issuer-directory/issuers/{id} |
issuer-directory:admin |
Delete issuer (records audit). |
GET |
/issuer-directory/issuers/{id}/keys |
issuer-directory:read |
List issuer keys (tenant + optional @global seeds). |
POST |
/issuer-directory/issuers/{id}/keys |
issuer-directory:write |
Add a signing key (validates format, deduplicates fingerprint, audits). |
POST |
/issuer-directory/issuers/{id}/keys/{keyId}/rotate |
issuer-directory:write |
Retire an active key and create a replacement atomically. |
DELETE |
/issuer-directory/issuers/{id}/keys/{keyId} |
issuer-directory:admin |
Revoke a key (status → revoked, audit logged). |
Payloads follow the contract in Contracts/IssuerDtos.cs and align with domain types (IssuerRecord, IssuerMetadata, IssuerEndpoint).
5. Dependencies & Reuse
StellaOps.IssuerDirectory.Core— domain model (IssuerRecord,IssuerKeyRecord) + application services.StellaOps.IssuerDirectory.Infrastructure— MongoDB persistence, audit sink, seed loader.StellaOps.IssuerDirectory.WebService— minimal API host, authentication wiring.- Shared libraries:
StellaOps.Configuration,StellaOps.Auth.ServerIntegration.
6. Testing
- Unit coverage for issuer CRUD (
IssuerDirectoryServiceTests) and key lifecycle (IssuerKeyServiceTests) inStellaOps.IssuerDirectory.Core.Tests. - Test infrastructure leverages
FakeTimeProviderfor deterministic timestamps and in-memory fakes for repository + audit sink.
7. Observability
- Metrics.
issuer_directory_changes_total(labels:tenant,issuer,action) tracks issuer create/update/delete events;issuer_directory_key_operations_total(labels:tenant,issuer,operation,key_type) covers key create/rotate/revoke flows;issuer_directory_key_validation_failures_total(labels:tenant,issuer,reason) captures validation/verification failures. The WebService exports these via OpenTelemetry (StellaOps.IssuerDirectorymeter). - Logs. Service-level
ILoggerinstrumentation records structured entries for issuer CRUD, key lifecycle operations, and validation failures; audit logs remain the authoritative trail.
8. Roadmap (next milestones)
- Key management APIs (ISSUER-30-002) — manage signing keys, enforce expiry, integrate with KMS.
- Trust weight overrides (ISSUER-30-003) — expose policy-friendly trust weighting with audit trails.
- SDK integration (ISSUER-30-004) — supply cached issuer metadata to VEX Lens and Excititor clients.
- Observability & Ops (ISSUER-30-005/006) — metrics, dashboards, deployment automation, offline kit.
Document owner: Issuer Directory Guild