first commit
This commit is contained in:
88
docs/security-stack/security/slsa/src/policy/policy.md
Normal file
88
docs/security-stack/security/slsa/src/policy/policy.md
Normal file
@@ -0,0 +1,88 @@
|
||||
# policy
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
## Purpose
|
||||
|
||||
`evaluatePolicy` is the composition point that layers every other
|
||||
verification capability into a single decision: given a provenance
|
||||
statement, its optional DSSE envelope, its optional Rekor entry, and a
|
||||
`VerificationPolicy`, return one `VerificationResult` with every relevant
|
||||
rule reported. Where `verifyProvenance` only runs structural rules and
|
||||
doesn't know about signatures or transparency logs, `evaluatePolicy` ties
|
||||
the full chain of trust together and is what release-gate scripts should
|
||||
call.
|
||||
|
||||
## Features
|
||||
|
||||
- Runs the baseline `verifyProvenance` suite first, then appends:
|
||||
- DSSE signature verification against `policy.trustedPublicKeys`.
|
||||
- Rekor inclusion-proof presence (when `policy.requireRekorInclusion`).
|
||||
- Minimum-level assertion against an explicit `pipelineLevel`.
|
||||
- OTel `slsa.policy.violation` event emitted on any failure, with
|
||||
violation count and required level attached.
|
||||
- Returns structured `VerificationResult` — never throws on policy failure.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { evaluatePolicy } from "@suaveplan/slsa";
|
||||
|
||||
const result = evaluatePolicy(
|
||||
statement,
|
||||
envelope,
|
||||
rekorEntry,
|
||||
{
|
||||
trustedBuilders: ["https://gitlab.fq.io/suaveplan/project/-/runners/*"],
|
||||
trustedPublicKeys: [releaseKey],
|
||||
requireRekorInclusion: true,
|
||||
minSlsaLevel: "L2",
|
||||
},
|
||||
{ pipelineLevel: "L3" }
|
||||
);
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import {
|
||||
createSlsaOtelAdapter,
|
||||
evaluatePolicy,
|
||||
RekorClient,
|
||||
} from "@suaveplan/slsa";
|
||||
|
||||
const otel = createSlsaOtelAdapter();
|
||||
const client = new RekorClient({ otel });
|
||||
const rekorEntry = await client.uploadIntoto(envelope);
|
||||
const result = evaluatePolicy(statement, envelope, rekorEntry, policy, {
|
||||
otel,
|
||||
clock: () => Date.now(),
|
||||
pipelineLevel: "L2",
|
||||
});
|
||||
|
||||
if (!result.valid) {
|
||||
for (const c of result.checks.filter((c) => !c.passed)) {
|
||||
log.warn({ rule: c.name, message: c.message }, "policy violation");
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `evaluatePolicy(statement, envelope | null, rekorEntry | null, policy,
|
||||
opts?)` — returns `VerificationResult`. `opts.pipelineLevel` must be
|
||||
supplied when `policy.minSlsaLevel` is set; otherwise the check fails
|
||||
with a self-describing message.
|
||||
- `EvaluatePolicyOptions { otel?, clock?, pipelineLevel? }` — all optional.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The extra checks are appended, never interleaved, so existing consumers
|
||||
that match on `checks[i].name` stay stable. `checkDsseSignatures` builds
|
||||
`TrustedEd25519Key` records without `keyid` by default — if keyids are
|
||||
required for scoping, call `verifyDsseEnvelope` directly and feed the
|
||||
derived checks in. `minSlsaLevel` uses an ordinal comparison
|
||||
(`L0 < L1 < L2 < L3`) rather than string equality so `"L3"` satisfies
|
||||
`minSlsaLevel: "L2"` without additional policy tweaks.
|
||||
Reference in New Issue
Block a user