Files
git.stella-ops.org/docs/modules/policy/evidence-hooks.md
StellaOps Bot dfaa2079aa test
2025-12-22 09:56:20 +02:00

337 lines
7.5 KiB
Markdown

# Evidence Hooks Reference
## Overview
**Evidence Hooks** require specific attestations before an exception can be approved. This ensures exceptions are backed by verifiable proof, not just assertions.
## Hook Model
```yaml
evidenceHooks:
- hookId: "feature-flag-off"
type: FeatureFlagDisabled
description: "Feature flag must be disabled in production"
isMandatory: true
maxAge: PT24H # ISO 8601 duration
minTrustScore: 0.8
```
## Hook Types
### FeatureFlagDisabled
Requires attestation that a feature flag is disabled.
| Field | Type | Description |
|-------|------|-------------|
| flagName | string | Name of the feature flag |
| environment | string | Target environment |
| attestedAt | timestamp | When flag state was verified |
**Evidence Example:**
```json
{
"type": "FeatureFlagDisabled",
"flagName": "EXPERIMENTAL_TEMPLATE_ENGINE",
"environment": "production",
"attestedAt": "2024-12-22T10:00:00Z",
"source": "launchdarkly"
}
```
### BackportMerged
Requires attestation that a security backport was merged.
| Field | Type | Description |
|-------|------|-------------|
| prUrl | string | Pull request URL |
| commitHash | string | Merged commit hash |
| mergedAt | timestamp | When PR was merged |
**Evidence Example:**
```json
{
"type": "BackportMerged",
"prUrl": "https://github.com/org/repo/pull/123",
"commitHash": "abc123...",
"mergedAt": "2024-12-22T09:30:00Z",
"mergedBy": "security-team"
}
```
### CompensatingControl
Requires attestation of a compensating security control.
| Field | Type | Description |
|-------|------|-------------|
| controlType | string | Type of control (WAF, RASP, etc.) |
| controlId | string | Control identifier |
| description | string | How control mitigates risk |
**Evidence Example:**
```json
{
"type": "CompensatingControl",
"controlType": "WAF",
"controlId": "rule-block-template-injection",
"description": "WAF rule blocks template injection patterns",
"deployedAt": "2024-12-22T08:00:00Z"
}
```
### SecurityReview
Requires attestation of completed security review.
| Field | Type | Description |
|-------|------|-------------|
| reviewId | string | Review identifier |
| reviewer | string | Who performed review |
| outcome | string | Review outcome |
### RuntimeMitigation
Requires attestation of runtime mitigation in place.
| Field | Type | Description |
|-------|------|-------------|
| mitigationType | string | Type of mitigation |
| configuration | object | Mitigation configuration |
### WAFRuleDeployed
Requires attestation of WAF rule deployment.
| Field | Type | Description |
|-------|------|-------------|
| ruleId | string | WAF rule identifier |
| provider | string | WAF provider |
| deployedAt | timestamp | Deployment time |
### CustomAttestation
Generic attestation for custom evidence types.
| Field | Type | Description |
|-------|------|-------------|
| predicateType | string | Custom predicate type URI |
| payload | object | Custom payload |
## Validation Rules
### Freshness (maxAge)
Evidence must be recent enough:
```yaml
maxAge: PT24H # 24 hours
maxAge: P7D # 7 days
maxAge: PT1H # 1 hour
```
If evidence is older than maxAge, it's marked as **Expired**.
### Trust Score (minTrustScore)
Evidence source must meet minimum trust:
```yaml
minTrustScore: 0.8 # 80% trust required
```
Trust scores come from the source registry.
### Signature Verification
If evidence includes a DSSE envelope, signature is verified:
```json
{
"content": { ... },
"dsseEnvelope": "eyJwYXlsb2FkIjoi...",
"signatureVerified": true
}
```
### Schema Validation
Custom attestations can require schema validation:
```yaml
validationSchema: "https://stellaops.io/schemas/evidence/feature-flag/v1"
```
## Validation States
| State | Description |
|-------|-------------|
| `Pending` | Evidence submitted, not yet validated |
| `Valid` | Evidence passes all validation |
| `Invalid` | Evidence fails validation |
| `Expired` | Evidence older than maxAge |
| `InsufficientTrust` | Source trust score too low |
## Submission Flow
```
1. User selects exception to approve
2. System shows required evidence hooks
3. User submits evidence for each hook:
a. Upload attestation file
b. Link to external system
c. Generate attestation in-place
4. System validates each submission
5. If all mandatory hooks satisfied:
a. Exception can be approved
6. If any mandatory hooks unsatisfied:
a. Approval blocked
b. Missing evidence highlighted
```
## API Endpoints
### POST /exceptions/{id}/evidence
Submit evidence for a hook.
**Request:**
```json
{
"hookId": "feature-flag-off",
"type": "FeatureFlagDisabled",
"reference": "launchdarkly://flags/EXPERIMENTAL_TEMPLATE_ENGINE",
"content": {
"flagName": "EXPERIMENTAL_TEMPLATE_ENGINE",
"environment": "production",
"state": "off"
}
}
```
### GET /exceptions/{id}/evidence
Get all submitted evidence for an exception.
### GET /exceptions/{id}/evidence/status
Get evidence satisfaction status.
**Response:**
```json
{
"isSatisfied": false,
"missingEvidence": [
{
"hookId": "backport-merged",
"type": "BackportMerged",
"description": "Security backport must be merged"
}
],
"validEvidence": [
{
"hookId": "feature-flag-off",
"type": "FeatureFlagDisabled",
"validatedAt": "2024-12-22T10:00:00Z"
}
]
}
```
## UI Integration
### Evidence Requirements Panel
Shows required evidence with status:
```
Evidence Requirements
---------------------
[x] Feature flag disabled (Verified 2h ago)
[ ] Backport PR merged (Missing)
[x] WAF rule deployed (Verified 1d ago)
[Submit Missing Evidence]
```
### Evidence Upload Modal
For each hook type:
1. File upload for attestations
2. URL input for external references
3. Form for in-place attestation
### Blocking Indicator
When evidence is missing:
- Approve button disabled
- Clear message: "Cannot approve: missing evidence"
- Link to evidence requirements
## Best Practices
1. **Mandatory = Critical**: Only mark truly required evidence as mandatory
2. **Reasonable maxAge**: Balance freshness with operational burden
3. **Trust Scores**: Configure source trust appropriately
4. **Documentation**: Document what each evidence type means
5. **Automation**: Integrate with systems to auto-generate attestations
## DSSE Attestation Format
Evidence can be wrapped in DSSE for integrity:
```json
{
"payloadType": "application/vnd.stellaops.evidence+json",
"payload": "<base64-encoded-evidence>",
"signatures": [
{
"keyid": "key-123",
"sig": "<base64-signature>"
}
]
}
```
## Example Hook Configurations
### Critical CVE Policy
```yaml
evidenceHooks:
- hookId: "security-review"
type: SecurityReview
description: "Security team review required"
isMandatory: true
- hookId: "compensating-control"
type: CompensatingControl
description: "Compensating control must be in place"
isMandatory: true
- hookId: "stakeholder-approval"
type: CustomAttestation
description: "Business stakeholder approval"
isMandatory: true
validationSchema: "https://stellaops.io/schemas/evidence/stakeholder-approval/v1"
```
### Standard Policy
```yaml
evidenceHooks:
- hookId: "justification"
type: CustomAttestation
description: "Written justification required"
isMandatory: true
- hookId: "compensating-control"
type: CompensatingControl
description: "Compensating control recommended"
isMandatory: false
```
## Related Documentation
- [Recheck Policy](./recheck-policy.md)
- [Exception Workflow](../../api/exceptions.md)
- [DSSE Attestations](../attestor/dsse.md)