Appearance
Known-Good Rule Management
System: SecOps Platform — secops.bedrockcybersecurity.org
Database: psql-secops-prod (PostgreSQL)
Final Authority: Rory — nothing is suppressed without his explicit approval
1. What Known-Good Rules Are and Are Not
What They Are
Known-good rules are DB-driven suppression rules that tell the analyst agent to auto-close findings that match a verified, business-justified, recurring pattern. When the analyst agent starts, it calls GET /api/known-good to load the full ruleset into memory. When a finding matches a rule, the agent moves the finding from NEW to CLOSED and fires POST /api/known-good/{id}/hit to increment the hit counter.
The only legitimate use case: a real, verified, benign event that recurs regularly, has a business justification, and has been reviewed and approved by Rory.
Examples of appropriate known-good rules:
| Name | Description | Why it's legitimate |
|---|---|---|
velociraptor-scheduled-scan-aws-us-east-1 | Velociraptor collector scans fire daily at 02:00 UTC from known IP | Internal tooling, fixed schedule, fixed source |
azure-openai-service-principal-token-refresh | AOAI SP refreshes tokens every hour via client credentials | App behavior, not human login, scoped to single SP OID |
intune-compliance-check-bulk-login | Intune MDM bulk device check-in at policy sync interval | Known MDM behavior, scoped to Intune source system |
What They Are Not
Known-good rules are not:
- A fix for noisy detections. If a rule fires thousands of times per month, fix the underlying detection logic or tune the alert threshold. Known-good rules hide the symptom; they do not solve the problem.
- A substitute for proper whitelisting at the source (firewall, EDR, SIEM). Suppression at the SecOps layer is a last resort, not a first response.
- A blanket authorization to stop investigating a source system or account type.
- Permanent. Every rule requires a periodic review date.
The Over-Suppression Risk
Over-suppression in a HIPAA environment is a material security failure. Suppressing a real security event is worse than living with alert fatigue. If a known-good rule masks a true positive — an attacker moving laterally, a compromised service account, a misconfigured privilege escalation — that event will be auto-closed with no investigation trail.
A suppressed finding is a blind spot, not a cleared finding.
2. When to Create a Rule
All Four Criteria Must Be Met
- Recurring pattern — the finding fires repeatedly across multiple days or incidents. A single occurrence or a pattern that appears intermittently does not qualify.
- Verified benign — the source, account, and behavior have been manually confirmed as legitimate. "Probably fine" is not verified. Check the source system logs, confirm the actor, confirm the action.
- Business-justified — there is a documented operational reason why this pattern exists and will continue. "It has always done this" is not a justification.
- Rory-approved — Rory has reviewed the proposed rule and explicitly approved it. No exceptions.
When NOT to Create a Rule
- Intermittent findings — if a finding appears once every few weeks or is sporadic, investigate each instance. Do not suppress to avoid the work.
- Unverified sources — if you cannot confirm the exact system, IP, or identity generating the finding, do not suppress it.
- Newly introduced systems — wait at least 30 days of baseline observation before proposing a known-good rule for a new system.
- Break-glass-adjacent accounts — any finding involving accounts that resemble break-glass naming conventions, AWS root accounts, or firewall local admins should never be suppressed. See Section 1.1 below.
- Findings from systems under active incident — never create or expand a known-good rule during an active incident.
- Findings flagged HIGH or CRITICAL without severity_filter restriction — broad suppression of high-severity findings requires an extraordinarily strong justification and stricter scoping. Default answer is no.
2.1 Permanently Unsuppressible Accounts — Hard API Block
The following 18 accounts and identities are permanently excluded from known-good rule coverage. The API enforces this at the enforcement layer. Never attempt to create a rule targeting these accounts, ever.
Cirius break-glass accounts:
cirius-breakglass@ciriusgroup.comcirius-breakglass@ciriusdde.comcirius-breakglass@dr.ciriusgroup.internal
AWS root accounts (all 7 Cirius AWS accounts):
- All 7 AWS root account identities — if you are seeing root account findings, you do not suppress them, you investigate them immediately.
Entra break-glass:
- Entra PROD break-glass account
- Entra DDE break-glass account
Palo Alto local admin (all 4 firewalls):
- Local admin account on each of the 4 Palo Alto firewalls
Any finding from these accounts requires human investigation. The API will reject any rule submission that would match these identities. Do not attempt to work around this.
3. Creating a Rule
3.1 Rule Fields
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | Yes | Naming convention: {source-system}-{behavior}-{scope} |
description | string | Yes | Plain-English explanation of what this suppresses and why |
match_type | enum | Yes | exact, regex, or contains — prefer exact |
match_field | string | Yes | The finding field to match against (e.g., actor, source_ip, event_type) |
match_value | string | Yes | The value to match |
source_system | string | Yes | Scope to the minimum necessary source system |
severity_filter | array | No | Limit suppression to specific severity levels |
enabled | bool | Yes | Default false until approved |
created_by | string | Yes | Identity of the submitter |
approved_by | string | Yes | Must be Rory — no self-approval |
3.2 Naming Convention
Pattern: {source-system}-{behavior}-{scope}
Good names:
velociraptor-scheduled-scan-aws-us-east-1intune-mdm-bulk-checkin-production-tenantazure-aoai-sp-token-refresh-prod
Bad names:
suppress-intune-noise— too vague, no behavior, no scoperule-004— no descriptive contentfix-false-positive— not a name, not scoped
3.3 match_type Guidance
Use exact whenever possible. Exact matches are explicit, auditable, and cannot be manipulated by an attacker into broader coverage.
Use contains only when the field value has a predictable prefix or suffix pattern and you have confirmed there is no plausible malicious string that shares that prefix or suffix.
Use regex only as a last resort — see Section 5.1 for the dangers. If you propose a regex rule, you must include a written justification for why exact or contains cannot work, and Rory must explicitly sign off on the regex pattern.
3.4 Scope Rules
source_systemmust be the most specific system that generates this finding. Never scope to*or leave blank.- If a finding comes from one AWS account, scope to that account. Do not scope to all AWS.
- If a finding involves one service principal, match on that SP's OID or app ID, not on a display name pattern.
3.5 How to Submit for Rory Review
- Create the rule via the API or UI with
enabled: falseandapproved_byleft empty. - Open a GitHub issue in the infrastructure repo using the template:
Known-Good Rule Approval Request. - The issue must include: the proposed rule JSON, the finding evidence (screenshots or log excerpts showing the verified benign pattern), the business justification, and the proposed review date (max 90 days from creation).
- Tag Rory for review. Do not enable the rule until Rory approves and sets
approved_by.
4. Rule Hygiene
4.1 Hit Count Monitoring
Hit counters are updated asynchronously via POST /api/known-good/{id}/hit. Use these to assess rule health.
Rules with 0 hits in 30 days must be reviewed. Either the underlying behavior stopped (and the rule should be disabled) or the rule was incorrectly scoped and never matched anything useful. A zero-hit rule that remains enabled is clutter that makes audits harder.
Pull the hit count report:
bash
curl -s https://soc.bedrockcybersecurity.org/api/known-good \
| jq '.[] | {id, name, hit_count, enabled, last_hit}'4.2 Hit Count Spikes — Attacker Exploitation Risk
A rule that suddenly spikes in hits is a red flag. If a known-good rule is being hit at 10x its normal rate, there are two possibilities: (1) a legitimate operational change increased the volume of that benign event, or (2) an attacker has discovered what the rule suppresses and is generating matching events to hide malicious activity.
Treat hit count spikes as potential incidents. Do not assume the explanation is benign.
When you see an unexpected spike:
- Pull a sample of the raw findings that triggered the rule.
- Confirm the actor, source IP, and behavior match the expected baseline.
- If anything is anomalous, disable the rule immediately (see Section 7) and escalate.
4.3 Quarterly Audit Procedure
Run the full audit on the first Monday of each quarter.
Steps:
- Pull all rules:
GET /api/known-good - For each enabled rule:
- Confirm
approved_byis populated and the approver is Rory. - Confirm the last hit date is within the last 30 days, or document why the rule is still needed if not.
- Confirm the
source_systemscope is still the minimum necessary. - Confirm the underlying behavior the rule was created for still exists and is still benign.
- Check whether the detection that generates the finding has been updated — if the detection was tuned, the known-good rule may no longer be needed.
- Confirm
- Disable any rule that fails the above checks and open a GitHub issue for Rory's review before re-enabling.
- Document audit results in the infrastructure repo under
docs/audits/known-good-YYYY-QN.md.
5. Dangerous Rule Patterns
5.1 Broad Regex
A regex rule that is too permissive can be exploited by an attacker to slip malicious activity past suppression. The attacker only needs to know enough about the rule to craft an event that matches.
Bad example:
json
{
"match_type": "regex",
"match_field": "actor",
"match_value": ".*-svc@ciriusgroup\\.com"
}This suppresses any service account. An attacker who compromises a real service account or creates a rogue account ending in -svc@ciriusgroup.com gets free suppression.
Good example:
json
{
"match_type": "exact",
"match_field": "actor",
"match_value": "aoai-inference-svc@ciriusgroup.com"
}One account. One rule. One approval.
5.2 Suppressing an Entire Source System
Setting source_system to a broad scope (e.g., all of Intune, all of Azure AD) and then applying a permissive match means any finding from that system in that category is suppressed. This is how large-scale compromise goes undetected.
Never suppress by source system alone without a specific match_field and match_value.
5.3 Rules Without a Severity Filter
A rule that suppresses across all severity levels will auto-close CRITICAL findings if the match hits. Every known-good rule should have severity_filter set to the minimum severity level that actually fires for the benign pattern.
Bad: No severity_filter — suppresses INFO through CRITICAL.
Good:
json
{
"severity_filter": ["INFO", "LOW"]
}If the legitimate pattern ever generates a HIGH or CRITICAL finding, you want that to land in the queue, not be auto-closed.
5.4 Rules with No Review Date in the Description
Rules without a documented review date accumulate indefinitely. The description field must include Review by: YYYY-MM-DD. This is enforced by the quarterly audit, but do not wait for the audit — set it at creation.
5.5 Rules Created During an Active Incident
A rule created or expanded during an active incident is suspect by definition. It may be a legitimate operational response, or it may be an attempt — intentional or accidental — to suppress evidence of the incident. No known-good rules are created or modified during active incidents without Rory's explicit sign-off documented in the incident ticket.
6. Approval Process
Who Approves
Rory is the final authority on all known-good rules. No exceptions.
- Agents do not self-approve. If the analyst agent identifies a candidate pattern for suppression, it logs the suggestion but does not create the rule.
- Automation does not approve. No CI/CD pipeline, no scheduled job, no script creates or enables a known-good rule without Rory's explicit approval.
- No analyst approves their own submission. The person who submits the rule cannot be the same person who approves it. In practice, since Rory is the only approver, this is enforced by role.
How Approval is Documented
- The GitHub issue tracking the submission must include Rory's written approval (a comment explicitly stating "Approved" is sufficient).
- The
approved_byfield in the database is set to Rory's identity string:rory@ciriusgroup.com. - The
enabledfield is set totrueonly afterapproved_byis populated. - The GitHub issue is linked in the rule's
descriptionfield:Approved: https://github.com/ciriusgroup/infrastructure/issues/{N}.
What Approval Covers
Rory's approval covers the exact rule as submitted — match_type, match_field, match_value, source_system, and severity_filter. Any change to these fields requires a new approval. Changing the name or description only does not require re-approval, but the change should be logged in the GitHub issue.
7. Emergency Rule Disable
If you suspect a known-good rule is masking an active attack, disable it immediately. Do not wait for Rory to review first — disable, then notify.
Immediate Disable
Via API:
bash
curl -s -X PATCH https://soc.bedrockcybersecurity.org/api/known-good/{id} \
-H "Content-Type: application/json" \
-d '{"enabled": false}' \
| jq .Confirm the disable:
bash
curl -s https://soc.bedrockcybersecurity.org/api/known-good/{id} \
| jq '{id, name, enabled}'Once disabled, the analyst agent will no longer suppress findings matching the rule. Findings that would have matched will now land in NEW for normal triage.
Investigating What Was Suppressed
After disabling, you need to assess the blast radius — how many findings were auto-closed by this rule and over what time window.
Pull all findings closed by this rule:
sql
SELECT f.id, f.title, f.actor, f.source_system, f.severity, f.created_at, f.closed_at
FROM findings f
WHERE f.closed_reason = 'known-good'
AND f.known_good_rule_id = {id}
ORDER BY f.closed_at DESC;Check the hit log for volume and timing:
sql
SELECT DATE(hit_timestamp) as day, COUNT(*) as hits
FROM known_good_hits
WHERE rule_id = {id}
AND hit_timestamp > NOW() - INTERVAL '90 days'
GROUP BY day
ORDER BY day DESC;Escalation path:
- Disable the rule.
- Notify Rory immediately — do not wait until you have the full picture.
- Pull the suppressed findings list.
- For any suppressed findings that look anomalous, open them as
NEWand begin triage. - If active attacker activity is confirmed, trigger the incident response runbook (
incident-response.md).
8. API Operations
List All Rules
bash
curl -s https://soc.bedrockcybersecurity.org/api/known-good \
| jq '.[] | {id, name, enabled, hit_count, approved_by}'Get a Specific Rule
bash
curl -s https://soc.bedrockcybersecurity.org/api/known-good/{id} | jq .Create a Rule (starts disabled)
bash
curl -s -X POST https://soc.bedrockcybersecurity.org/api/known-good \
-H "Content-Type: application/json" \
-d '{
"name": "velociraptor-scheduled-scan-aws-us-east-1",
"description": "Velociraptor collector scan from 10.0.4.12 daily 02:00 UTC. Review by: 2026-08-01. Approved: https://github.com/ciriusgroup/infrastructure/issues/NNN",
"match_type": "exact",
"match_field": "source_ip",
"match_value": "10.0.4.12",
"source_system": "velociraptor-prod",
"severity_filter": ["INFO", "LOW"],
"enabled": false,
"created_by": "rory@ciriusgroup.com"
}' | jq .Enable a Rule After Approval
bash
curl -s -X PATCH https://soc.bedrockcybersecurity.org/api/known-good/{id} \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"approved_by": "rory@ciriusgroup.com"
}' | jq .Check Hit Counts (rules with 0 hits — candidates for review)
bash
curl -s https://soc.bedrockcybersecurity.org/api/known-good \
| jq '[.[] | select(.enabled == true and .hit_count == 0)] | {count: length, rules: [.[].name]}'Agents (Internal Reference)
Agents call the following endpoints automatically — these are not analyst-facing operations:
GET /api/known-good— agent startup, loads the full rulesetPOST /api/known-good/{id}/hit— fire-and-forget, async, called when a finding matches a rule
Do not attempt to replicate agent behavior manually. If you need to test whether a finding would match a rule, query the rule fields directly and compare against the finding data.
9. Cross-Environment Scoping
Environments
| Environment | Source System Prefix | Database |
|---|---|---|
| Production | prod, aws-prod, azure-prod | psql-secops-prod |
| DDE (Dev/Demo/Eval) | dde, aws-dde, azure-dde | psql-secops-dde |
| AWS (all accounts) | aws-{account-alias} | psql-secops-prod |
Minimum Necessary Scope
Rules must be scoped to the minimum necessary source_system. A rule that suppresses a finding in production should not suppress the same pattern in DDE, and vice versa.
Bad:
json
{
"source_system": "*"
}This suppresses across all source systems. Never do this.
Bad:
json
{
"source_system": "aws"
}This covers all 7 AWS accounts. Scope to the specific account.
Good:
json
{
"source_system": "aws-cirius-security"
}One account. Clear scope.
DDE Is Not a Testing Ground for Production Rules
Do not create a known-good rule in DDE to "test it out" before proposing it for production. DDE findings are still security findings. If you want to validate that a rule pattern would match correctly, query the finding data directly and compare the fields manually.
Cross-Environment Duplication
If a legitimate benign pattern exists in both PROD and DDE (e.g., a tool runs in both environments), create two separate rules — one scoped to each environment. Do not create a single broad rule to cover both. Each rule goes through the same approval process.
Quick Reference: Good vs. Bad Rule Examples
GOOD Rules
json
{
"name": "velociraptor-scheduled-scan-aws-cirius-security",
"match_type": "exact",
"match_field": "source_ip",
"match_value": "10.0.4.12",
"source_system": "velociraptor-prod",
"severity_filter": ["INFO", "LOW"],
"enabled": true,
"approved_by": "rory@ciriusgroup.com"
}Why it's good: exact match, single IP, specific source system, severity-filtered, approved.
json
{
"name": "intune-mdm-bulk-checkin-azure-prod-tenant",
"match_type": "exact",
"match_field": "event_type",
"match_value": "DevicePolicySync",
"source_system": "azure-prod-intune",
"severity_filter": ["INFO"],
"enabled": true,
"approved_by": "rory@ciriusgroup.com"
}Why it's good: single event type, specific Intune source, INFO only, not touching identity or auth events.
BAD Rules
json
{
"name": "suppress-service-accounts",
"match_type": "regex",
"match_field": "actor",
"match_value": ".*-svc@.*",
"source_system": "*",
"enabled": true,
"approved_by": ""
}Why it's bad: broad regex matches any service account on any source system, no severity filter, no approver.
json
{
"name": "aws-noise",
"match_type": "contains",
"match_field": "title",
"match_value": "login",
"source_system": "aws",
"enabled": true,
"approved_by": "automation"
}Why it's bad: suppresses any finding with "login" in the title across all AWS, approved by automation (not allowed), no severity filter.
json
{
"name": "break-glass-suppress",
"match_type": "exact",
"match_field": "actor",
"match_value": "cirius-breakglass@ciriusgroup.com",
"enabled": true
}Why it's bad: this is a permanently unsuppressible account. The API will reject this. Never attempt it.
Last updated: 2026-05-25
Owner: Rory
Related runbooks: break-glass-procedure.md, incident-response.md, secops-findings-triage.md, secops-platform-guide.md