337 lines
7.5 KiB
Markdown
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)
|