Repository navigation
v0.13.0
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.0Every 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 openctemioInstalling 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 openctemioUpgrading (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