- Python 92.4%
- Nix 5.1%
- JavaScript 2.5%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
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
|
||
| .forgejo/workflows | ||
| .security | ||
| examples | ||
| nix | ||
| scripts | ||
| tests | ||
| .gitignore | ||
| flake.lock | ||
| flake.nix | ||
| README.md | ||
| renovate.config.js | ||
| renovate.json | ||
| security-repositories.json | ||
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 whentrue, otherwise the checked-out filesystem; defaulttrue.results: comma-separated TruffleHog result classes; defaultverified,unknown.fail-on-findings: enforce a clean result; defaulttrue.
Trivy scanning
trivy.yml produces a JSON trivy-results artifact.
Inputs:
scanners: defaultvuln,misconfig,secret.severity: defaultHIGH,CRITICAL.ignore-unfixed: defaultfalse.config: optional repository-relative Trivy configuration path.fail-on-findings: defaulttrue.
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: default50.fail-on-findings: defaulttrue.
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.