Docs · reference
Quickstart reference — zero to your first overnight PR.
Five onboarding sections a brand-new user walks end to end on day one — connect the Driftlock GitHub App, declare the trigger entry point in a sealed-secret .driftlock/config.yaml, learn the canonical scan cadences, read the resulting PR with the SPDX 2.3 SBOM delta, and follow a five-step rollback recipe. Then the seven-step overnight deep reference scenario — a transitive dependency CVE surfaces at 02:14 UTC, Driftlock pins the alert id, drafts a byte-stable fix on a branch, replays the full monorepo test matrix in the sandbox under the pinned hermetic toolchain, signs the commit with cosign ECDSA P-256 over the SBOM sha256 + the approver-chain root SHA, attaches the SPDX 2.3 SBOM delta, and opens the PR ready for morning merge — a reviewer traces alert id → audit row in one click.
Trigger
dependency.advisory.detected
GHSA-xxxx-yyyy-zzzz · pkg:npm/lodash@4.17.20 — call-graph reachability marks the CVE in-scope.
Audit footprint
Seven columns, one row
alert · triage · drafted-fix · sandboxed-test · approver-chain · signed-commit · sbom — pinned to run id driftlock-run-2026-08-12-7421.
Sandbox
Hermetic · replayed
Toolchain nix:node-22 · hermetic build hash pinned to the run id · failing test test/checkout/refund.round_trip reproduces pre-fix, passes post-fix.
Signature + SBOM
cosign + SPDX 2.3
Cosign keyful ECDSA P-256 over commit SHA + SBOM sha256 + approver-chain root SHA. SPDX 2.3 emitted at registry.internal/<org>/<repo>/spdx/<sha256>.spdx.json.
byte-stable · replayable · KMS-resident
Connect GitHub
Install the Driftlock GitHub App — six steps from OAuth scope to a verified first delivery.
Every Driftlock trial begins with the GitHub App install. The six steps below are the day-one onboarding checklist — every row names both the platform-team action and the verification the operator runs to confirm the row landed. None of the steps ask for write scope on your repo; the Driftlock App manifest declares a read-only grant set and the platform team can revoke per-repo access without uninstalling.
#
step · verification command
01
Install the Driftlock GitHub App on your org
From the platform-team dashboard, install the Driftlock GitHub App on the org that owns the watched repos. The install URL is one-click; the App manifest declares the read-only Dependabot, pull_request, check_run, and branch_protection events the watcher subscribes to — no write scopes are requested at install.
02
Select the 2–10 watched repos
The App surfaces a per-repo grant screen at install. Pick the trial repos (typically 2 to 10 monorepos the platform team keeps under change-control). Least-privilege scope is enforced at the App manifest level — your team can revoke per-repo access without uninstalling.
03
Confirm OAuth permission scope
The Driftlock App declares read-only Dependabot + pull_request + check_run + branch_protection. The install screen enumerates each scope before confirmation. Bring your security reviewer to this step — the per-scope list is the audit-trail vocabulary the regulatory questionnaire expects.
04
Confirm the in-VPC webhook subscription
The install step opens a webhook from GitHub → your Driftlock receiver URL (the in-VPC endpoint the platform team registered at install). The first delivery fires within a minute; the receiver acks with a 200 + a delivery_id the watcher pins to the run id it will produce.
05
Verify the receiver acks the first delivery
In the Driftlock dashboard, the GitHub Webhook card reads `last delivery 200 · <delivery_id>`. The receiving endpoint HMAC-validates the X-Hub-Signature-256 header against your KMS-resident webhook secret before the payload lands. A mismatched signature fails closed — the watcher never sees it.
06
Bootstrap the .driftlock/config.yaml RBAC block
Commit a sealed-secret .driftlock/config.yaml to the watched repo. The block enumerates the six platform-team roles × eleven actions; every `+` cell surfaces a dual-approval sign-off marker. The config is the source of truth for approver chain on every PR the watcher drafts.
install · select-repos · scope-oauth · webhook-subscription · receiver-ack · rbac-bootstrap
Trigger entry point
The .driftlock/config.yaml declares which signal sources the watcher listens on.
The watcher subscribes to six signal classes. Each one is a key in `.driftlock/config.yaml` under the `sources:` block; turning a key off disables that trigger without redeploying. The snippet below is what a brand-new user drops into the watched repo on day one — the file is sealed-secret encrypted, reviewed by your platform team, and re-applied on every helm upgrade.
Day-one config snippet
# .driftlock/config.yaml — committed to the watched repo, sealed-secret encrypted.
# Reviewed by your platform team; re-applied on every helm upgrade.
sources:
dependabot:
enabled: true # GitHub-native alerts for your direct deps
severity_floor: medium # drop LOW-severity alerts before they pollute the queue
package_ecosystems: [npm, pip, cargo, go, maven]
ghsa:
enabled: true # GitHub Security Advisories · transitive reachability
feed: https://api.github.com/advisories
poll_interval_sec: 900
nvd:
enabled: true # NVD CVE feed — independent of GHSA
poll_interval_sec: 3600
cps_severity_floor: high
osv:
enabled: true # OSV.dev cross-ecosystem DB
poll_interval_sec: 1800
ci_failure:
enabled: true # CI emits job.completed events on failure
replay_first: true # sandbox replays the failing test before diff is applied
audience: driftlock # OIDC audience claim the verifier checks
on_call:
enabled: false # opt-in: PagerDuty / Opsgenie / SLO burn alerts
slo_burn_floor: 2.0
# The watcher ingests every source above and runs the call-graph reachability
# rule before drafting a fix. Out-of-scope dependencies do not produce runs.The signal sources the snippet declares
Dependabot
event-driven · GHSA-native · <60s to scrape
GHSA
15-minute poll · transitive reachability scoring
NVD
60-minute poll · CPS severity floor applied
OSV
30-minute poll · cross-ecosystem dependency DB
CI failure
event-driven · OIDC claim audited · replay-first
On-call
opt-in · SLO burn-rate floor · PagerDuty / Opsgenie
sources dependabot · ghsa · nvd · osv · ci_failure · on_call — declared in .driftlock/config.yaml, applied on every helm upgrade.
Scan cadence
Five cadences a reviewer learns on day one.
Five cadences a reviewer learns on day one. Each runs inside the in-VPC sandbox with default-deny egress; a 4-hourly re-scan picks up advisories that gain a CVE after the nightly sweep. The cron syntax mirrors the schedule documented on `/docs/self-host#cron-and-scheduling` — the platform team can move each row without rewriting the pipeline. /docs/self-host › cron-and-scheduling carries the cron-syntax reference the platform team owns.
step 0102:14 UTC · nightly dependency-feed sweep
The nightly cron pulls NVD + OSV + GHSA into a single deduped envelope. The watcher cross-checks against the call-graph and updates the reachability cache. Run id is keyed off the UTC date — every artefact a 02:14 run produces carries the same run id, so an audit day can replay the whole sweep row by row.
step 02on-PR-trigger · within 60 seconds
A pull-request event triggers a sub-minute scan against the PR head SHA. The watcher opens a branch if the diff introduced a vulnerable PURL reachable from the review surface; no branch is opened when the diff is merge-conflict or already-fixed.
step 034-hourly · hot-CVE re-scan
CVEs that score above your CPS severity floor re-scan every four hours. The re-scan emits a fresh SBOM delta against the current main; an updated dep on a hot CVE fans out a new alert id and the watcher drafts a follow-up PR automatically.
step 04on-alert · within same run id
When the watcher detects a CVE, it replays the full monorepo test matrix under the pinned hermetic toolchain. Replay status (`REPLAYED_OK` / `REPLAYED_FAIL`) is stamped onto the audit-trail `sandboxed-test` row alongside the toolchain identity.
step 0524:00 UTC · sbom-reaper + rekor-prune cron
Two nightly housekeeping jobs close the ledger. The sbom-reaper links orphan SBOM hashes back to the owning PR for retention enforcement; the Rekor-prune job moves cold claims into the offline tier. Both run on Sunday only; their cron schedules share the schedule documented on `/docs/self-host#cron-and-scheduling`.
02:14 nightly · on-PR <60s · 4-hourly re-scan · on-alert replay · sbom-reaper + rekor-prune
Read the PR
Where the SBOM delta lands, and how a reviewer reads it at 08:00.
The Driftlock-stamped PR carries three artefacts a reviewer reads at the same time — the description body, the SBOM-hash diff table, and the in-PR trigger link that carries the alert id. The SBOM document itself lands at the content-addressed registry path registry.internal/<org>/<repo>/spdx/<sbom_sha256>.spdx.json — the same path the /docs/compliance › sbom-emission reference documents. A reviewer clicks the trigger link once and lands on the alert row in the audit-trail — alert, triage, drafted-fix, sandboxed-test, approver-chain, signed-commit, and sbom, one screen.
Reading order at 08:00
- SummaryCVE id, advisory GUID, affected PURL list — pinned to the run id at the top of the description.
- RiskCall-graph reachability verdict, egress verdict against the release registry, severity score.
- Test evidenceToolchain identity, hermetic-build hash, replay status (REPLAYED_OK / REPLAYED_FAIL), sandbox log URL.
- ComplianceAudit row id, SBOM sha256, cosign KID + Rekor claim payload — all five audit-trail columns in the table.
- Reviewer checklistFive checkbox items — version bump, lockfile vs SBOM hash diff, cosign verify, rekor search, sign-off.
summary · risk · test evidence · compliance · reviewer checklist · audit-trail row pinned to run id
Rollback
Five steps the platform team runs on a bad merge.
When a merged PR needs to come back out — the test passes locally but fails in production, the CVE was mis-graded, or the lockfile churn unmasked a regression — the rollback recipe below is the canonical path. Every step is auditable; the cosign `verify-blob` confirmation ensures the head SHA on the Rekor log survives the revert. /docs/install › upgrade-rollback carries the install-side flip side of the same recipe — pre-flight, apply, rollback — for the platform team that owns the helm chart.
rollback · step 01
Revert the merge commit and push
Run `git revert -m 1 <merge-sha> && git push origin main`. The revert commit carries the original PR head SHA in its message; the watcher re-runs the pup-line SBOM delta table against the revert and stamps a new run id onto the audit-trail `drafted-fix` slot for the revert itself.
rollback · step 02
Close any follow-up PRs that depended on the reverted SHA
Run `gh pr close <pr-number>` on every PR that referenced the reverted head SHA in its `risk` section. Driftlock stamps a `reverted-by=<merge-sha>` trailer onto each closed PR so a future audit day can trace the chain.
rollback · step 03
Re-open the /demo review queue
On the /demo dashboard the queue card flips from `merged` to `reverted`. Reviewers get an inbox ping on every PR whose `risk` section still pins to the reverted SHA. The queue drift surfaces in the audit-trail `approver-chain` row — no PR is silently skipped.
rollback · step 04
Stamp audit row `rollback-issued`
The audit-trail row for the original merge receives a `rolled-back-by <revert-sha> at <UTC>` line. The existing Rekor claim stays valid — the rolled-back commit is still in the transparency log — but the live `signed-commit` row now points at the revert. A regulator tracing the chain reads the trail intact, with the rollback stamped onto the original row.
rollback · step 05
Re-run cosign `verify-blob` against the SBOM sha256
Run `cosign verify-blob --key kms://<your-kms-key-alias> --signature <sig-b64> <sbom-sha256>.spdx.json`. The exit code is `0` for already-verified commits: the Rekor claim is still valid even after the revert. The full upgrade / rollback lifecycle is documented on `/docs/install#upgrade-rollback`.
revert · pr-close · queue-reopen · audit-stamp · verify-blob · Rekor-anchored
The scenario
Ingest → triage → draft → sandbox test → sign → SBOM delta → open PR.
Seven ordered steps the watcher runs to take a CVE from "detected" to a PR ready for morning merge. Every step pins a write onto the audit-trail record — a reviewer traces back through PR description → SBOM hash → approver-chain → commit signature → sandbox run id → alert id → advisory GUID in one hop. The full pipeline diagram + audit-trail vocabulary lives on /architecture.
step 01overnight · 02:14 UTC → 08:00 PR
Ingest — the dependency feed surfaces a transitive CVE while you sleep.
02:14 UTC. The in-VPC watcher pulls the GHSA / NVD / OSV feed. The incoming payload matches the dependency-advisory envelope from /docs/webhooks; the watcher pins the advisory GUID + the affected PURL list to a per-PR alert id and lands the row on the audit-trail `alert` slot. No human intervention, no on-call page — by the time the watcher moves on, the alert sits pinned to the run id it will produce.
step 02overnight · 02:14 UTC → 08:00 PR
Triage — call-graph reachability marks the CVE in-scope.
The watcher runs the call-graph reachability rule (`deps.reachable.npm.lodash` style). It walks the import graph from your review surface to the affected PURL and writes the verdict onto the audit-trail `triage` row. The egress verdict against the release registry is logged against `triage.egressVerdict`. A pinned PURL + alert id is the pair the rest of the run hangs off of; flip the dependency out of scope and the run halts, no PR is opened.
step 03overnight · 02:14 UTC → 08:00 PR
Draft — byte-stable fix lands on a branch with the lockfile churn.
The watcher opens a branch, pins the affected package to the patched version, and writes the exact byte-stable diff onto the audit-trail `drafted-fix` slot — same bytes across reruns, pinned to the run id that produced it. The lockfile churn is part of the diff, not a follow-up commit, so reviewers diff the lockfile and the SBOM hash together in one motion.
step 04overnight · 02:14 UTC → 08:00 PR
Sandbox test — full monorepo test matrix, hermetic, replay succeeds.
The sandbox runner takes the drafted fix and replays the full monorepo test matrix under the pinned hermetic toolchain. The audit-trail `sandboxed-test` row carries the toolchain identity, the hermetic-build hash, the exact failing test that triggered the run, and the replay status — `REPLAYED_OK` only when the test reproduces and the proposed fix passes it. Egress is bounded by the platform team’s allow-list; an outbound call to a host the team has not reviewed fails the run with a `triage.egressVerdict` reject line.
step 05overnight · 02:14 UTC → 08:00 PR
Sign — cosign ECDSA P-256 commit, Rekor claim pinned to the run.
The signing-controller stamps the cosign ECDSA P-256 signature over the commit + the SBOM sha256 + the approver-chain root SHA. The Rekor transparency-log claim payload carries `run_id`, `sbom_sha256`, and `approver_chain_root` — the same payload documented on /docs/compliance › cryptographic-signing. KMS-resident by default; on Enterprise tier the platform team’s HSM holds the private half, never the signing workload itself.
step 06overnight · 02:14 UTC → 08:00 PR
SBOM delta — SPDX 2.3 emitted at the content-addressed registry path.
The sandbox runner emits the SPDX 2.3 document for the new commit and writes it to the content-addressed registry path — `registry.internal/<org>/<repo>/spdx/<sbom_sha256>.spdx.json` — the same path the /docs/compliance › sbom-emission reference declares. The SBOM hash diff against last main is attached to the PR description so reviewers see the dependency delta in one glance, and the audit-trail `sbom` slot pins the document to the run id.
step 07overnight · 02:14 UTC → 08:00 PR
Open PR — PR ready in the queue, reviewer traces alert id → audit row.
A PR lands in the queue with Driftlock-stamped PR description, the SBOM delta table, and an in-PR trigger link that carries the alert id. The reviewer clicks once and lands on the audit row — alert, triage, drafted-fix, sandboxed-test, approver-chain, signed-commit, sbom — all on one screen. Approve, merge, and the run closes out idempotently; reject, and the run halts before the signing step.
ingest · triage · draft · sandbox-test · sign · sbom-delta · open-pr · byte-stable · KMS-resident · Rekor-anchored
Incoming notification
The wrapper shape — HMAC + signing header, then the alert-id pin.
The wrapper around the dependency advisory carries the same HMAC + signing-header surface every Driftlock inbound envelope uses — cryptographic signing covers the verifier path. The receiver-key on the in-VPC webhook receiver accepts the payload before the watcher pins the alert id, so a tampered advisory fails closed before the run begins.
Example payload
The dependency webhook that fires the run. Shape mirrors the example on /docs/webhooks › dependency-advisory-detected; the wrapper preserves the HMAC + signing header so the receiver-key on the in-VPC webhook receiver accepts the payload before the watcher pins the alert id.
{
"delivery_id": "019284f3-1a6c-71e2-b4f1-9c8a7e2d4a55",
"event": "dependency.advisory.detected",
"webhook_id": "dependency-webhook",
"advisory_id": "GHSA-xxxx-yyyy-zzzz",
"source": "GHSA",
"cve": {
"id": "CVE-2026-9999",
"cvss_v3": 7.5
},
"affected": [
{ "purl": "pkg:npm/lodash@4.17.20" }
],
"call_graph": [
"api/users",
"middleware/audit",
"utils/dep"
],
"severity": "high",
"first_detected": "2026-08-12T02:14:09Z",
"ingested_at": "2026-08-12T02:14:11Z",
"alert_id_hint": "driftlock-alert-2026-08-12-7421",
"headers": {
"X-Driftlock-Advisory-Signature": "t=1762884849,v1=2cf24d…",
"X-Driftlock-Delivery": "019284f3-1a6c-71e2-b4f1-9c8a7e2d4a55"
}
}dependency · advisory · detected · HMAC-SHA256 · alert_id hint
PR description template
Driftlock-stamped Markdown body — five sections, audit-trail mapped.
Each section header below maps 1:1 to a column on the merge audit-trail record (/docs/compliance › merge audit trail): Summary → Risk → Test evidence → Compliance → Reviewer checklist. The template pins the PR body to the run id so a regulator can trace any merged PR back to its alert, its sandbox run, its SBOM, and its Rekor claim.
Markdown body
The Markdown body Driftlock stamps onto the PR. Each section header corresponds to one audit-trail row — alert → triage → drafted-fix → sandboxed-test → approver-chain → signed-commit → sbom — so the PR body and the audit-trail record walk the reader down the same columns.
## Summary
- Bump `lodash` from `4.17.20` to `4.17.21` to address CVE-2026-9999.
- Triggered by `dependency.advisory.detected` for advisory `GHSA-xxxx-yyyy-zzzz`.
- Pinned to run id `driftlock-run-2026-08-12-7421`.
## Risk
- Scope: `pkg:npm/lodash@4.17.20`, reachable from `api/users`, `middleware/audit`, `utils/dep`.
- Triage verdict: **in-scope** (rule `deps.reachable.npm.lodash`).
- Egress verdict: `triage.egressVerdict = ALLOW` against `registry.npmjs.org`.
- Severity: high (CVSS v3 7.5).
## Test evidence
- Toolchain: `nix:node-22` · hermetic build hash `9e2f…`.
- Failing test pre-fix: `test/checkout/refund.round_trip` — replay-passed post-fix.
- Replay status: `REPLAYED_OK` · sandbox log ref: `/var/lib/driftlock/runs/7421/sandbox.log`.
## Compliance
- Audit row: `pr_id=acme/checkout-svc#4215` · `head_sha=8f6c1d5b9c2f…`.
- SBOM: SPDX 2.3 · sha256 `3f6e…` · registry path:
`registry.internal/acme/checkout-svc/spdx/3f6e….spdx.json`.
- Signature: cosign ECDSA P-256 · KMS-resident signer
`driftlock/commit-signer`.
- Rekor claim payload: `run_id`, `sbom_sha256`, `approver_chain_root`.
## Reviewer checklist
- [ ] Confirm the version bump is the patched release the advisory
recommends (no unrelated upgrades).
- [ ] Confirm the lockfile churn matches the SBOM hash delta (no
silent drift).
- [ ] Re-run `cosign verify --certificate-identity-regexp ".*" <head_sha>`
— expect `0` exit.
- [ ] Run `rekor search --artifact <head_sha>` — expect one inclusion
claim with the run id.
- [ ] Approve or request changes — both land on the approver-chain row
before merge.summary · risk · test evidence · compliance · reviewer checklist · pinned to run id
Back to the runbook
The parent /docs page covers the four reference sections — this page walks the pipeline that ties them together.
The walkthrough above composes the audit-trail vocabulary from /docs/compliance, the dependency-advisory envelope from /docs/webhooks, and the audit-trail diagram from /architecture into one overnight scenario — the alert id travels through every artefact, every verifier command, every reviewer checklist.
Request a deeper-docs walkthrough
We'll reply with a calendar link and the air-gap or key-handling runbook relevant to your scope.