No description
  • Python 92.4%
  • Nix 5.1%
  • JavaScript 2.5%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Renovate Bot 6296642eac
Some checks failed
checks / workflow-syntax (push) Failing after 19s
checks / release-security (push) Has been skipped
checks / secrets-scan (push) Successful in 10s
checks / secrets (push) Successful in 0s
checks / trivy-scan (push) Successful in 12s
checks / trivy (push) Successful in 0s
checks / yara-scan (push) Successful in 6s
checks / yara (push) Successful in 0s
Merge pull request 'chore(deps): lock file maintenance' (#21) from renovate/lock-file-maintenance into main
2026-10-15 03:26:13 +00:00
.forgejo/workflows Use generic self-hosted scheduling for shared CI 2026-09-29 14:13:31 +02:00
.security test: avoid credential-shaped URL fixture and record exact historical exception 2026-09-27 21:23:33 +02:00
examples feat: publish inventories directly with native Dependency-Track identity federation 2026-09-27 20:19:35 +02:00
nix feat: release shared security workflows and dispatch subscribers immediately 2026-09-27 16:17:07 +02:00
scripts feat: publish inventories directly with native Dependency-Track identity federation 2026-09-27 20:19:35 +02:00
tests test: avoid credential-shaped URL fixture and record exact historical exception 2026-09-27 21:23:33 +02:00
.gitignore feat: release shared security workflows and dispatch subscribers immediately 2026-09-27 16:17:07 +02:00
flake.lock chore(deps): lock file maintenance 2026-10-15 05:25:07 +02:00
flake.nix feat: publish inventories directly with native Dependency-Track identity federation 2026-09-27 20:19:35 +02:00
README.md Use generic self-hosted scheduling for shared CI 2026-09-29 14:13:31 +02:00
renovate.config.js fix: keep shared workflow callers on the floating stable channel 2026-09-27 16:32:37 +02:00
renovate.json feat: release shared security workflows and dispatch subscribers immediately 2026-09-27 16:17:07 +02:00
security-repositories.json feat: publish inventories directly with native Dependency-Track identity federation 2026-09-27 20:19:35 +02:00

Forgejo workflows

Shared Forgejo Actions workflows for repositories on git.karpfen.dev.

The security and SBOM workflows are callable building blocks. They do not select repositories or create triggers by themselves. A participating repository keeps a small caller under .forgejo/workflows/ and controls activation through its triggers. The subscriber list controls release-triggered runs. Renovate is the exception: this repository centrally schedules it against an explicit repository allowlist.

Workflows

Workflow Purpose Default enforcement
security.yml Run the shared secret, Trivy and YARA scanners Scanner-specific enforcement
sbom.yml Generate backend-neutral inventories Generation failure fails the run
sca.yml Upload already-generated CycloneDX documents directly to Dependency-Track Generation, validation, or publication failure fails the run
secrets.yml Scan Git history or the checked-out tree with TruffleHog Verified and unknown findings fail the run
trivy.yml Scan the filesystem with Trivy for vulnerabilities, misconfigurations, and secrets High and critical findings fail the run
yara.yml Scan tracked files with karpfen/yara-sigs Signature matches fail the run

The security and SCA jobs use the normal self-hosted runner, currently provided by Forge; callers only use the reusable workflow and do not repeat runner placement. The scanner workflows keep distinct internal job IDs so Forgejo associates expanded-job logs with the correct scan. These workflows are not suitable for repositories whose contents are not trusted to execute on that runner.

Renovate

.forgejo/workflows/renovate.yml runs Renovate daily and on manual dispatch. renovate.config.js contains the complete repository allowlist. Autodiscovery, onboarding PRs, package install scripts, plugins, post-upgrade commands, unsafe executions, are disabled. Automerge is enabled only by the central workflow repository’s own configuration. Renovate opens ordinary dependency PRs; each target repository's own pull-request workflows decide whether those changes pass.

The workflow reads its dedicated Forgejo personal access token from the RENOVATE_TOKEN repository secret and maps the GH_COM_TOKEN repository secret to Renovate's GITHUB_COM_TOKEN. The Forgejo token belongs to the restricted renovate service account and has only write:repository, read:user, write:issue, and read:organization scopes. Grant that account write access only to repositories listed in renovate.config.js or the security subscriber catalog; private Git dependencies that Renovate must resolve receive read-only collaborator access.

Automatic security channel

Security callers follow @stable. Successful validation of a commit on main advances that branch immediately and dispatches security.yml and sbom.yml in the repositories listed in security-repositories.json. Callers need no commit to adopt the new version or start a new run. Manual dispatch also resolves the current channel. Harbor release workflows retain their separate versioning.

Before dispatch, the release job cancels older security scanner runs on main. SBOM runs finish under the caller concurrency group; accepted native imports continue processing even if CI is cancelled. New releases are dispatched immediately and wait for that group when a publication is already running.

Tool inputs are locked centrally in flake.lock; consumers have no tool pins. The central Renovate configuration updates those locks and enables automerge for this repository after required checks. Upstream release discovery still follows the Renovate run schedule; channel publication and consumer dispatch are event-driven and do not wait for that schedule.

Independent generation

From any supported Git project, without adding a workflow, configuration file, SBOM flake outputs, producer script, or publication credentials:

nix run --refresh 'git+https://git.karpfen.dev/karpfen/workflows.git?ref=stable#sbom'

Generation streams phase messages and tool diagnostics to the job log. Long collector steps report elapsed time every 30 seconds; Nix inventories also report metadata batches and per-root rendering. Progress uses stderr, leaving stdout as JSON, and requires no project configuration.

Existing language manifests select source inventories. Nix-only repositories use nix-sbom against standard flake outputs; --include-nix also selects Nix builds in a source repository. Supplier inventories below sbom/ are retained as individual documents. Optional --cargo-target and --all-features arguments preserve target-specific workspace inventories without a custom producer script. These use ordinary Cargo metadata and do not claim that a binary was observed. Use --plan to inspect discovery, and --allow-import-from-derivation when the project's existing Nix build evaluation requires it. Missing or failing evidence is reported in inventory.json; the command fails rather than publishing a successful-looking partial run. Evidence and generated documents remain available. No CVE database, Trivy findings, project authorization, or notification preference selects the generated inventory. Native composition remains limited by the available build and artifact evidence; discovery does not establish completeness.

The generation-only workflow is .forgejo/workflows/sbom.yml. It uploads sbom-inventory, containing ordinary CycloneDX files, evidence, and a manifest with subject identifiers, hashes and collection evidence. Its contents have no Dependency-Track project IDs.

Separate publication

.forgejo/workflows/sca.yml uploads a previously generated bundle using native Dependency-Track workload identity federation (5.2 or later). Forgejo issues the job token; /api/v2/oauth/token exchanges it for a short-lived service-account session, and /api/v1/bom accepts the unmodified CycloneDX file. There is no publication server or persistent Dependency-Track credential in CI.

Publication selection and service-account names live in security-repositories.json. Dependency-Track administrators separately provision projects, per-repository teams, project ACLs, service accounts and identity bindings. Project access control must be enabled. CI accounts receive only BOM_UPLOAD and VIEW_PORTFOLIO. CI resolves existing main project UUIDs and never creates projects or changes permissions. New subjects must be provisioned before their first publication. Existing UUIDs, history and triage are preserved.

See examples/sca.yml for the two-job caller. The caller's concurrency group serializes runs for a repository/ref across push and dispatch triggers; let the active publication finish because cancelling CI does not cancel an accepted Dependency-Track import. This group belongs in the caller, as Forgejo evaluates concurrency for top-level runs. Inventory-only callers need no publication inputs.

Every selected file, hash and project mapping is checked before the first upload. The original generation artifacts and documents remain unchanged. Vulnerability records are rejected: Dependency-Track performs its own matching. Two uploads at a time bound ingestion load. Logs show each project, completed count and a 30-second heartbeat. The publication artifact records accepted upload tokens, project UUIDs and partial results even on failure. Only an explicit native COMPLETED processing status counts as success; processing=false alone does not. Neither bearer sessions nor platform tokens enter logs or artifacts.

Source-only project mappings publish a repository inventory. Fishystuff retains its explicit Linux, Windows, Wasm and site publication subjects; the target list is a build selection, while subject-to-project mappings belong only to publication.

Secret scanning

secrets.yml checks out full history and runs TruffleHog against the local Git repository by default. Results are written to the trufflehog-results artifact without printing candidate secrets to the job log.

Reviewed historical test fixtures can be recorded in .security/secret-exceptions.json with schemaVersion: 1 and an exceptions array. Each entry requires detector, the full commit, file, rawSha256 (SHA256 of TruffleHog's exact Raw value), and a review reason. Matching is exact; another commit, path, value or detector remains a finding. Verified credentials always fail. The artifact retains the complete scanner output and a separate review report; exception values themselves are never stored in Git.

Inputs:

  • history: scan Git history when true, otherwise the checked-out filesystem; default true.
  • results: comma-separated TruffleHog result classes; default verified,unknown.
  • fail-on-findings: enforce a clean result; default true.

Trivy scanning

trivy.yml produces a JSON trivy-results artifact.

Inputs:

  • scanners: default vuln,misconfig,secret.
  • severity: default HIGH,CRITICAL.
  • ignore-unfixed: default false.
  • config: optional repository-relative Trivy configuration path.
  • fail-on-findings: default true.

A repository may keep .trivyignore at its root for reviewed exceptions. Use the config input only when the defaults are insufficient.

YARA scanning

yara.yml archives the selected tracked path at HEAD, removes symlinks, and scans the resulting isolated tree. It does not traverse .git, caches, or other untracked runner state.

Inputs:

  • scan-path: repository-relative tracked path; default ..
  • max-file-size-mb: default 50.
  • fail-on-findings: default true.

Matches are uploaded in the yara-results artifact.

Versioning

stable is the automatically advanced security release channel. Generator versions are recorded inside the CycloneDX documents; the central Git history records the corresponding locked tool inputs. Release promotion and fan-out use the existing restricted Renovate account; that account needs write access to the central repository and Actions dispatch access to each explicitly listed subscriber. It is not a generation credential.