Skip to main content
Attesta’s risk scoring system is fully pluggable. Any class that implements the RiskScorer protocol — a score(ctx) method and a name property — can be used wherever a scorer is expected. No inheritance or registration is required. This guide walks through building custom scorers from scratch, testing them, and wiring them into your Attesta configuration.

The RiskScorer Protocol

Every scorer must satisfy two requirements:

Step-by-Step: Rule-Based Scorer

A rule-based scorer evaluates the ActionContext against a set of predefined rules. This is the most common approach for organizations with well-defined security policies.
1

Define Your Rules

Start by mapping your organization’s security policies to scoring rules. Each rule inspects a specific aspect of the action context and contributes to the total score.
2

Implement Rule Logic

Create concrete rule classes for each security concern.
3

Assemble the Scorer

Combine the rules into a scorer that satisfies the RiskScorer protocol.
4

Register and Use

Pass the scorer to @gate or the Attesta constructor.

Step-by-Step: ML-Based Scorer

For organizations with historical approval data, a machine-learning scorer can learn risk patterns from past decisions.
1

Prepare the Feature Extractor

Extract features from the ActionContext that your model can consume.
2

Build the Scorer Class

Wrap your trained model in a class that satisfies the RiskScorer protocol.
3

Add a Fallback

ML models can fail. Wrap the scorer with a fallback for robustness.
4

Use with CompositeRiskScorer

Blend ML predictions with heuristic scores for defense in depth.
Never deploy an ML scorer without a fallback. If the model fails to load or predict, the fallback ensures that actions are still scored rather than silently passing through.

Example: API Cost Scorer

A practical scorer that estimates financial risk based on API call costs.

Composing Custom Scorers

Once you have custom scorers, you can compose them with built-in scorers using CompositeRiskScorer or MaxRiskScorer.

Testing Your Scorer

Always test custom scorers in isolation before deploying them.
Use DefaultRiskScorer.reset_novelty() in tests to clear the internal call counter between test cases. The novelty factor is stateful and can cause score drift if not reset.

Best Practices

Always Bound Scores

Ensure score() always returns a value in [0.0, 1.0]. Use max(0.0, min(1.0, raw)) as a safety clamp.

Name Your Scorer

The name property appears in RiskAssessment.scorer_name and audit trails. Use descriptive, stable names.

Test Edge Cases

Test with empty arguments, missing hints, unknown function names, and extreme values.

Use Composition

Prefer CompositeRiskScorer or MaxRiskScorer over monolithic scorers. It is easier to adjust weights than rewrite logic.

Risk Scorers

Built-in scorer types and composition strategies

Protocols

Full protocol reference for RiskScorer and other interfaces