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.
This commit is contained in:
@@ -31,7 +31,7 @@ B --> E[DSSE Envelope]
|
||||
C --> F[Feedser Snapshot Export]
|
||||
C --> G[Policy/Lattice Bundle]
|
||||
D --> H[DSSE Outputs (SBOM, Findings, VEX)]
|
||||
E --> I[MongoDB: replay_runs]
|
||||
E --> I[PostgreSQL: replay_runs]
|
||||
C --> J[Blob Store: Input/Output Bundles]
|
||||
````
|
||||
|
||||
@@ -98,60 +98,60 @@ C --> J[Blob Store: Input/Output Bundles]
|
||||
],
|
||||
"trustProfile": "sha256:..."
|
||||
},
|
||||
"outputs": {
|
||||
"sbomHash": "sha256:...",
|
||||
"findingsHash": "sha256:...",
|
||||
"vexHash": "sha256:...",
|
||||
"logHash": "sha256:..."
|
||||
},
|
||||
"reachability": {
|
||||
"graphs": [
|
||||
{
|
||||
"kind": "static",
|
||||
"analyzer": "scanner/java@sha256:...",
|
||||
"casUri": "cas://replay/scan-123/reachability/static-graph.tar.zst",
|
||||
"sha256": "abc123"
|
||||
},
|
||||
{
|
||||
"kind": "framework",
|
||||
"analyzer": "scanner/framework@sha256:...",
|
||||
"casUri": "cas://replay/scan-123/reachability/framework-graph.tar.zst",
|
||||
"sha256": "def456"
|
||||
}
|
||||
],
|
||||
"runtimeTraces": [
|
||||
{
|
||||
"source": "zastava",
|
||||
"casUri": "cas://replay/scan-123/reachability/runtime-trace.ndjson.zst",
|
||||
"sha256": "feedface",
|
||||
"recordedAt": "2025-11-07T11:10:00Z"
|
||||
}
|
||||
]
|
||||
},
|
||||
"provenance": {
|
||||
"signer": "scanner.authority",
|
||||
"dsseEnvelopeHash": "sha256:...",
|
||||
"rekorEntry": "optional"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 Reachability Section
|
||||
|
||||
The optional `reachability` block captures the inputs needed to replay explainability decisions:
|
||||
|
||||
| Field | Description |
|
||||
|-------|-------------|
|
||||
| `reachability.graphs[]` | References to static/framework callgraph bundles. Each entry records the producing analyzer (`analyzer`/`version`), the CAS URI under `cas://replay/<scan-id>/reachability/graphs/`, and the SHA-256 digest of the tarball. |
|
||||
| `reachability.runtimeTraces[]` | References to runtime observation bundles (e.g., Zastava ND-JSON traces). Each item stores the emitting source, CAS URI (typically `cas://replay/<scan-id>/reachability/traces/`), SHA-256, and capture timestamp. |
|
||||
|
||||
Replay engines MUST verify every referenced artifact hash before re-evaluating reachability. Missing graphs downgrade affected signals to `reachability:unknown` and should raise policy warnings.
|
||||
|
||||
Producer note: default clock values in `StellaOps.Replay.Core` are `UnixEpoch` to avoid hidden time drift; producers MUST set `scan.time` and `reachability.runtimeTraces[].recordedAt` explicitly.
|
||||
|
||||
---
|
||||
|
||||
## 4. Deterministic Execution Rules
|
||||
"outputs": {
|
||||
"sbomHash": "sha256:...",
|
||||
"findingsHash": "sha256:...",
|
||||
"vexHash": "sha256:...",
|
||||
"logHash": "sha256:..."
|
||||
},
|
||||
"reachability": {
|
||||
"graphs": [
|
||||
{
|
||||
"kind": "static",
|
||||
"analyzer": "scanner/java@sha256:...",
|
||||
"casUri": "cas://replay/scan-123/reachability/static-graph.tar.zst",
|
||||
"sha256": "abc123"
|
||||
},
|
||||
{
|
||||
"kind": "framework",
|
||||
"analyzer": "scanner/framework@sha256:...",
|
||||
"casUri": "cas://replay/scan-123/reachability/framework-graph.tar.zst",
|
||||
"sha256": "def456"
|
||||
}
|
||||
],
|
||||
"runtimeTraces": [
|
||||
{
|
||||
"source": "zastava",
|
||||
"casUri": "cas://replay/scan-123/reachability/runtime-trace.ndjson.zst",
|
||||
"sha256": "feedface",
|
||||
"recordedAt": "2025-11-07T11:10:00Z"
|
||||
}
|
||||
]
|
||||
},
|
||||
"provenance": {
|
||||
"signer": "scanner.authority",
|
||||
"dsseEnvelopeHash": "sha256:...",
|
||||
"rekorEntry": "optional"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 Reachability Section
|
||||
|
||||
The optional `reachability` block captures the inputs needed to replay explainability decisions:
|
||||
|
||||
| Field | Description |
|
||||
|-------|-------------|
|
||||
| `reachability.graphs[]` | References to static/framework callgraph bundles. Each entry records the producing analyzer (`analyzer`/`version`), the CAS URI under `cas://replay/<scan-id>/reachability/graphs/`, and the SHA-256 digest of the tarball. |
|
||||
| `reachability.runtimeTraces[]` | References to runtime observation bundles (e.g., Zastava ND-JSON traces). Each item stores the emitting source, CAS URI (typically `cas://replay/<scan-id>/reachability/traces/`), SHA-256, and capture timestamp. |
|
||||
|
||||
Replay engines MUST verify every referenced artifact hash before re-evaluating reachability. Missing graphs downgrade affected signals to `reachability:unknown` and should raise policy warnings.
|
||||
|
||||
Producer note: default clock values in `StellaOps.Replay.Core` are `UnixEpoch` to avoid hidden time drift; producers MUST set `scan.time` and `reachability.runtimeTraces[].recordedAt` explicitly.
|
||||
|
||||
---
|
||||
|
||||
## 4. Deterministic Execution Rules
|
||||
|
||||
### 4.1 Environment Normalization
|
||||
|
||||
@@ -171,19 +171,19 @@ Producer note: default clock values in `StellaOps.Replay.Core` are `UnixEpoch` t
|
||||
* Parallel jobs: ordered reduction by subject path.
|
||||
* Temporary directories: ephemeral but deterministic hash seeds.
|
||||
|
||||
### 4.3 Feeds & Policies
|
||||
|
||||
* All network I/O disabled; feeds must be read from snapshot bundles.
|
||||
* Policies and suppressions must resolve by hash, not name.
|
||||
|
||||
### 4.4 Library hooks (StellaOps.Replay.Core)
|
||||
|
||||
Use the shared helpers in `src/__Libraries/StellaOps.Replay.Core` to keep outputs deterministic:
|
||||
|
||||
- `CanonicalJson.Serialize(...)` → lexicographic key ordering with relaxed escaping, arrays preserved as-is.
|
||||
- `DeterministicHash.Sha256Hex(...)` and `DeterministicHash.MerkleRootHex(...)` → lowercase digests and stable Merkle roots for bundle manifests.
|
||||
- `DssePayloadBuilder.BuildUnsigned(...)` → DSSE payloads for replay manifests using payload type `application/vnd.stellaops.replay+json`.
|
||||
- `ReplayManifestExtensions.ComputeCanonicalSha256()` → convenience for CAS naming of manifest blobs.
|
||||
### 4.3 Feeds & Policies
|
||||
|
||||
* All network I/O disabled; feeds must be read from snapshot bundles.
|
||||
* Policies and suppressions must resolve by hash, not name.
|
||||
|
||||
### 4.4 Library hooks (StellaOps.Replay.Core)
|
||||
|
||||
Use the shared helpers in `src/__Libraries/StellaOps.Replay.Core` to keep outputs deterministic:
|
||||
|
||||
- `CanonicalJson.Serialize(...)` → lexicographic key ordering with relaxed escaping, arrays preserved as-is.
|
||||
- `DeterministicHash.Sha256Hex(...)` and `DeterministicHash.MerkleRootHex(...)` → lowercase digests and stable Merkle roots for bundle manifests.
|
||||
- `DssePayloadBuilder.BuildUnsigned(...)` → DSSE payloads for replay manifests using payload type `application/vnd.stellaops.replay+json`.
|
||||
- `ReplayManifestExtensions.ComputeCanonicalSha256()` → convenience for CAS naming of manifest blobs.
|
||||
|
||||
---
|
||||
|
||||
@@ -193,7 +193,7 @@ Use the shared helpers in `src/__Libraries/StellaOps.Replay.Core` to keep output
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"payloadType": "application/vnd.stellaops.replay+json",
|
||||
"payloadType": "application/vnd.stellaops.replay+json",
|
||||
"payload": "<base64-encoded canonical JSON>",
|
||||
"signatures": [
|
||||
{ "keyid": "authority-root-fips", "sig": "..." },
|
||||
@@ -204,16 +204,16 @@ Use the shared helpers in `src/__Libraries/StellaOps.Replay.Core` to keep output
|
||||
|
||||
### 5.2 Verification Steps
|
||||
|
||||
1. Decode payload → verify canonical form.
|
||||
2. Verify each signature chain against RootPack (offline trust anchors).
|
||||
3. Recompute hash and compare to `dsseEnvelopeHash` in manifest.
|
||||
4. Optionally verify Rekor inclusion proof.
|
||||
|
||||
### 5.3 Default payload type
|
||||
|
||||
Replay DSSE envelopes emitted by `DssePayloadBuilder` use payload type `application/vnd.stellaops.replay+json`. Consumers should treat this as canonical unless a future manifest revision increments the schema and payload type together.
|
||||
|
||||
---
|
||||
1. Decode payload → verify canonical form.
|
||||
2. Verify each signature chain against RootPack (offline trust anchors).
|
||||
3. Recompute hash and compare to `dsseEnvelopeHash` in manifest.
|
||||
4. Optionally verify Rekor inclusion proof.
|
||||
|
||||
### 5.3 Default payload type
|
||||
|
||||
Replay DSSE envelopes emitted by `DssePayloadBuilder` use payload type `application/vnd.stellaops.replay+json`. Consumers should treat this as canonical unless a future manifest revision increments the schema and payload type together.
|
||||
|
||||
---
|
||||
|
||||
## 6. CLI Interface
|
||||
|
||||
@@ -267,7 +267,7 @@ Shows field-level differences (feed snapshot, tool, or policy hash).
|
||||
|
||||
---
|
||||
|
||||
## 7. MongoDB Schema
|
||||
## 7. PostgreSQL Schema
|
||||
|
||||
### 7.1 `replay_runs`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user