Files
git.stella-ops.org/docs/modules/issuer-directory/architecture.md
master 8bbfe4d2d2 feat(rate-limiting): Implement core rate limiting functionality with configuration, decision-making, metrics, middleware, and service registration
- Add RateLimitConfig for configuration management with YAML binding support.
- Introduce RateLimitDecision to encapsulate the result of rate limit checks.
- Implement RateLimitMetrics for OpenTelemetry metrics tracking.
- Create RateLimitMiddleware for enforcing rate limits on incoming requests.
- Develop RateLimitService to orchestrate instance and environment rate limit checks.
- Add RateLimitServiceCollectionExtensions for dependency injection registration.
2025-12-17 18:02:37 +02:00

6.4 KiB
Raw Blame History

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: PostgreSQL (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.json into the global tenant (@global) and records a seeded audit 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 ──> PostgreSQL
                                            │
                                            └─> Audit sink (PostgreSQL)

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
  Postgres:
    connectionString: Host=localhost;Port=5432;Database=issuer_directory;Username=stellaops;Password=secret
    schema: issuer_directory
    issuersTable: issuers
    issuerKeysTable: issuer_keys
    auditTable: 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).
GET /issuer-directory/issuers/{id}/trust issuer-directory:read Retrieve tenant/global trust overrides with effective weight.
PUT /issuer-directory/issuers/{id}/trust issuer-directory:write Set or update a tenant trust override; reason may be supplied in body/header.
DELETE /issuer-directory/issuers/{id}/trust issuer-directory:admin Remove a tenant trust override (falls back to global/default weight).

All write/delete operations accept an optional audit reason header (X-StellaOps-Reason) which is persisted alongside trust override changes.

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 — PostgreSQL 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) in StellaOps.IssuerDirectory.Core.Tests.
  • Test infrastructure leverages FakeTimeProvider for 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.IssuerDirectory meter).
  • Logs. Service-level ILogger instrumentation records structured entries for issuer CRUD, key lifecycle operations, and validation failures; audit logs remain the authoritative trail.

8. Roadmap (next milestones)

  1. Key management APIs (ISSUER-30-002) — manage signing keys, enforce expiry, integrate with KMS.
  2. Trust weight overrides (ISSUER-30-003) — expose policy-friendly trust weighting with audit trails.
  3. SDK integration (ISSUER-30-004) — supply cached issuer metadata to VEX Lens and Excititor clients.
  4. Observability & Ops (ISSUER-30-005/006) — metrics, dashboards, deployment automation, offline kit.

9. Operations & runbooks


Document owner: Issuer Directory Guild