Skip to content

Trust model ​

This page defines trust status and the evidence Securock records. For configuration examples, see Policy. For per-ecosystem depth, see Ecosystems.

Canonical source: docs/trust-model.md.

What "trusted" means ​

trusted means the artifact passed the active policy. It is not a guarantee that a package is safe, authentic, or free of malicious behavior. The CLI prints this as trusted (under active policy).

The default policy requires that OSV was queried and returned no known vulnerabilities, and that malicious reports are clear. Unchecked vulnerabilities (state: unknown) are unknown, not trusted. Digest, provenance, signature, capability, and ownership checks are optional policy rules and are off by default.

Policy files are fail-closed: unknown fields, versions, and network modes are errors.

What "untrusted" means ​

The artifact failed at least one enabled policy rule. Typical reasons:

  • known vulnerabilities
  • malicious package reports (MAL-*)
  • missing digest, when required
  • invalid or weak digest (sha1 / malformed), when require_digest is set
  • provenance not verified, when required
  • signature not verified, when required
  • denied capability (shell, install scripts, …)
  • filesystem access above the configured maximum

What "unknown" means ​

Securock could not complete an evidence lookup, or the ecosystem does not yet expose that evidence. Unknown is not the same as verified.

Evidence states ​

StateMeaning
unknownLookup skipped or failed
missingLookup succeeded and found no evidence
presentRegistry returned provenance or signatures; not cryptographically verified
verifiedCryptographic verification succeeded

require_provenance: true accepts present or verified. To require cryptographic verification:

yaml
rules:
  provenance:
    minimum: verified
  signature:
    minimum: verified

Or use the built-in strict profile:

bash
securock verify --profile strict

strict requires digests plus provenance / signature minimum verified. Prefer strict on npm-heavy trees today.

Evidence Securock records ​

Evidencenpm / pnpm / yarn / bun / deno npmPyPI (uv / Poetry / PDM)All other ecosystems
digestfrom the language lockfilefrom the language lockfilefrom the language lockfile
vulnerabilitiesOSV ids (non-MAL-)OSV ids when the source is proven publicOSV ids when the source is proven public
maliciousOpenSSF Malicious Packages via OSV MAL-*same, when OSV is queriedsame, when OSV is queried
provenancenpm provenance; verified after Sigstore check + digest bindPEP 740 Integrity API; verified after Sigstore re-verify + filename/digest bindunknown
signaturenpm dist.signatures; verified after ECDSA check + digest bindsame PEP 740 path as provenanceunknown
capabilitiesregistry metadata + package source heuristicsunknownunknown
behaviorhosts, file paths, commands, env vars from source heuristicsunknownunknown
ownershipnpm publisher (_npmUser) and maintainersunknownunknown
chainsource repo, commit, ref, builder, workflow, predicate type from provenanceTrusted Publisher + verified Sigstore identity (SAN) and predicate type from PEP 740unknown

Malicious package reports are not vulnerabilities. A package with no CVEs can still be malware. The default policy denies both.

Capability detection for npm uses install-script and native-build metadata, then a deterministic scan of published JS/TS sources for network, filesystem, environment, and shell indicators. It is not a full behavioral sandbox and may under-report obfuscated code.

Trust chain evidence is extracted from npm provenance attestations (SLSA predicates). Securock only accepts SLSA provenance predicate types (https://slsa.dev/provenance/v0.1, v0.2, and v1) for provenance evidence. Policy origin allowlists can further restrict which source, builder, workflow, ref, and predicate type count as trusted. Securock does not rebuild the artifact from source.

Deno JSR and HTTPS URL artifacts record integrity from deno.lock. OSV does not cover those ecosystems yet, so vulnerability state stays unknown.

Offline scans leave provenance, signature, capability, ownership, behavior, chain, vulnerability, and malicious-report state as unknown. That is not a clean bill of health.

Private registries are not queried in the default public-only network mode. See Privacy.

Accepted findings ​

securock accept records that a team reviewed a finding and accepts it until a date. Accepted findings are stored in .securock/exceptions.yaml, separately from the policy and from securock.lock.

An exception does not make an artifact trusted. It does not change securock.lock, the policy digest, or any trust status, and scan, verify, and diff ignore it. It only suppresses a finding in audit output (and --fail-on), where it stays visible as suppressed with its reason, approver, and expiry. Keeping exceptions out of the lockfile keeps the lockfile deterministic: an exception that lapses with time never rewrites it.

Every exception needs a reason and an expiry date. When one lapses, the finding comes back and audit reports exception-expired, so an acceptance cannot become permanent by neglect. securock doctor reports expired exceptions, those expiring within 14 days, and exceptions with no approver.

What Securock does not guarantee ​

  • that a trusted package is benign
  • that a version bump is a security fix
  • that transitive behavior is reachable or exploitable (--reachability follows the dependency graph, not the code, and yes only means a package is not shown to be development-only)
  • that GitHub, npm, or OSV are uncompromised
  • that non-npm ecosystems collect provenance or signature evidence
  • that capability heuristics catch every malicious behavior
  • that a present trust chain proves the artifact was built from that source

Next steps ​

Released under the Apache-2.0 License. Pre-1.0: all lockfile resolvers are stable.