ecluse:ecluse-core
Safe HaskellNone
LanguageGHC2021

Ecluse.Core.Rules.Types

Description

The closed rule vocabulary, the evidence a rule reads, rule verdicts, and policy decisions. Ecluse.Core.Rules binds these values to capabilities and evaluates them. Configuration selects built-in rules and cannot supply evaluation closures.

Synopsis

The built-in rule vocabulary

data Rule Source #

The closed built-in rule vocabulary accepted from configuration. prepare binds capabilities without accepting arbitrary evaluation closures.

Constructors

AllowScope Scope

Unconditionally allow every package under the given scope.

AllowIfOlderThan NominalDiffTime

Delay new versions to give malicious publishes time to be detected and removed. Allow only after the configured publish age.

DenyInstallTimeExecution

Deny install-time code execution through npm scripts, RubyGems native builds, or PyPI sdist build backends. Abstain when the package carries no install-time execution signal.

DenyByIdentity Text

A hard deny for a specific package or package@version. Evaluated at top precedence (above AllowScope) as a post-mirror revocation mechanism.

AllowByIdentity Text

Allow an exact package identity, optionally with a version, including fixes the exact fix match cannot recognise. Default precedence overrides advisory denies but yields to install-code and identity denies.

AllowIfRemediatesCve

Admit an exact advisory fix without quarantine when no advisory still affects the version. Consult the local database and abstain when it is absent or either condition fails.

DenyIfCve DenyIfCveParams

Opt-in denial for affected versions meeting the severity threshold, including historical mirror dependencies. DenyIfCveParams governs missing scores and unavailable lookups.

DenyIfEpss DenyIfEpssParams

Deny on a known EPSS score at or above the threshold. Individual missing scores abstain, including malware without CVE aliases. DenyIfCve governs severity independently.

Instances

Instances details
Show Rule Source # 
Instance details

Defined in Ecluse.Core.Rules.Types

Methods

showsPrec :: Int -> Rule -> ShowS #

show :: Rule -> String #

showList :: [Rule] -> ShowS #

Eq Rule Source # 
Instance details

Defined in Ecluse.Core.Rules.Types

Methods

(==) :: Rule -> Rule -> Bool #

(/=) :: Rule -> Rule -> Bool #

data DenyIfCveParams Source #

DenyIfCve's configured behaviour: a separate record rather than fields on the constructor, so its selectors stay total under the sum (-Wpartial-fields).

Constructors

DenyIfCveParams 

Fields

  • dicMinCvss :: Double

    CVSS threshold (0 to 10). Qualitative labels use their band's ceiling. Missing scores satisfy every threshold, so unscored malware remains denied.

  • dicOnUnavailable :: FailureAlignment

    Resolve an unavailable advisory lookup: FailDeny refuses by default. FailNoDecision skips the rule and records the reason in the decision's audit trail.

data DenyIfEpssParams Source #

DenyIfEpss's configured behaviour, the EPSS twin of DenyIfCveParams.

Constructors

DenyIfEpssParams 

Fields

ruleName :: Rule -> Text Source #

A stable, human-facing name for a rule: its identity, derived from the data. It is the boot-order tiebreak and the credited identity in logs and denial messages.

readsAdvisories :: Rule -> Bool Source #

Whether a rule reads the advisory database. A rule set with none never needs one, and a set with one is worth waiting a bounded while for the first sync before deciding anything.

deniesOnAdvisories :: Rule -> Bool Source #

Whether a rule denies on the advisory database rather than abstaining without one. A rule set holding one cannot decide anything until an artifact loads, which is what makes a store mandatory.

Precedence

data PrecededRule Source #

A rule with explicit precedence, ordered highest first and then by name through bootOrder. No derived Ord defines policy order.

Constructors

PrecededRule 

Fields

Instances

Instances details
Show PrecededRule Source # 
Instance details

Defined in Ecluse.Core.Rules.Types

Eq PrecededRule Source # 
Instance details

Defined in Ecluse.Core.Rules.Types

defaultPrecedence :: Rule -> Int Source #

Use the rule type's default when configuration omits precedence. See bootOrder for tie-breaking. Identity allows override both advisory denies, while install-code and identity denies outrank every allow.

defaultAllowIfOlderThanPrecedence :: Int Source #

Default precedence of AllowIfOlderThan: the lowest band, a passive quarantine that yields to an explicit allow-list and to every deny.

defaultAllowIfRemediatesCvePrecedence :: Int Source #

Admit security fixes ahead of quarantine. Yield to AllowScope, whose trusted packages need no advisory probe.

defaultAllowScopePrecedence :: Int Source #

Default precedence of AllowScope: above the quarantine, because an explicit allow-list is a stronger statement than the time gate. Still below every deny.

defaultDenyIfCvePrecedence :: Int Source #

Outrank quarantine, remediation, and scope allows. Yield to AllowByIdentity so an operator can override an advisory denial.

defaultDenyIfEpssPrecedence :: Int Source #

Default precedence of DenyIfEpss: the same rung as DenyIfCve, which reads the same database and answers to the same identity-pin override. A tie resolves by name.

defaultAllowByIdentityPrecedence :: Int Source #

An identity pin overrides both advisory denies. DenyInstallTimeExecution and DenyByIdentity retain higher default precedence.

defaultDenyInstallTimeExecutionPrecedence :: Int Source #

Default precedence of DenyInstallTimeExecution: the deny band, strictly above every allow default, so a matching deny overrides any allow out of the box.

What a rule reads about one version

data Fact a Source #

Whether the evidence set carries one fact. Known wraps the fact's own vocabulary, so a determined absence (Known Nothing) stays distinct from Unread, which is no reading at all.

Constructors

Known a

The fact was read, and is whatever it says.

Unread

Nothing read this fact, so a rule that needs it cannot decide.

Instances

Instances details
Show a => Show (Fact a) Source # 
Instance details

Defined in Ecluse.Core.Rules.Types

Methods

showsPrec :: Int -> Fact a -> ShowS #

show :: Fact a -> String #

showList :: [Fact a] -> ShowS #

Eq a => Eq (Fact a) Source # 
Instance details

Defined in Ecluse.Core.Rules.Types

Methods

(==) :: Fact a -> Fact a -> Bool #

(/=) :: Fact a -> Fact a -> Bool #

data RuleEvidence Source #

What the engine reads about one version, one entry per fact the rule vocabulary consults. Identity is unconditional, because a store listing establishes it without any metadata read.

Constructors

RuleEvidence 

Fields

Instances

Instances details
Show RuleEvidence Source # 
Instance details

Defined in Ecluse.Core.Rules.Types

Eq RuleEvidence Source # 
Instance details

Defined in Ecluse.Core.Rules.Types

completeEvidence :: PackageDetails -> RuleEvidence Source #

Every fact present, the shape the serve, admission, and mirror paths always hold.

identityEvidence :: PackageName -> Version -> RuleEvidence Source #

Identity alone, which an authenticated store listing establishes with no manifest. A rule reading any further fact cannot decide over it.

Evaluation

data EvalContext Source #

Ambient information a rule may need that is not part of the package itself.

Constructors

EvalContext 

Fields

  • ctxNow :: UTCTime

    The wall-clock "now" for age-based rules.

  • ctxAdvisoryEtag :: Maybe DbEtag

    The advisory generation active when the audit line emits, or Nothing when none is loaded. A shadow swap means this need not identify the generation used for evaluation.

Instances

Instances details
Show EvalContext Source # 
Instance details

Defined in Ecluse.Core.Rules.Types

Eq EvalContext Source # 
Instance details

Defined in Ecluse.Core.Rules.Types

mkEvalContext :: IO UTCTime -> IO (Maybe DbEtag) -> IO EvalContext Source #

Build the shared context from the mount's injected clock, never an ad-hoc wall clock. The advisory ETag is audit-only and cannot affect the decision.

type Reason = Text Source #

A human-facing reason a rule attaches to its result, kept for the audit trail.

data RuleVerdict Source #

A deterministic verdict that the harness never retries. Allow, Deny, and fail-closed CannotVet are decisive. Other verdict reasons enter the deny-by-default audit trail in boot order.

Constructors

Allow Reason

This rule admits the package (with a human reason). Decisive.

Deny (Maybe DbEtag) Reason

A decisive denial, with its acquired advisory ETag or none for a non-advisory rule.

NoDecision Reason

This rule has no opinion. The reason stays for the audit trail. A no-op.

CannotVet FailureAlignment Reason

Deterministic inability to vet: an absent database, or a fact nothing read. Never enters retry or breaker handling. FailDeny yields Undecidable. FailNoDecision abstains.

Instances

Instances details
Show RuleVerdict Source # 
Instance details

Defined in Ecluse.Core.Rules.Types

Eq RuleVerdict Source # 
Instance details

Defined in Ecluse.Core.Rules.Types

data RuleEvaluation Source #

The harness alone creates Unavailable from faults. Decisive verdicts and fail-closed faults determine the decision. Other outcomes contribute their reasons to the audit trail.

Constructors

Decided RuleVerdict

The rule returned a verdict, and the harness takes it at face value.

Unavailable Transience FailureAlignment Reason

A harness-observed IO fault, timeout, or open breaker, with retry advice in Transience. FailDeny yields Undecidable. FailNoDecision abstains.

data FailureAlignment Source #

Choose refusal or abstention when a rule cannot vet or its evaluation faults. There is no failure alignment that admits unvetted bytes.

Constructors

FailDeny

Fail closed. An uncomputable result is decisive: the version is not admitted.

FailNoDecision

Fail open. An uncomputable result is a no-op: the rule simply does not fire.

data Decision Source #

The overall decision for a package version against a whole rule set. It credits the deciding rule by name (see ruleName), independent of how the engine evaluates it.

Constructors

Admitted Text Reason [SkippedCheck]

Admitted by the named rule, with its reason and the configured checks the admission did not benefit from, so a copy this decision makes trusted can say what it passed without.

Blocked Text (Maybe DbEtag) Reason

Blocked by the named rule, with the advisory ETag that supplied its evidence and its reason.

BlockedByDefault [Reason]

No rule was decisive. Deny-by-default; carries every non-decisive reason, in boot order, so the denial response can explain what was considered.

Undecidable Transience Reason

A fail-closed rule won without vetting the version. Packuments omit it, and artifact requests return an error. Transience selects the error status and retry advice. The reason remains available for audit.

Instances

Instances details
Show Decision Source # 
Instance details

Defined in Ecluse.Core.Rules.Types

Eq Decision Source # 
Instance details

Defined in Ecluse.Core.Rules.Types

data SkippedCheck Source #

A configured check the winning allow did not benefit from. The two kinds stay apart so no consumer reads a check the engine never ran as one that passed.

Constructors

SkippedUnavailable Text Reason

The check ran, could not vet the version, and its fail-open alignment let the fold move on.

Unreached Text

An earlier allow in the boot order decided, so the engine never ran the check.

Instances

Instances details
Show SkippedCheck Source # 
Instance details

Defined in Ecluse.Core.Rules.Types

Eq SkippedCheck Source # 
Instance details

Defined in Ecluse.Core.Rules.Types

skippedChecks :: Decision -> [SkippedCheck] Source #

The skipped-check evidence a decision carries: an admission's, and none for any other outcome.

Unavailability

data Transience Source #

Serve transient outages, rate limits, timeouts, and open breakers as 503. Serve internal or parse faults as 500. WillResolve and WontResolve encode that distinction.

Constructors

WillResolve (Maybe RetryAfter)

A retry may succeed after an outage, timeout, or open breaker. The optional RetryAfter suggests a client delay.

WontResolve

Not expected to self-heal (an internal or parse error). Retrying cannot help, so the request is a 500, never a 503.

Instances

Instances details
Show Transience Source # 
Instance details

Defined in Ecluse.Core.Rules.Types

Eq Transience Source # 
Instance details

Defined in Ecluse.Core.Rules.Types

newtype RetryAfter Source #

A Retry-After delay, in whole seconds. A 'newtype' so a raw count of seconds is never confused with some other integer when it reaches a response header or a sweep's wait.

Constructors

RetryAfter Int