Skip to content

v0.13.0

Choose a tag to compare

@github-actions github-actions released this 21 Oct 08:53
· 1760 commits to main since this release
99adc18

Container images (multi-arch: amd64 + arm64)

docker pull ghcr.io/openctemio/openctem:v0.13.0      # all-in-one (API + web + console + gateway)
docker pull ghcr.io/openctemio/openctem-api:v0.13.0
docker pull ghcr.io/openctemio/openctem-web:v0.13.0
docker pull ghcr.io/openctemio/openctem-console:v0.13.0   # platform console
docker pull ghcr.io/openctemio/migrations:v0.13.0
docker pull ghcr.io/openctemio/seed:v0.13.0
docker pull ghcr.io/openctemio/admin-cli:v0.13.0

Every image is signed with cosign (keyless, GitHub OIDC) and carries a
signed SPDX SBOM attestation and a signed SLSA build provenance; the
SBOMs are also attached to this release.
Verify an image before deploying it:

cosign verify ghcr.io/openctemio/openctem-api:v0.13.0 \
  --certificate-identity-regexp '^https://github.com/openctemio/openctem/.github/workflows/docker-publish.yml@refs/tags/v' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com
cosign verify-attestation --type spdxjson ghcr.io/openctemio/openctem-api:v0.13.0 \
  --certificate-identity-regexp '^https://github.com/openctemio/openctem/.github/workflows/docker-publish.yml@refs/tags/v' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com
gh attestation verify oci://ghcr.io/openctemio/openctem-api:v0.13.0 --owner openctemio

Installing without containers, or from a private registry

The archives below install every component as programs with systemd
units (linux amd64/arm64; bootstrap-admin also for macOS and
Windows): api/docs/deployment/binary-install.md. For sites whose
clusters cannot reach the internet, each image is also attached as an
OCI archive with its signatures (openctem-image-*.oci.tar, listed
and signed in openctem-images-v0.13.0.txt), and the image kit builds
the images from the archives without source code:
api/docs/deployment/air-gapped.md.

Verify before use:

cosign verify-blob checksums-sha256.txt --bundle checksums-sha256.txt.sigstore.json \
  --certificate-identity https://github.com/openctemio/openctem/.github/workflows/release.yml@refs/tags/v0.13.0 \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com
sha256sum --ignore-missing -c checksums-sha256.txt
gh attestation verify openctem-server-v0.13.0-linux-amd64.tar.gz --owner openctemio

Upgrading (Compose deployment, api/deploy)

Read the upgrade notes below first. Then set OPENCTEM_VERSION=v0.13.0 in
api/deploy/.env and run docker compose pull && docker compose up -d:
the one-shot migrate service applies the database migrations before the
API starts (the API refuses to start on an older schema). Back up the
database and the api-data volume before upgrading.

What's Changed

  • perf(findings): recount a branch only when a finding's branch, severity or status changes by @0xmanhnv in #2636
  • fix(priority): rule dry run covers only findings in the caller's data scope by @0xmanhnv in #2631
  • fix(priority): batched audit cleanup (no-op and deleted-organization rows), erase on organization delete by @0xmanhnv in #2637
  • fix(tenant): risk scoring save merges partial bodies and refuses unsafe score maps by @0xmanhnv in #2634
  • fix(scoring): the daily EPSS refresh compares and writes the score only, not the percentile by @0xmanhnv in #2639
  • perf(ingest): stop rewriting every touched asset at the end of a report by @0xmanhnv in #2642
  • feat(audit): retention is on by default and archives through the storage provider by @0xmanhnv in #2643
  • perf(findings): unchanged scanner output and template provenance no longer rewrite a re-seen finding by @0xmanhnv in #2644
  • perf(db): drop six duplicate indexes by @0xmanhnv in #2635
  • fix(findings): reversing a decision needs findings:approve; automation cannot reverse it by @0xmanhnv in #2647
  • fix(findings): sole-member self-approval is for false positives only by @0xmanhnv in #2649
  • chore(security): ignore the fake credentials in the all-in-one child-env test fixture by @0xmanhnv in #2660
  • fix(automation): a scan an automation starts acts as the automation's owner by @0xmanhnv in #2659
  • fix(findings): bulk status and bulk assign need the single-item permission by @0xmanhnv in #2633
  • fix(deploy): bundled sensor reaches the platform over https through the gateway by @0xmanhnv in #2654
  • fix(approvals): false-positive approval treats every public asset as internet-exposed by @0xmanhnv in #2655
  • test(e2e): create a remediation task from findings, then hold and resume it by @0xmanhnv in #2657
  • feat(scanrun): unreachable and skipped targets do not make a run partial by @0xmanhnv in #2658
  • feat(scan): managed scans are identified by key, never by name by @0xmanhnv in #2638
  • fix(migrations): severity override down restores chk_activity_type validated by @0xmanhnv in #2656
  • fix(dashboard): facts maintainer skips the all-zero system tenant row by @0xmanhnv in #2663
  • chore(release): after v0.12.0: versions.yaml, changelog folded by @0xmanhnv in #2662
  • test(findings): disposition-reversal bulk test carries findings:status by @0xmanhnv in #2701
  • feat(deploy): optional off-host backups and point-in-time recovery (pgBackRest overlay) by @0xmanhnv in #2650
  • fix(findings): bulk status never overwrites a finding that changed after it was read by @0xmanhnv in #2651
  • feat(web): scan workflow connections say what they carry by @0xmanhnv in #2665
  • feat(web): deleting an asset asks for its name; bulk delete asks for the count by @0xmanhnv in #2670
  • fix(web): asset relationship graph full-screen button and card overflow by @0xmanhnv in #2668
  • fix(findings): classify is limited by finding type and approval, and recorded by @0xmanhnv in #2671
  • test(findings): bulk compare-and-set test carries findings:status by @0xmanhnv in #2715
  • fix(easm): govern public host names by what they are, not the asset type by @0xmanhnv in #2632
  • fix(roles): role edits are checked against old and new permissions; gaining approve permissions needs step-up by @0xmanhnv in #2672
  • feat(db): lz4 compression for large columns, app-role statement and idle-in-transaction timeouts by @0xmanhnv in #2640
  • feat(remediation): status menu per finding row and in-task finding drawer (P0-15) by @0xmanhnv in #2704
  • feat(web): one verification-code field and one step-up dialog by @0xmanhnv in #2706
  • fix(retest): a tool that could not run the check is not an unreachable target by @0xmanhnv in #2664
  • fix(commands): every return to the queue is counted, delayed and capped by @0xmanhnv in #2641
  • feat(scan): managed scans are read-only through the scan API by @0xmanhnv in #2646
  • fix(remediation): task timeline redacts other tasks the reader cannot open by @0xmanhnv in #2677
  • fix(service-accounts): key list is admin-only; last-used IP shown to administrators only by @0xmanhnv in #2673
  • ops(refingerprint): reset secret fingerprints derived from a mask by @0xmanhnv in #2675
  • feat(ai): openai_compatible provider, private-address toggle and model allow-list by @0xmanhnv in #2676
  • fix(ingest): keep a secret finding's masked line and preview; no code lines of secrets to AI or exports by @0xmanhnv in #2682
  • fix(remediation): finding_id filter and related members respect the data scope by @0xmanhnv in #2679
  • ci: a pull request runs a fast tier, the merge queue the full one by @0xmanhnv in #2709
  • fix(remediation): a new task owner is told; task notices respect the data scope; moves notify both owners by @0xmanhnv in #2684
  • fix(remediation): task members and counters follow the pentest member rule by @0xmanhnv in #2683
  • fix(attack): protected_by marks the protected asset, not the control by @0xmanhnv in #2687
  • fix(remediation): removing a task from a campaign checks access to the task by @0xmanhnv in #2688
  • fix(approvals): the requester is told how a request ended; hide the dead Mentions preference by @0xmanhnv in #2689
  • fix(members): offboarding reassigns the member's open remediation tasks and campaigns by @0xmanhnv in #2685
  • feat(scan): coverage runs act as a named system policy, a missing actor is refused by @0xmanhnv in #2652
  • fix(findings): a secret is not resolved because a scan stopped seeing it by @0xmanhnv in #2669
  • feat(findings): retest checks — console by @0xmanhnv in #2693
  • feat(ticketing): one outbound gate for tracker content; linking an issue needs findings:fix_apply by @0xmanhnv in #2703
  • perf(threatintel): EPSS and KEV syncs write only changes; EPSS percentile moves to a curve table by @0xmanhnv in #2645
  • feat(assets): lowering exposure, criticality or crown jewel needs approval when it drops an open P0/P1 by @0xmanhnv in #2648
  • fix(ingest): secret identity and rotation group never come from a mask by @0xmanhnv in #2674
  • feat(ticketing): the Jira assignee of a linked issue is stored on the ticket link by @0xmanhnv in #2705
  • feat(console): use the shared verification-code field and step-up dialog by @0xmanhnv in #2707
  • feat(web): system scans look like system scans by @0xmanhnv in #2661
  • feat(remediation): audit background state changes, regression tasks and auto-join as the system by @0xmanhnv in #2692
  • feat(release): install from release archives, private registries and air-gapped sites by @0xmanhnv in #2714
  • fix(web): findings toolbar in two fixed rows; search never wraps under the filter button by @0xmanhnv in #2667
  • feat(findings): retest checks — API by @0xmanhnv in #2698
  • fix(assettech): backfill mark skips a tenant deleted mid-run by @0xmanhnv in #2717
  • fix(attack): priority and threat models read the full exposure-chain result by @0xmanhnv in #2690
  • feat(remediation): the owner of a live task sees and works exactly the task's findings by @0xmanhnv in #2711
  • chore: gofmt files that fail the format check on develop by @0xmanhnv in #2716
  • fix(findings): the verification checklist records who completed it by @0xmanhnv in #2666
  • fix(findings): a finding can only be assigned to a member who can read it by @0xmanhnv in #2680
  • fix(jira): an inbound change moves only the links of the integration that sent it by @0xmanhnv in #2696
  • fix(remediation): every task write names the version, checked inside the transaction by @0xmanhnv in #2702
  • fix(ingest): do not store or return the producer's keyed secret hash by @0xmanhnv in #2678
  • feat(ai): organizations can use their own AI provider (Settings > AI source) by @0xmanhnv in #2686
  • test(migrations): replay 001262 in a private database (fixes 40P01 deadlock flake) by @0xmanhnv in #2718
  • feat(service-accounts): manage permission, team full-data ceiling, keys revoked when their minter leaves, read-only key scopes by @0xmanhnv in #2681
  • fix(attack): scope before cap; hidden steps for out-of-scope hops by @0xmanhnv in #2691
  • fix(ticketing): a retried ticket create adopts the issue it already created by @0xmanhnv in #2708
  • fix(security): GitHub inbound webhooks per integration; issue events take the shared ticket rules by @0xmanhnv in #2699
  • feat(remediation): the task owner picker explains missing access by @0xmanhnv in #2710
  • perf(attack): linear exposure-chain builder; drop reachable_from_entry_points by @0xmanhnv in #2694
  • feat(jira): issue type per kind of issue; task issues and status changes use the mapping of their own type by @0xmanhnv in #2719
  • fix(attack): cache scores, skip deleted assets, open findings only by @0xmanhnv in #2695
  • fix(web): honest attack-paths copy, load error state, hidden steps, i18n by @0xmanhnv in #2700
  • feat(participation): watchers of findings and remediation tasks (table, service, API) by @0xmanhnv in #2697
  • chore(security): Go 1.26.10 (GO-2026-6809) by @0xmanhnv in #2721
  • feat(participation): watchers hear about finding events; auto-watch, notification reason, coalescing by @0xmanhnv in #2712
  • feat(web): People section and watch bell on findings and remediation tasks by @0xmanhnv in #2713
  • feat(ticketing): per-integration create policy for automatic Jira issues by @0xmanhnv in #2720
  • fix(dashboard): pending fact runs skip the all-zero system tenant by @0xmanhnv in #2722
  • fix(web): accessible name for two-factor code inputs by @0xmanhnv in #2723
  • release: v0.13.0 by @0xmanhnv in #2729

Full Changelog: v0.12.0...v0.13.0