Skip to content
bitzorcas
中EN

Concept

RiskControl

Understand the complete risk path from login history and parallel factors to tenant policy, challenge execution, independent evidence persistence, and GA gates.

Last updated

RiskControl evaluates a login environment and recommends None, Captcha, MFA, StepUp, or Block. It raises the cost of automated and anomalous access, but it does not replace password checks, account status, authorization, rate limiting, or audit.

1. Capability map

LayerMain typesResponsibility
ContractsRiskAssessment, RiskPolicy, IRiskFactor, captcha portsStable models, narrow ports, and AOT JSON
Applicationrule engine, four factors, policy provider, persistence pipelineEvaluation, tenant policy, and post-transaction recording
InfrastructureRiskAssessmentStoreUnified aggregate writes and QueryShape reads
Identitylogin-history provider, LoginFlow, risk-driven MFAProvides facts and executes challenges
API and Websitecaptcha filter and Website captcha endpointHTTP adaptation and anonymous form protection

There is no rule-management endpoint, machine-learning model, geo-anomaly factor, or weak-password factor in the current module. It is an extensible deterministic rule engine.

2. Login path

NoneCaptchaMFA / StepUpBlock

Login command

One history snapshot

Four parallel factors

Tenant riskcontrol.policy

RiskAssessment

RequiredChallenge

Password and account checks

Two-stage captcha

MFA after password

Reject before password

Independent evidence commit

Login evaluates before password verification. Block avoids BCrypt work; Captcha returns a challenge and waits for a second submission; MFA and StepUp both enter the existing MFA path; None continues normal authentication.

3. Built-in factors

FactorWeightTriggerCurrent evidence
NewIp20non-empty IP absent from the recent setraw IP and known count
NewDevice15device info or user agent absent from known devicesraw fingerprint and known count
HighFrequency40at least three failures in five minutesfailure count and threshold
OffHours10business-local time from 00:00 to 06:00hour and full business time

All four total 85. The default Block range starts at 91, so built-in factors alone cannot reach Block. A tenant must lower the threshold or an extension must add another valid factor.

Read Rule engine and risk factors.

4. Default policy

ScoreLevelChallengeLogin behavior
0–30LowNonecontinue password checks
31–50MediumCaptchaissue or verify image captcha
51–75HighMFArequire MFA after password
76–90CriticalStepUpcurrently enters the same MFA path
91–100BlockBlockreject before password

Tenants override the complete mapping through riskcontrol.policy. Read, JSON, or policy-validation failure falls back to the default and logs a warning; caller cancellation still propagates.

Read Tenant policy and evidence persistence.

5. Captcha capability versus wiring

The module implements ImageCode, Slider, PointSelect, and optional Behavior providers. In-house providers use five-minute tickets, random nonces, salted SHA-256 values, and Redis GETDEL.

Actual business wiring is narrower:

  • Login and Website call ResolveDefault() and therefore use ImageCode.
  • Unconfigured Behavior silently resolves to ImageCode.
  • Slider and PointSelect are registered, but no business endpoint selects them.
  • RequireCaptchaEndpointFilter is attached nowhere.
  • The filter rejects Result failure but lets Success(Passed=false) continue.
  • Login does not validate that a submitted ChallengeId belongs to the current tenant and pseudo-session; Website does.

Read Captcha providers and one-time tickets.

6. Independent assessment recording

Login.Command implements IRiskAssessedRequest. The engine captures one successful assessment in scoped execution context. An outer pipeline records it with a fresh unit of work after the business transaction succeeds, returns failure, or throws.

Separate business and risk-evidence transactions
try
{
// The inner path contains the login transaction and produces its own outcome.
return await next(message, cancellationToken);
}
finally
{
// Evidence uses an independent non-cancelled unit of work after business completion.
await PersistPendingAssessmentAsync();
}

Persistence failure logs an error and preserves the original outcome. That protects availability but can lose security evidence; production needs metrics, alerts, and possibly durable compensation.

7. Query, tenancy, and privacy

GET /api/risk/assessments requires risk-control.assessment.view. The handler takes TenantId from CurrentUser and the Store adds an explicit tenant predicate before provider-neutral paging.

Two boundaries remain:

  1. during formal tenant impersonation, CurrentUser may retain the operator tenant while Effective CurrentTenant is the target;
  2. response items expose complete factors containing raw IP, device fingerprint, and business time without a redacted projection.

Read Identity, Website, and query integration.

8. Failure policy by stage

Failure pointCurrent policy
history, factor, or engine exceptionEngine returns failure; Login warns and continues without risk challenge
unreadable or invalid settingdefault policy
Login captcha generation/provider failurelogin fails
wrong captcha answerLogin and Website deny; general filter currently allows
no Redis registrationno-op ticket store; generation appears successful and every verification fails
assessment record failureroll back evidence transaction, log, preserve business outcome
damaged assessment snapshotquery returns stable failure

It is inaccurate to describe the entire module as simply fail-open or fail-closed.

9. Chapter map

GoalPage
Understand snapshots, parallel factors, scoring, and reachabilityDecision engine
Generate, bind, and consume four challenge types safelyCaptcha providers
Configure tenant policy and record immutable evidencePolicy and persistence
Integrate Login, MFA, Website, and query APIIntegration boundaries
Establish security, privacy, fault, and production gatesTesting and operations

10. Source review

Terminal window
# Review engine, factors, and the actual Login consumer together.
rg -n "RuleBasedRiskEngine|IRiskFactor|RequiredChallenge|AssessAsync" \
src/Platform/RiskControl src/Platform/Identity -g '*.cs'
# Locate every challenge-generation, verification, and endpoint-wiring path.
rg -n "GenerateAsync|VerifyAsync|RequireCaptchaEndpointFilter|ResolveDefault" \
src/Platform/RiskControl src/Platform/Identity src/Platform/Website src/Hosts -g '*.cs'
# The current expected result has no endpoint attachment and no Passed check in the filter.
rg -n "AddEndpointFilter<RequireCaptchaEndpointFilter>|GetValueOrThrow\\(\\)\\.Passed" \
src/Hosts/BitzOrcas.Api -g '*.cs'

11. Minimum GA evidence

  • The general filter checks Passed and is attached to every intended endpoint.
  • Login, Website, and filter validate tenant, session, and scenario binding.
  • Every in-house provider, resolver rule, Redis failure, and vendor adapter has contract tests.
  • Vendor secrets are not sent in URLs; provider, scene, Randstr, IP, and response protocol are validated.
  • Engine fail-open has explicit risk acceptance, metrics, alerts, and high-value exceptions.
  • Assessment query uses EffectiveTenantId and redacts sensitive evidence.
  • Evidence persistence failure has durable alerting or compensation.

Next: Rule engine and risk factors · Back to platform modules

100%

Scroll or use controls to zoom · drag when enlarged · double-click for 100% / 200%