tests fixes and some product advisories tunes ups
This commit is contained in:
237
docs/modules/attestor/guides/identity-watchlist.md
Normal file
237
docs/modules/attestor/guides/identity-watchlist.md
Normal file
@@ -0,0 +1,237 @@
|
||||
# Identity Watchlist User Guide
|
||||
|
||||
This guide covers how to use the identity watchlist feature in Stella Ops to monitor signing activity in transparency logs.
|
||||
|
||||
## Overview
|
||||
|
||||
The identity watchlist enables proactive alerting when specific signing identities appear in Rekor transparency log entries. Use cases include:
|
||||
|
||||
- **Threat Detection**: Monitor for known malicious or compromised signing identities
|
||||
- **Compliance Monitoring**: Track when specific OIDC issuers sign artifacts
|
||||
- **Operational Awareness**: Get notified when CI/CD workflows from specific repositories sign releases
|
||||
- **Key Tracking**: Monitor usage of specific signing keys across your organization
|
||||
|
||||
## Core Concepts
|
||||
|
||||
### Watchlist Entries
|
||||
|
||||
A watchlist entry defines an identity pattern to monitor and alert configuration:
|
||||
|
||||
| Field | Description | Required |
|
||||
|-------|-------------|----------|
|
||||
| `displayName` | Human-readable label | Yes |
|
||||
| `description` | Why this identity is watched | No |
|
||||
| `issuer` | OIDC issuer URL pattern | At least one |
|
||||
| `subjectAlternativeName` | Certificate SAN pattern | of these |
|
||||
| `keyId` | Key identifier for keyful signing | three |
|
||||
| `matchMode` | Pattern matching mode | No (default: `exact`) |
|
||||
| `severity` | Alert severity level | No (default: `warning`) |
|
||||
| `enabled` | Whether entry is active | No (default: `true`) |
|
||||
| `scope` | Visibility scope | No (default: `tenant`) |
|
||||
|
||||
### Match Modes
|
||||
|
||||
| Mode | Description | Example Pattern | Matches |
|
||||
|------|-------------|-----------------|---------|
|
||||
| `exact` | Case-insensitive equality | `https://accounts.google.com` | Only that exact URL |
|
||||
| `prefix` | Starts with pattern | `https://token.actions.` | Any GitHub Actions issuer |
|
||||
| `glob` | Wildcard matching | `*@example.com` | Any email at example.com |
|
||||
| `regex` | Full regex (advanced) | `user\d+@.*` | user123@domain.com |
|
||||
|
||||
> **Note**: Regex mode has a 100ms timeout and pattern validation. Use sparingly for performance-critical environments.
|
||||
|
||||
### Severity Levels
|
||||
|
||||
| Level | Use Case | Notification Priority |
|
||||
|-------|----------|----------------------|
|
||||
| `info` | Informational tracking | Low |
|
||||
| `warning` | Unexpected but not critical (default) | Medium |
|
||||
| `critical` | Immediate attention required | High |
|
||||
|
||||
### Scope Levels
|
||||
|
||||
| Scope | Description | Who Can Create |
|
||||
|-------|-------------|----------------|
|
||||
| `tenant` | Visible only to owning tenant | Any user with `watchlist:write` |
|
||||
| `global` | Shared across all tenants | Administrators only |
|
||||
| `system` | System-managed entries | System only |
|
||||
|
||||
## CLI Usage
|
||||
|
||||
### Adding a Watchlist Entry
|
||||
|
||||
Monitor a specific OIDC issuer:
|
||||
```bash
|
||||
stella watchlist add \
|
||||
--issuer "https://token.actions.githubusercontent.com" \
|
||||
--name "GitHub Actions" \
|
||||
--severity warning \
|
||||
--description "Track all GitHub Actions signatures"
|
||||
```
|
||||
|
||||
Monitor email patterns with glob matching:
|
||||
```bash
|
||||
stella watchlist add \
|
||||
--san "*@malicious-domain.com" \
|
||||
--match-mode glob \
|
||||
--severity critical \
|
||||
--name "Malicious Domain"
|
||||
```
|
||||
|
||||
### Listing Entries
|
||||
|
||||
List all entries including global ones:
|
||||
```bash
|
||||
stella watchlist list --include-global
|
||||
```
|
||||
|
||||
Output as JSON for scripting:
|
||||
```bash
|
||||
stella watchlist list --format json
|
||||
```
|
||||
|
||||
### Testing Patterns
|
||||
|
||||
Test if an identity would trigger an alert:
|
||||
```bash
|
||||
stella watchlist test <entry-id> \
|
||||
--issuer "https://token.actions.githubusercontent.com" \
|
||||
--san "repo:org/repo:ref:refs/heads/main"
|
||||
```
|
||||
|
||||
### Managing Entries
|
||||
|
||||
Update an entry:
|
||||
```bash
|
||||
stella watchlist update <entry-id> --enabled false
|
||||
stella watchlist update <entry-id> --severity critical
|
||||
```
|
||||
|
||||
Delete an entry:
|
||||
```bash
|
||||
stella watchlist remove <entry-id>
|
||||
stella watchlist remove <entry-id> --force # Skip confirmation
|
||||
```
|
||||
|
||||
### Viewing Alerts
|
||||
|
||||
List recent alerts:
|
||||
```bash
|
||||
stella watchlist alerts --since 24h
|
||||
stella watchlist alerts --severity critical --limit 50
|
||||
```
|
||||
|
||||
## API Usage
|
||||
|
||||
### Create Entry
|
||||
|
||||
```http
|
||||
POST /api/v1/watchlist
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"displayName": "GitHub Actions Monitor",
|
||||
"issuer": "https://token.actions.githubusercontent.com",
|
||||
"matchMode": "prefix",
|
||||
"severity": "warning",
|
||||
"description": "Monitor all GitHub Actions signatures",
|
||||
"enabled": true,
|
||||
"suppressDuplicatesMinutes": 60
|
||||
}
|
||||
```
|
||||
|
||||
### List Entries
|
||||
|
||||
```http
|
||||
GET /api/v1/watchlist?includeGlobal=true
|
||||
```
|
||||
|
||||
### Test Pattern
|
||||
|
||||
```http
|
||||
POST /api/v1/watchlist/{id}/test
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"issuer": "https://token.actions.githubusercontent.com",
|
||||
"subjectAlternativeName": "repo:org/repo:ref:refs/heads/main"
|
||||
}
|
||||
```
|
||||
|
||||
## Alert Deduplication
|
||||
|
||||
To prevent alert storms, the watchlist system deduplicates alerts based on:
|
||||
|
||||
1. **Watchlist Entry ID** - Which entry triggered the alert
|
||||
2. **Identity Hash** - SHA-256 of the matched identity fields
|
||||
|
||||
Configure the deduplication window per entry with `suppressDuplicatesMinutes` (default: 60 minutes).
|
||||
|
||||
When an alert is suppressed, subsequent alerts will include a `suppressedCount` indicating how many similar alerts were skipped.
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Pattern Design
|
||||
|
||||
1. **Start specific, broaden as needed**: Begin with exact matches before using wildcards
|
||||
2. **Test before deploying**: Use the test endpoint to validate patterns
|
||||
3. **Document why**: Always include a description explaining the monitoring purpose
|
||||
4. **Use appropriate match modes**:
|
||||
- `exact` for known bad actors
|
||||
- `prefix` for issuer families (e.g., all Google issuers)
|
||||
- `glob` for email/SAN patterns
|
||||
- `regex` only when simpler modes can't express the pattern
|
||||
|
||||
### Performance Considerations
|
||||
|
||||
- Limit regex patterns to < 256 characters
|
||||
- Avoid catastrophic backtracking patterns (e.g., `(a+)+`)
|
||||
- Monitor the `attestor.watchlist.scan_latency_seconds` metric
|
||||
- Keep watchlist size reasonable (< 1000 entries per tenant)
|
||||
|
||||
### Alert Management
|
||||
|
||||
1. **Set appropriate severity**: Reserve `critical` for genuine emergencies
|
||||
2. **Configure dedup windows**: Use shorter windows (5-15 min) for critical entries
|
||||
3. **Review suppressed counts**: High counts may indicate a pattern is too broad
|
||||
4. **Route appropriately**: Use channel overrides for sensitive entries
|
||||
|
||||
## Monitoring & Metrics
|
||||
|
||||
The following OpenTelemetry metrics are exposed:
|
||||
|
||||
| Metric | Description |
|
||||
|--------|-------------|
|
||||
| `attestor.watchlist.entries_scanned_total` | Total Rekor entries processed |
|
||||
| `attestor.watchlist.matches_total{severity}` | Pattern matches by severity |
|
||||
| `attestor.watchlist.alerts_emitted_total` | Alerts sent to notification system |
|
||||
| `attestor.watchlist.alerts_suppressed_total` | Alerts suppressed by deduplication |
|
||||
| `attestor.watchlist.scan_latency_seconds` | Per-entry scan duration |
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Entry Not Matching Expected Identity
|
||||
|
||||
1. Verify the match mode is appropriate for your pattern
|
||||
2. Use the test endpoint with verbose output
|
||||
3. Check if the entry is enabled
|
||||
4. Verify case sensitivity (all modes are case-insensitive)
|
||||
|
||||
### Too Many Alerts
|
||||
|
||||
1. Increase `suppressDuplicatesMinutes`
|
||||
2. Narrow the pattern (more specific issuer, SAN prefix)
|
||||
3. Consider if the pattern is too broad
|
||||
|
||||
### Missing Alerts
|
||||
|
||||
1. Verify the entry is enabled
|
||||
2. Check if alerts are being suppressed (view suppressed count)
|
||||
3. Verify notification routing is configured
|
||||
4. Check service logs for matching errors
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Attestor Architecture](../architecture.md)
|
||||
- [Notification Templates](../../notify/templates.md)
|
||||
- [Watchlist Monitoring Runbook](../../operations/watchlist-monitoring-runbook.md)
|
||||
Reference in New Issue
Block a user