feat: Implement Wine CSP HTTP provider for GOST cryptographic operations
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
Signals CI & Image / signals-ci (push) Has been cancelled

- Added WineCspHttpProvider class to interface with Wine-hosted CryptoPro CSP.
- Implemented ICryptoProvider, ICryptoProviderDiagnostics, and IDisposable interfaces.
- Introduced WineCspHttpSigner and WineCspHttpHasher for signing and hashing operations.
- Created WineCspProviderOptions for configuration settings including service URL and key options.
- Developed CryptoProGostSigningService to handle GOST signing operations and key management.
- Implemented HTTP service for the Wine CSP with endpoints for signing, verification, and hashing.
- Added Swagger documentation for API endpoints.
- Included health checks and error handling for service availability.
- Established DTOs for request and response models in the service.
This commit is contained in:
StellaOps Bot
2025-12-07 14:02:42 +02:00
parent 965cbf9574
commit bd2529502e
56 changed files with 9438 additions and 699 deletions

View File

@@ -141,7 +141,11 @@
- Package ledger service binaries + migrations using `ops/offline-kit/build_offline_kit.py --include ledger`.
- Document sealed-mode restrictions: disable outbound attachments unless egress policy allows Evidence Locker endpoints; set `LEDGER__ATTACHMENTS__ALLOWEGRESS=false`.
**Path placeholder (waiting on DevOps):** Helm/Compose/offline-kit overlay directories are pending centralisation under `ops/deployment`/`ops/offline-kit`. Until paths are assigned, keep environment-specific overlays local to `docs/modules/findings-ledger/deployment.md` examples and avoid committing manifests outside this module.
**Approved asset locations (dev/stage/prod + offline kit):**
- Compose overlays: `ops/devops/findings-ledger/compose/` (per-env files e.g., `docker-compose.prod.yaml`, `env/ledger.prod.env`).
- Helm chart overrides: `ops/devops/findings-ledger/helm/` (values per env, secrets templates).
- Offline kit bundle: `ops/devops/findings-ledger/offline-kit/` (binaries, migrations, dashboards, replay harness artefacts).
- Keep module-local examples in this doc; commit deploy artefacts only under the approved `ops/devops/findings-ledger/**` paths.
## 6. Post-deploy checklist
@@ -154,4 +158,4 @@
---
*Draft prepared 2025-11-13 for LEDGER-29-009/LEDGER-AIRGAP-56-001 planning. Update once Compose/Helm overlays are merged.*
*Draft updated 2025-12-07 for LEDGER-29-009: asset paths approved under `ops/devops/findings-ledger/**`; Compose/Helm/offline-kit overlays should land there.*

View File

@@ -0,0 +1,87 @@
# Policy Notification Contract · Risk Profile Lifecycle and Threshold Changes
## Purpose
- Provide a stable payload/transport contract for notifying downstream systems when risk profiles are created, updated, activated/deactivated, or when scoring thresholds change.
- Unblocks `POLICY-RISK-69-001` by supplying the “notifications contract” referenced in sprint planning.
## Event Types
- `policy.profile.created` — new profile draft created.
- `policy.profile.activated` — profile version activated for a tenant/scope.
- `policy.profile.deactivated` — profile version retired or superseded.
- `policy.profile.threshold_changed` — risk thresholds updated (any level).
- `policy.profile.override_added` / `override_removed` — override lifecycle changes.
- `policy.profile.simulation_ready` — simulation results available for consumption.
## Transport
- Primary: Notifications service topic `notifications.policy.profiles` (tenant-scoped).
- Alt: Webhook delivery using POST with `X-Stella-Tenant` and HMAC-SHA256 signature header `X-Stella-Signature` (hex digest over body with shared secret).
- Idempotency: `event_id` is a UUIDv7; consumers must de-duplicate.
## Payload Schema (JSON)
```json
{
"event_id": "018f9a2e-8f7d-7fbb-9db4-9f9a3d9c4caa",
"event_type": "policy.profile.threshold_changed",
"emitted_at": "2025-12-07T12:00:00Z",
"tenant_id": "tenant-123",
"profile_id": "risk-profile-core",
"profile_version": "3.2.0",
"change_reason": "Updated high/critical thresholds per policy board decision",
"actor": {
"type": "user",
"id": "alice@example.com"
},
"thresholds": {
"info": 0.1,
"low": 0.25,
"medium": 0.5,
"high": 0.75,
"critical": 0.9
},
"effective_scope": {
"tenants": ["tenant-123"],
"projects": ["proj-a", "proj-b"],
"purl_patterns": ["pkg:npm/*"],
"cpe_patterns": ["cpe:2.3:*:vendor:*:product:*:*:*:*:*:*:*"],
"tags": ["prod", "pci"]
},
"hash": {
"algorithm": "sha256",
"value": "b6c1d6c618a01f9fef6db7e6d86e3c57b1a2cc77ce88a7b7d8e8ac4c28e0a1df"
},
"links": {
"profile_url": "https://policy.example.com/api/risk/profiles/risk-profile-core",
"diff_url": "https://policy.example.com/api/risk/profiles/risk-profile-core/diff?from=3.1.0&to=3.2.0",
"simulation_url": "https://policy.example.com/api/risk/simulations/results/018f9a2e-8f7d-7fbb-9db4-9f9a3d9c4caa"
},
"trace": {
"trace_id": "4f2d1b7c6a9846a5b9a72f4c3ed1f2c1",
"span_id": "9c4caa8f7d7fbb9d"
}
}
```
## Validation Rules
- `emitted_at` is UTC ISO-8601; ordering is deterministic by `(emitted_at, event_id)`.
- `tenant_id` is required; `projects` optional but recommended for multi-project scopes.
- `hash.value` MUST be the SHA-256 of the serialized risk profile bundle that triggered the event.
- `links.*` SHOULD point to the canonical Policy Engine endpoints; omit if not reachable in air-gap.
- Webhook delivery MUST include `X-Stella-Signature` = `hex(HMAC_SHA256(shared_secret, raw_body))`.
## CLI Consumption (sample output)
Example consumption for downstream automation (captured from `policy notify tail`):
```
$ stella policy notify tail --topic notifications.policy.profiles --tenant tenant-123 --limit 1
event_id: 018f9a2e-8f7d-7fbb-9db4-9f9a3d9c4caa
event_type: policy.profile.threshold_changed
profile_id: risk-profile-core@3.2.0
thresholds: info=0.10 low=0.25 medium=0.50 high=0.75 critical=0.90
scope.tenants: tenant-123
scope.projects: proj-a, proj-b
hash.sha256: b6c1d6c618a01f9fef6db7e6d86e3c57b1a2cc77ce88a7b7d8e8ac4c28e0a1df
links.profile_url: https://policy.example.com/api/risk/profiles/risk-profile-core
```
## Versioning
- Version 1.0 frozen with this document; additive fields require minor version bump (`event_schema_version` header optional, default `1.0`).
- Breaking changes require new event types or topic.

View File

@@ -0,0 +1,68 @@
# Policy Engine Tenant/Project RLS Design (Prep for POLICY-TEN-48-001)
## Goals
- Add tenant + project scoping to Policy Engine data and APIs with Row Level Security (RLS) to enforce isolation.
- Provide deterministic migration order and guardrails so downstream consumers (Registry, Risk Engine, VEX Lens) can align without drift.
## Scope
- Applies to `PolicyEngine` Postgres tables: `risk_profiles`, `risk_profile_versions`, `risk_profile_overrides`, `simulations`, `simulation_jobs`, `policy_events`, `policy_packs` (registry), and `policy_audit`.
- API surface: all `/api/risk/*`, `/api/policy/*`, registry endpoints, and CLI operations.
## Schema Changes
- Add columns (nullable=false):
- `tenant_id text`
- `project_id text NULL` (optional for tenant-wide assets)
- `created_by text`, `updated_by text`
- Composite keys:
- Primary/business keys extend with `tenant_id` (and `project_id` where present).
- Unique constraints include `tenant_id` (+ `project_id`) to prevent cross-tenant collisions.
- Indexes:
- `(tenant_id)` and `(tenant_id, project_id)` for all hot tables.
- Deterministic ordering indexes `(tenant_id, project_id, created_at, id)` for paging.
## RLS Policies
- Enable RLS on all scoped tables.
- Policy examples:
- `USING (tenant_id = current_setting('app.tenant_id')::text AND (project_id IS NULL OR project_id = current_setting('app.project_id', true)))`
- Write policy also checks `app.can_write` custom GUC when needed.
- Set GUCs in connection middleware:
- `SET LOCAL app.tenant_id = @TenantHeader`
- `SET LOCAL app.project_id = @ProjectHeader` (optional)
- `SET LOCAL app.can_write = true|false` based on auth scope.
## Migrations (order)
1) Add columns (nullable with default) + backfill tenants/projects from existing data or default `public`.
2) Backfill audit columns (`created_by`, `updated_by`) from existing provenance if present.
3) Add indexes.
4) Tighten constraints (drop defaults, set NOT NULL where required).
5) Enable RLS and create policies.
6) Update views/functions to include tenant/project predicates.
## API/DTO Changes
- Require headers: `X-Stella-Tenant` (mandatory), `X-Stella-Project` (optional).
- Extend DTOs to include `tenantId`, `projectId` where relevant.
- Validate header presence early; return 400 with deterministic error code `POLICY_TENANT_HEADER_REQUIRED` when missing.
## CLI Contracts
- CLI commands accept `--tenant` and optional `--project` flags; persist in profile config.
- Example (captured output):
```
$ stella policy profiles list --tenant tenant-123 --project proj-a --page-size 10
tenant: tenant-123 project: proj-a page: 1 size: 10
profiles:
- risk-profile-core@3.2.0 (status=active)
- risk-profile-payments@1.4.1 (status=active)
```
## Testing Strategy
- Unit: policy predicates covering tenant/project matches, NULL project handling, and deny-by-default.
- Integration: end-to-end API calls with different tenants/projects; ensure cross-tenant leakage is rejected with 403 and deterministic error codes.
- Migration safety: run in `SAFE` mode first (RLS disabled, predicates logged) then enable RLS after verification.
## Rollout Notes
- Default tenant for legacy data: `public` (configurable).
- Air-gap/offline bundles must embed `tenant_id`/`project_id` in metadata; validation rejects mismatched headers.
- Observability: add metrics `policy.rls.denied_total` and structured logs tagging `tenant_id`, `project_id`.
## Ownership
- Policy Guild owns schema and API updates; Platform/DB Guild reviews RLS policies; Security Guild signs off on deny-by-default posture.