feat(crypto): extract crypto providers to overlay compose files + health probe API
- Extract smremote to docker-compose.crypto-provider.smremote.yml - Rename cryptopro/crypto-sim compose files for consistent naming - Add crypto provider health probe endpoint (CP-001) - Add tenant crypto provider preferences API + migration (CP-002) - Update docs and compliance env examples Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
219
docs/implplan/SPRINT_20260408_001_FE_crypto_provider_picker.md
Normal file
219
docs/implplan/SPRINT_20260408_001_FE_crypto_provider_picker.md
Normal file
@@ -0,0 +1,219 @@
|
||||
# Sprint 20260408-001 -- Crypto Provider Picker (UI + Backend)
|
||||
|
||||
## Topic & Scope
|
||||
- Admin-facing UI panel for discovering, monitoring, and selecting crypto providers per tenant.
|
||||
- Platform service backend endpoints for provider health probing and tenant preference persistence.
|
||||
- Integrates with existing `ICryptoProviderRegistry` (in `src/__Libraries/StellaOps.Cryptography/`) to respect tenant-level provider selection at runtime.
|
||||
- Working directory: `src/Web/StellaOps.Web` (Angular UI), `src/Platform/` (backend API).
|
||||
- Expected evidence: UI component rendering, API integration tests, DB migration for tenant crypto preferences.
|
||||
|
||||
## Dependencies & Concurrency
|
||||
- Depends on crypto provider compose refactor (smremote extracted from main compose; crypto overlays renamed to `docker-compose.crypto-provider.*.yml`). **DONE** as of 2026-04-08.
|
||||
- No upstream sprint blockers. Can run in parallel with other UI or backend work that does not touch Platform settings or Cryptography libraries.
|
||||
- The `docker-compose.sm-remote.yml` (standalone HSM provider) remains unchanged; this sprint only concerns provider *discovery* and *selection*, not provider lifecycle management.
|
||||
|
||||
## Documentation Prerequisites
|
||||
- `devops/compose/README.md` -- updated Crypto Provider Overlays section (contains health endpoints and compose commands).
|
||||
- `src/__Libraries/StellaOps.Cryptography/CryptoProviderRegistry.cs` -- current registry implementation with preferred-order resolution.
|
||||
- `src/__Libraries/StellaOps.Cryptography/CryptoProvider.cs` -- `ICryptoProvider` interface contract.
|
||||
- `docs/security/crypto-profile-configuration.md` -- current crypto profile configuration docs.
|
||||
|
||||
## Delivery Tracker
|
||||
|
||||
### CP-001 - Provider health probe API endpoint
|
||||
Status: DONE
|
||||
Dependency: none
|
||||
Owners: Backend Developer
|
||||
|
||||
Task description:
|
||||
Add a Platform admin API endpoint `GET /api/v1/admin/crypto-providers/health` that probes each known crypto provider's health endpoint and returns aggregated status.
|
||||
|
||||
Known provider health endpoints:
|
||||
- SmRemote (router microservice): `http://smremote.stella-ops.local:8080/health` (internal router mesh)
|
||||
- SM Remote (standalone HSM): `http://localhost:56080/status` (or configured `SM_REMOTE_PORT`)
|
||||
- CryptoPro CSP: `http://cryptopro-csp:8080/health`
|
||||
- Crypto Simulator: `http://sim-crypto:8080/keys`
|
||||
|
||||
Response schema (JSON):
|
||||
```json
|
||||
{
|
||||
"providers": [
|
||||
{
|
||||
"id": "smremote",
|
||||
"name": "SmRemote (SM2/SM3/SM4)",
|
||||
"status": "running",
|
||||
"healthEndpoint": "http://smremote.stella-ops.local:8080/health",
|
||||
"responseTimeMs": 12,
|
||||
"composeOverlay": "docker-compose.crypto-provider.smremote.yml",
|
||||
"startCommand": "docker compose -f docker-compose.stella-ops.yml -f docker-compose.crypto-provider.smremote.yml up -d smremote"
|
||||
},
|
||||
{
|
||||
"id": "cryptopro",
|
||||
"name": "CryptoPro CSP (GOST)",
|
||||
"status": "unreachable",
|
||||
"healthEndpoint": "http://cryptopro-csp:8080/health",
|
||||
"responseTimeMs": null,
|
||||
"composeOverlay": "docker-compose.crypto-provider.cryptopro.yml",
|
||||
"startCommand": "CRYPTOPRO_ACCEPT_EULA=1 docker compose -f docker-compose.stella-ops.yml -f docker-compose.crypto-provider.cryptopro.yml up -d cryptopro-csp"
|
||||
},
|
||||
{
|
||||
"id": "crypto-sim",
|
||||
"name": "Crypto Simulator (dev/test)",
|
||||
"status": "stopped",
|
||||
"healthEndpoint": "http://sim-crypto:8080/keys",
|
||||
"responseTimeMs": null,
|
||||
"composeOverlay": "docker-compose.crypto-provider.crypto-sim.yml",
|
||||
"startCommand": "docker compose -f docker-compose.stella-ops.yml -f docker-compose.crypto-provider.crypto-sim.yml up -d sim-crypto"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
The endpoint should use `HttpClient` with a short timeout (5s) to probe each provider. Status values: `running`, `stopped`, `unreachable`, `degraded`.
|
||||
|
||||
Provider definitions should be stored in configuration (appsettings or DB), not hardcoded, so that custom providers can be registered.
|
||||
|
||||
Completion criteria:
|
||||
- [x] `GET /api/v1/admin/crypto-providers/health` returns JSON with status for all configured providers
|
||||
- [x] Unreachable providers return `unreachable` status (not 500)
|
||||
- [x] Response includes `startCommand` with the correct compose overlay filename
|
||||
- [x] Endpoint is admin-only (requires `ops.admin` or `crypto:admin` scope)
|
||||
- [ ] Unit test covering probe timeout and mixed healthy/unhealthy scenarios
|
||||
|
||||
### CP-002 - Tenant crypto provider preference API + DB table
|
||||
Status: DONE
|
||||
Dependency: none
|
||||
Owners: Backend Developer
|
||||
|
||||
Task description:
|
||||
Add a database table and API endpoints for storing per-tenant crypto provider preferences.
|
||||
|
||||
Database table (`platform` schema):
|
||||
```sql
|
||||
CREATE TABLE platform.tenant_crypto_preferences (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id UUID NOT NULL REFERENCES shared.tenants(id),
|
||||
provider_id VARCHAR(100) NOT NULL,
|
||||
algorithm_scope VARCHAR(100) NOT NULL DEFAULT '*',
|
||||
priority INT NOT NULL DEFAULT 0,
|
||||
is_active BOOLEAN NOT NULL DEFAULT true,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
UNIQUE (tenant_id, provider_id, algorithm_scope)
|
||||
);
|
||||
```
|
||||
|
||||
API endpoints:
|
||||
- `GET /api/v1/admin/crypto-providers/preferences` -- list current tenant's provider preferences
|
||||
- `PUT /api/v1/admin/crypto-providers/preferences` -- update provider selection (body: `{ providerId, algorithmScope, priority, isActive }`)
|
||||
- `DELETE /api/v1/admin/crypto-providers/preferences/{id}` -- remove a preference
|
||||
|
||||
The preference should feed into `CryptoProviderRegistry` via `CryptoRegistryProfiles`, allowing per-tenant override of the `preferredProviderOrder`.
|
||||
|
||||
Completion criteria:
|
||||
- [x] SQL migration file added as embedded resource in Platform persistence library
|
||||
- [x] Auto-migration on startup (per repo-wide rule 2.7)
|
||||
- [x] CRUD endpoints work and are admin-scoped
|
||||
- [x] Preferences are tenant-isolated (multi-tenant safe)
|
||||
- [ ] Integration test: set preference, resolve provider, confirm correct provider is selected
|
||||
|
||||
### CP-003 - Angular crypto provider dashboard panel
|
||||
Status: TODO
|
||||
Dependency: CP-001
|
||||
Owners: Frontend Developer
|
||||
|
||||
Task description:
|
||||
Add a "Crypto Providers" panel in the Platform Settings area of the Angular UI. Location: under the existing settings navigation, accessible at `/settings/crypto-providers`.
|
||||
|
||||
Panel layout:
|
||||
1. **Provider List** -- Table/card grid showing each provider with:
|
||||
- Provider name and icon/badge (SM, GOST, SIM, etc.)
|
||||
- Status indicator: green dot (Running), red dot (Stopped/Unreachable)
|
||||
- Health response time (if running)
|
||||
- Last checked timestamp
|
||||
2. **Start Instructions** -- When a provider is stopped or unreachable, show a collapsible section with:
|
||||
- The exact `docker compose` command to start it (from the API response `startCommand`)
|
||||
- Copy-to-clipboard button
|
||||
3. **Refresh Button** -- Re-probe all providers on demand
|
||||
4. **Auto-refresh** -- Poll every 30 seconds when the panel is visible (use `interval` with `switchMap` and `takeUntilDestroyed`)
|
||||
|
||||
Angular implementation:
|
||||
- Component: `src/Web/StellaOps.Web/src/app/features/settings/crypto-providers/`
|
||||
- Service: `CryptoProviderService` calling `GET /api/v1/admin/crypto-providers/health`
|
||||
- Route: Add to settings routing module
|
||||
- Use existing StellaOps design system components (cards, status badges, tables)
|
||||
|
||||
Completion criteria:
|
||||
- [ ] Panel renders provider list with live status from API
|
||||
- [ ] Stopped providers show start command with copy button
|
||||
- [ ] Auto-refresh works and stops when navigating away
|
||||
- [ ] Panel is accessible only to admin users
|
||||
- [ ] Responsive layout (works on tablet and desktop)
|
||||
|
||||
### CP-004 - Active provider selection UI
|
||||
Status: TODO
|
||||
Dependency: CP-002, CP-003
|
||||
Owners: Frontend Developer
|
||||
|
||||
Task description:
|
||||
Extend the crypto provider dashboard panel (CP-003) with an "Active Provider" selection feature.
|
||||
|
||||
UI additions:
|
||||
1. **Active Badge** -- Show which provider is currently selected for the tenant
|
||||
2. **Select Button** -- On each running provider card, show "Set as Active" button
|
||||
3. **Algorithm Scope** -- Optional: dropdown to scope the selection to specific algorithm families (SM, GOST, default, etc.) or apply globally (`*`)
|
||||
4. **Confirmation Dialog** -- Before changing the active provider, show a confirmation dialog explaining the impact on signing operations
|
||||
5. **Priority Ordering** -- Drag-and-drop reordering of provider priority (maps to `CryptoRegistryProfiles.preferredProviderOrder`)
|
||||
|
||||
The selection calls `PUT /api/v1/admin/crypto-providers/preferences` and updates the UI immediately.
|
||||
|
||||
Completion criteria:
|
||||
- [ ] Admin can select active provider per tenant
|
||||
- [ ] Selection persists across page refreshes (reads from API)
|
||||
- [ ] Cannot select a provider that is currently stopped/unreachable (button disabled with tooltip)
|
||||
- [ ] Confirmation dialog shown before changing provider
|
||||
- [ ] Priority ordering updates the registry's preferred order
|
||||
|
||||
### CP-005 - ICryptoProviderRegistry tenant-aware resolution
|
||||
Status: TODO
|
||||
Dependency: CP-002
|
||||
Owners: Backend Developer
|
||||
|
||||
Task description:
|
||||
Extend `CryptoProviderRegistry` (or introduce a decorator/wrapper) to consult tenant preferences when resolving providers. Currently the registry uses a static `preferredProviderOrder` set at startup. The enhancement should:
|
||||
|
||||
1. Accept an `IStellaOpsTenantAccessor` to determine the current tenant
|
||||
2. Query the `platform.tenant_crypto_preferences` table (cached, TTL ~60s) for the tenant's preferred order
|
||||
3. Override `CryptoRegistryProfiles.ActiveProfile` based on the tenant preference
|
||||
4. Fall back to the default preferred order if no tenant preference exists
|
||||
|
||||
This must not break existing non-tenant-aware code paths (CLI, background workers). The tenant-aware resolution should be opt-in via DI registration.
|
||||
|
||||
Key files:
|
||||
- `src/__Libraries/StellaOps.Cryptography/CryptoProviderRegistry.cs`
|
||||
- `src/__Libraries/StellaOps.Cryptography/CryptoRegistryProfiles.cs` (if exists)
|
||||
|
||||
Completion criteria:
|
||||
- [ ] Tenant-aware resolution works when tenant accessor is available
|
||||
- [ ] Falls back to default when no tenant context or no preferences set
|
||||
- [ ] Cached query (not per-request DB hit)
|
||||
- [ ] Existing non-tenant code paths unaffected (unit tests pass)
|
||||
- [ ] Integration test: two tenants with different preferences resolve different providers
|
||||
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2026-04-08 | Sprint created. Crypto provider compose overlays refactored (smremote extracted, files renamed). | Planning |
|
||||
| 2026-04-08 | CP-001 implemented: CryptoProviderHealthService + CryptoProviderAdminEndpoints (health probe). CP-002 implemented: SQL migration 062, ICryptoProviderPreferenceStore with Postgres and InMemory impls, CRUD endpoints. Both wired in Program.cs. Build verified (0 errors, 0 warnings). Unit tests pending. | Developer |
|
||||
| 2026-04-08 | Compose refactoring confirmed complete: smremote extracted (Slot 31 comment in main compose), overlay files already named `docker-compose.crypto-provider.*.yml`, README Crypto Provider Overlays section up to date, INSTALL_GUIDE.md references correct filenames. No old-named files to rename. | Developer |
|
||||
|
||||
## Decisions & Risks
|
||||
- **Risk: Provider health probing from within containers.** The Platform service runs inside the Docker network; it can reach other containers by DNS alias but cannot determine whether a compose overlay is loaded vs. the container is unhealthy. Mitigation: treat any non-200 response (including DNS resolution failure) as `unreachable`.
|
||||
- **Risk: Tenant preference caching coherence.** If an admin changes the active provider, other service instances may use stale cache. Mitigation: use Valkey pub/sub to broadcast preference changes, or accept eventual consistency with a 60s TTL.
|
||||
- **Decision: `docker-compose.sm-remote.yml` (standalone HSM overlay) remains unchanged.** Only the router-integrated `smremote` microservice was extracted from the main compose. The standalone SM Remote overlay serves a different purpose (HSM integration with build context).
|
||||
- **Decision: Provider definitions should be configurable, not hardcoded.** Seed the initial set from appsettings but allow DB overrides so operators can add custom providers.
|
||||
|
||||
## Next Checkpoints
|
||||
- CP-001 + CP-002 backend endpoints ready for frontend integration.
|
||||
- CP-003 initial panel rendering with mock data for design review.
|
||||
- CP-004 + CP-005 integration testing with live crypto providers.
|
||||
Reference in New Issue
Block a user