DEV Community

Saurabh Kumar
Saurabh Kumar

Posted on

Designing the Risk Engine Behind CIDS

A security system can collect thousands of events.

But collecting events is not the difficult part.

The difficult part is deciding:

Which events actually matter?

This is where the Risk Engine becomes an important part of CyberMoranda CIDS.

The purpose of the Risk Engine is not to simply assign a large number to suspicious activity.

Its purpose is to combine security evidence, context, and behavior into a defensible risk decision.

From Events to Risk
A simplified CIDS pipeline looks like this:

Incoming Activity

Event Normalization

Session Context

Behavior Analysis

Security Signals

Risk Engine

Policy Engine

Response

The Risk Engine sits between detection and response.

That separation is intentional.

Detection answers:

What looks suspicious?

Risk evaluation answers:

How concerning is the combined evidence?

Policy answers:

What should we do about it?

Why a Single Score Isn't Enough

A common mistake is to create something like:

Normal request = +2
Admin request = +30
Failed login = +20

and simply add everything together.

That can work for a basic prototype, but it becomes problematic as the system grows.

Consider:

Failed login

Five failed logins from a normal user might be suspicious.

Five failed logins from a known security-testing environment might be completely expected.

The same event can have different meanings depending on context.

Therefore, CIDS needs more than a static point system.

Context Matters

The Risk Engine should eventually consider multiple dimensions:

┌── Event Evidence

├── Session History

├── Behavioral Pattern

├── Identity Context

├── Asset Sensitivity

├── Frequency / Timing

└── Previous Signals

Risk Engine

This allows the system to reason about activity as a sequence rather than isolated events.

Signals Before Scores
One architectural decision I'm exploring is to standardize security signals before calculating the final risk.

For example:

AUTH_FAILURE_BURST
ENDPOINT_ENUMERATION
RESTRICTED_PATH_PROBE
REQUEST_RATE_ANOMALY
FINGERPRINT_CHANGE
SESSION_BEHAVIOR_SHIFT

Each signal should have structured information such as:

Signal
├── type
├── severity
├── confidence
├── timestamp
├── source
├── session
└── evidence

This creates a cleaner boundary between detection and risk calculation.

Instead of the detector saying:

Risk = 74

it can say:

Signal:
ENDPOINT_ENUMERATION

Severity:
HIGH

Confidence:
0.91

Evidence:
Multiple restricted endpoints accessed
within a short session window.

The Risk Engine can then combine that signal with other evidence.

Risk and Confidence Are Different

This distinction is important.

Risk asks:

How dangerous could this behavior be?

Confidence asks:

How confident are we that our interpretation is correct?

These should not automatically be treated as the same value.

For example:

Risk: High
Confidence: Low

could mean:

The potential impact is significant, but the system doesn't have enough evidence yet.

That should potentially produce a different response from:

Risk: High
Confidence: High<

This is one reason I don't want CIDS to depend on a single arbitrary threshold.

Temporal Behavior
Another important component is time.

Suppose a session produces:

10:01 Login
10:02 Failed authentication
10:03 /robots.txt
10:03 /admin
10:04 /.env
10:04 /internal

Looking at each event independently loses information.

Looking at the sequence reveals a behavioral pattern.

So the Risk Engine needs access to temporal context.

Conceptually:

Event A

Event B

Event C

Event D

Behavioral Pattern

Risk Update

This is one of the areas where CIDS can move beyond simple rule matching.

Risk Should Decay Too
Risk shouldn't necessarily increase forever.

If suspicious behavior stops, the system should eventually be able to reduce the active risk associated with a session.

Conceptually:

Suspicious activity

Risk increases

No further suspicious activity

Risk gradually decays

This prevents an old event from permanently defining a session.

The exact decay model needs to be tested rather than chosen arbitrarily.

Explainability Is Mandatory
A security analyst shouldn't have to trust a mysterious number.

If CIDS reports:

Risk: 91

the system should also be able to answer:

Why?

  1. Restricted endpoint probing
  2. Abnormal request frequency
  3. Authentication failure burst
  4. Suspicious session sequence

Confidence: High

This becomes especially important when automated responses are involved.

Risk Should Not Directly Trigger Everything

I want to keep another boundary inside CIDS:

Signals

Risk

Policy

Response

Not:

Risk > X

BLOCK

The policy layer should have the final authority over the response.

For example:

High Risk + Low Confidence

Monitor

while:

High Risk + High Confidence

Contain

And a controlled deception policy could be applied where appropriate.

This separation also makes CIDS easier to adapt to different environments.

The Architecture I'm Building Toward

The longer-term backend direction looks roughly like:

Telemetry

Event Normalizer

Session Engine

Behavior Analysis

Signal Engine

Risk Engine
/ \
Risk Score Confidence
\ /
Policy Engine

Response Engine
/ | \
Allow Monitor Contain

Deception

Audit / Feedback

Additional telemetry sources such as host-level telemetry, eBPF and fingerprinting signals can feed into this architecture as the system evolves.

The Hard Part

The architecture is easy to draw.

The real engineering challenge is proving that the Risk Engine works.

That means testing questions such as:

Does it detect meaningful behavioral changes?

How many false positives does it produce?

How quickly does risk change?

Does risk decay appropriately?

Can every decision be explained?

What happens under high event volume?

Can the system recover from failures?

Can the scoring model be tuned without rewriting the detection engine?

These are the questions I want CIDS to answer with experiments and measurable results.

Not marketing claims.

Where CIDS Is Going

My current goal isn't to build a dashboard that simply displays:

Threat: HIGH
Risk: 91

I want to build the engine underneath it that can explain:

Why is this behavior suspicious?

What evidence supports that conclusion?

How confident is the system?

What should happen next?

That is the direction I'm taking with the CIDS backend.

Observe the behavior.
Build the context.
Evaluate the evidence.
Then act.

CyberMoranda CIDS — Think Before You Act.

Top comments (0)