Cross-cutting
Purpose¶
Shared infrastructure, security, observability, and resilience requirements that apply across all Virtufin services. Every service SHALL conform to these requirements.
Requirements¶
Requirement: Dapr Service Mesh Integration¶
Every service SHALL run with a Dapr sidecar providing state management, pub/sub messaging, and service-to-service invocation. Service code SHALL NOT connect directly to infrastructure backends.
Scenario: Sidecar communication¶
- WHEN a service needs to read/write persistent state
- THEN it SHALL use the Dapr state management API via the sidecar (HTTP
:3500or gRPC:50001)
Scenario: Event publishing¶
- WHEN a service publishes a domain event
- THEN it SHALL use the Dapr pub/sub API through the configured pubsub component
Scenario: Service invocation¶
- WHEN a service calls another service
- THEN it SHALL use Dapr service invocation or direct gRPC with mTLS; no unauthenticated calls
Requirement: Observability¶
Every service SHALL emit OpenTelemetry traces and metrics. Health checks SHALL gate readiness until the service is fully initialized.
Scenario: Distributed tracing¶
- WHEN a request is processed across multiple services
- THEN each span SHALL be exported to the configured OpenTelemetry collector with correlation context
Scenario: Liveness and readiness¶
- WHEN a service starts up and before it recovers its persistent state
- THEN the readiness health check SHALL fail, preventing traffic routing
Scenario: Startup recovery¶
- WHEN a service restarts after a crash
- THEN it SHALL restore its persisted state from the Dapr state store before marking itself healthy
Requirement: Resilience¶
All Dapr operations and external calls SHALL use retry with exponential backoff and circuit breaking.
Scenario: Transient Dapr failure¶
- WHEN a Dapr API call fails with a transient error
- THEN the operation SHALL be retried up to 3 times with exponential backoff before failing
Scenario: Persistent failure¶
- WHEN Dapr API calls consistently fail beyond a threshold
- THEN the circuit breaker SHALL open, failing fast for subsequent calls until the break duration elapses
Requirement: Security¶
All service-to-service communication SHALL be encrypted. User-supplied code execution SHALL be sandboxed. URL-based code fetching SHALL prevent SSRF.
Scenario: Service-to-service communication¶
- WHEN one service communicates with another
- THEN Dapr mTLS SHALL encrypt the connection
Scenario: SSRF prevention¶
- WHEN fetching code from a user-supplied URL
- THEN the service SHALL reject URLs targeting private IP ranges (loopback, RFC1918, link-local) unless the host is in an explicit allowlist
Requirement: Native AOT Compilation¶
Services targeting AOT-capable runtimes SHALL compile to native code. All JSON serialization SHALL use source-generated contexts.
Scenario: Build and deployment¶
- WHEN a service is built for production
- THEN it SHALL compile to a self-contained native binary with trimmed dependencies
Requirement: Configuration¶
Every service SHALL support configuration via command-line arguments, environment variables, and configuration files. Ports SHALL be configurable. Dapr component names SHALL be configurable.
Scenario: Port override¶
- WHEN the
HttpPortenvironment variable or--http-portargument is set - THEN the service SHALL listen on that port instead of the default
Scenario: Dapr component override¶
- WHEN
pubsubNameis configured - THEN the service SHALL use the named Dapr pubsub component for all pub/sub operations
Requirement: Containerization¶
Every service SHALL be containerizable as a minimal Docker image based on the chiseled runtime image.
Scenario: Docker build¶
- WHEN a service's Dockerfile is built
- THEN the resulting image SHALL contain only the native AOT binary and its runtime dependencies on a
runtime-depsbase