Security features at a glance
Everything fremforge ships, in one scannable table. Each row links into the dedicated page for configuration, override flow, and the underlying tool’s documentation.
fremforge is deliberately transparent about the OSS tooling underneath every control: customers under BSI C5, ISO 27001, BaFin, or ENISA-regulated review need the tool-level audit trail, and we’d rather you can grep our source than reverse-engineer a black box. The differentiation is the integration (hooks, RBAC, audit chain, EU residency, no Microsoft, no AWS) — not the scanner.
Code-push controls
| Control | What it does | Tool | Configurable per tenant |
|---|---|---|---|
| Push protection | Pre-receive secret-scan; rejects commits containing credentials before they enter git history | Gitleaks v8 (120+ patterns) | Override rules + per-pattern bypass |
| Branch protection | Per-branch rules: required reviewers, status checks, signed-commit requirement, force-push blocks | Forgejo native | Yes (per branch) |
| Two-factor auth | TOTP + WebAuthn for every user account. Enforceable per-org | Forgejo native + custom enforcement hooks | Yes (org-wide enforce, per-user opt-in) |
| OIDC MFA verification | Cryptographically verify your IdP asserted MFA on every sign-in via the OIDC amr claim (RFC 8176). Replaces the legacy operator-attested “trust IdP MFA” checkbox — the token says ["pwd","mfa"] or it’s not MFA | Custom claim-check middleware | Per-tenant required-amr policy |
| SSO break-glass | When your IdP is unavailable, misconfigured, or the SSO connection is broken, named org owners can recover access via a separately-managed break-glass credential path. Audit-logged | Custom (fremforge-written) | Per-tenant named owners |
| Keyless commit signing (sigstore / gitsign) | OIDC-bound signing — your IdP identity (Entra, Okta, Google Workspace, Authentik) signs the commit via a 10-minute Fulcio cert. Forgejo renders Verified by sigstore: <email> via <IdP>. Root CA in T Cloud DEW KMS (FIPS 140-2 Level 3 HSM, Germany). Fulcio at sign.frem.sh, TSA at tsa.frem.sh. Deliberately no Rekor / transparency log — TSA-anchored timestamping only, keeps signatures off any third-party log | Self-hosted Fulcio v1.8.5 + TSA on T Cloud eu-de, customer-side gitsign | Org admin → Allowed OIDC issuers + strictness level |
| Commit signing — SSH key | Sign commits with the same SSH key Forgejo uses for push. “Verified” badge appears natively in the web UI. Coexists with keyless; org admin sets strictness | OpenSSH + Forgejo’s allowedSignersFile | Per-user enable |
| Commit signing — GPG | Standard git commit.gpgsign flow. Upload public key at user settings, Forgejo verifies + renders the “Verified” badge | GnuPG + Forgejo native | Per-user enable |
Code-quality + vulnerability scanning
The following controls ship as workflow templates auto-scaffolded into every new repo on creation (Forgejo repository.created event → workflow-installer service). No customer action required — push code and the scanners run on every PR. Existing repos can backfill via Org admin → Repos → Install fremforge defaults.
| Control | What it does | Tool | Configurable |
|---|---|---|---|
| SAST | Static analysis on every PR via the scaffolded sast-opengrep.yaml workflow. Detects injection, XSS, hardcoded secrets, dangerous APIs across 30+ languages | OpenGrep 1.21 (FOSS Semgrep successor) | Custom rules URL |
| Dependency scanning (OSV) | Dependency CVE/GHSA scan on every PR via the scaffolded dep-scan-osv.yaml workflow. Surfaces fixable CVEs with the suggested upgrade | osv-scanner | Severity threshold |
| Container image scanning | The scaffolded image-scan-trivy.yaml workflow runs trivy image (Trivy is baked into the runner image — no install step) and POSTs results back to fremforge. Findings surface at Org admin → Code security → Container images, attached to the image + commit. Merge-block policy on unfixed high-severity is opt-in | Trivy | Severity threshold + ignore-policy + merge-block toggle |
| OpenSSF Scorecard | Weekly scorecard run on every repo. Surfaces best-practice gaps (branch protection, MFA enforcement, pinned dependencies, code review coverage) | scorecard | Schedule + stale-repo skip |
| Malware scan | Every push scanned for known-bad signatures + LFS objects scanned on upload | ClamAV + SaneSecurity feeds | Override on known-FP signatures |
| Workflow security gate | Pre-receive hook (04-workflow-security) parses every changed workflow YAML and rejects pushes that introduce: docker:// references to non-allowlisted registries (must be swr.eu-de.otc.t-systems.com/fremforge-prd/ by default), dangerous pull_request_target + script injection patterns, unpinned uses: references to non-mirrored orgs | Custom rules (fremforge-written) | Per-tenant docker-URI allowlist override |
| IP allowlist | Optional per-tenant push-time IP allowlist enforced by the 05-ip-allowlist pre-receive hook. Pushes from CIDRs outside the allowlist are rejected; admin-tab override available | Custom rules (fremforge-written) | Per-tenant CIDR list |
Supply-chain provenance
| Control | What it does | Tool | Configurable |
|---|---|---|---|
| SBOMs | CycloneDX 1.5 + SPDX 2.3 SBOM generated on every release-tag push (v* semver / calver tags) via the auto-scaffolded sbom-syft.yaml workflow. Results attached to the artifact + queryable at Org admin → Code security → SBOMs | Syft | Customer-customisable |
| SLSA provenance | SLSA Level 2 provenance generated for every release via the auto-scaffolded slsa-provenance.yaml workflow. buildType=https://frem.sh/buildtypes/forgejo-actions/v1. Signed with cosign against the local Fulcio CA. Verifiable with the standard slsa-verifier binary against fremforge’s published trust root. L3 hardened-builder posture is in scope for a future iteration | Custom builder (fremforge-supplied workflow) + cosign + Fulcio | — |
| Cosign image signing + verification | The auto-scaffolded cosign-verify.yaml workflow walks the repo, finds every digest-pinned image, runs cosign verify against the local Fulcio CA (sign.frem.sh), reports results at Org admin → Code security → Container images. Customer CI signs with its own OIDC identity — no long-lived signing keys | cosign + self-hosted Fulcio | Customer-customisable |
| Digest pinning | Every FROM in customer Dockerfiles can be auto-pinned to digests via the sha-pin-scan workflow; runs daily and opens PRs when upstream tags move | Custom | Enable per repo |
| Action mirror | uses: actions/checkout@v4 resolves to frem.sh/actions/checkout — Forgejo native pull-mirror of upstream with 8-hour sync. No build-time github.com fetch on the customer’s critical path. Mirrored orgs include actions, docker, pnpm, aws-actions, azure, google-github-actions, peter-evans, softprops, sonarsource, step-security, dorny | Forgejo native pull-mirror + Forgejo [actions] DEFAULT_ACTIONS_URL=https://frem.sh | (Operator-managed; transparent to customers) |
| Marketplace compatibility surface | The top-20 most-used GitHub Marketplace actions verified to work unmodified on fremforge — GITHUB_TOKEN, GITHUB_SHA, GITHUB_REF, GITHUB_API_URL etc all populated identically | Forgejo Actions runtime | — |
| Hosted Renovate | A managed Renovate bot that opens dependency-bump PRs for every customer repo on a 15-minute schedule. Identifies stale deps, action versions, container base images. Skips repos opted out via .renovaterc.json | Renovate + custom orchestration cron | Per-repo enable/disable |
Runtime isolation (hosted CI runners)
| Control | What it does | Tool | Configurable |
|---|---|---|---|
| Hosted runner sandbox | One job = one dedicated VM node = one kernel. The runner-controller spawns a fresh CCE Turbo VM node per queued job, places exactly one runner pod on it (podAntiAffinity + dedicated taint), then deletes the node on completion. No two jobs — same tenant or cross-tenant — ever share a kernel. Pods carry per-pod VPC ENI + Security Group (network isolation), seccompProfile: RuntimeDefault, no kube SA token. The reaper backstop kills orphan nodes whose pod never started or never finished. Same model as GitHub-hosted and GitLab-hosted runners | T Cloud CCE Turbo + Yangtse CNI + forgejo-runner (act_runner v6.2.1) + fremforge runner-controller with CCE node:delete IAM | LimitRange (CPU/RAM per pod), per-tenant concurrency cap |
| Per-tenant concurrent cap | 30 concurrent jobs per tenant (matches GitHub Pro). Higher caps for paid tiers | Spawner-level enforcement | Per-tenant override |
| Runner-minute pool | seat_cap × 1000 min/month. Overage-enabled tenants keep running; others get refused dispatch with reason runner_minute_cap | Spawner pre-dispatch check vs metering_events aggregate | runner_minutes_cap override |
| Egress proxy | Customer workflows reach the public internet through outbound-proxy-runners (SSRF-only deny, CGNAT-permissive — matches GitHub-hosted behaviour) | Custom proxy (fremforge-written, Hono-based) | — |
| Job wall-clock | 60-min hard ceiling per job (activeDeadlineSeconds=3600). Stale-pod sweeper kills anything older than 90 min | Cron runner-stale-sweep + spawner | Step-level timeout-minutes |
Secrets + access control
| Control | What it does | Tool | Configurable |
|---|---|---|---|
| Deploy secrets | Per-environment encrypted secrets. AES-256-GCM at rest with a MASTER_ENCRYPTION_KEY held in DEW KMS. Decrypted only inside the runner pod that needs them. Key rotation supports a two-key window (current + previous) for in-place rotation | Custom (Node crypto) + per-env scoping + DEW KMS | Per env / per repo / per org |
| RBAC + per-tenant scoping | Forgejo’s native RBAC + fremforge’s tenant-scoping layer; all platform API endpoints enforce tenant_id from the JWT, no cross-tenant data leaks. Org admin → Members → Roles | Forgejo + fremforge api middleware | Per-team granularity |
| OIDC single sign-on | Preferred IdP path. Connect Okta, Entra, Google Workspace, Authentik, Keycloak, Auth0 — any OpenID Connect provider — for inbound federation. Domain verification, just-in-time user provisioning, group → team mapping. Configured at Org admin → SSO → Auth sources | Forgejo native OIDC auth-source | Per-tenant IdP config |
| SAML 2.0 single sign-on | For IdPs without OIDC support (ADFS, legacy PingFederate, some on-prem SAML stacks). Same domain-verify + auth-source registration flow as OIDC | Forgejo native SAML auth-source | Per-tenant IdP config |
| SCIM 2.0 user provisioning | Push users from your IdP into your fremforge org via SCIM 2.0. Per-tenant bearer-token auth, dual-token rotation window, idempotent CRUD on Forgejo users. Works with any SCIM-compliant IdP | Custom api endpoints under /<slug>/scim/v2/* | Per-tenant SCIM token |
| SSH CA | SSH access to git uses a CA-signed certificate, not raw key fingerprints. Per-user cert with TTL; revocable via the org admin UI | OpenSSH CA + fremforge-managed cert issuance | TTL + per-user revoke |
| Authentication policy | Per-org bundle of enforcement toggles: hardware-backed keys (WebAuthn-only, no TOTP), max PAT lifetime (cap below the 90-day platform default), signed-commits required (block unsigned pushes), SSH disabled (HTTPS-only), 2FA required, SSO-only sign-in (block local Forgejo username/password). Mirrors the GHEC enterprise-policy surface. Each toggle audit-emits on change | Forgejo carried patches + fremforge enforcement hooks | Per-tenant policy bundle |
| Email-domain allowlist | Per-org allowlist of email hostname patterns. When enabled, members can only add @acme.com-style addresses matching the configured patterns. Closes the “claim commits as attacker@arbitrary-domain.com” path during forensic review. Pre-existing emails not auto-evicted; OIDC sign-in is exempt (the IdP attests). Patterns support exact + *.subdomain shapes | Custom rules + Bunny edge intercept on /user/settings/account/email | Per-tenant patterns + enforce flag |
| Workflow secrets | Org-level + repo-level Actions secrets injected into every CI job as env vars. Forgejo stores encrypted at rest; fremforge admin proxies CRUD with audit events (value never persisted in fremforge DB or audit log). Override secret = same form is the rotation flow | Forgejo native secrets + fremforge admin proxy | Per-org / per-repo / per-environment |
| Workflow OIDC for cloud auth | Runner pods get a fresh OIDC JWT with aud=fremforge per job. Customer cloud trust policies key off this for short-lived credential exchange (no long-lived AWS keys, GCP service-account JSONs, or Azure client secrets in workflow secrets) | Custom OIDC issuer signed by fremforge runner-OIDC key (rotated 30d) | — |
| Agent-native authentication | Three IdP-side patterns for non-human callers: (1) Direct customer-IdP JWT bearer — present an Entra workload-identity / Okta service-account / Google service-account JWT directly as Authorization: Bearer on any /api/v1/* endpoint; (2) RFC 8693 token exchange + OBO — POST /api/v1/auth/token-exchange accepts subject_token and optional actor_token; audit chain records both actor and on_behalf_of; (3) RFC 6749 client_credentials — POST /api/v1/oauth/token for apps without an IdP. Per-tenant audience binding (https://frem.sh/<slug>), per-source claim assertions (tid/hd), DB-level UNIQUE preventing two tenants from claiming the same issuer for direct bearer | Custom (auth_sources + oauth_clients + token-exchange pipeline using jose) | Per-source opt-in; per-client scope cap |
DevOps observability
| Control | What it does | Tool | Configurable |
|---|---|---|---|
| DORA dashboard | The four canonical DORA metrics — Deployment frequency, Lead time for changes, Change-failure rate, MTTR — computed over a 30-day rolling window from a tenant-scoped dora_deployments table. Ingest path is the Forgejo release webhook plus a manual POST /api/v1/dora/deployments for workflows that don’t tag releases. Visible at Org admin → DORA | Custom (fremforge-written, against tenant DB) | Rolling window + manual ingest |
| Code-security overview | Single admin tab aggregating findings from every scanner in the supply chain (Gitleaks pre-receive, OpenGrep SAST, osv-scanner deps, Trivy images, Scorecard, cosign verification). Filter by repo, severity, age. Each row links into the underlying tool’s report | Custom aggregator | Per-tenant severity floor |
| Workflow run inspector | Every Actions run streams structured logs (annotated with step + line) into the tenant audit log and into a per-run viewer at Org admin → Actions → Runs. Failed-job filter + workflow YAML diff vs last green run | Forgejo Actions UI + fremforge audit overlay | — |
| Runner usage panel | Per-month runner-minute count + per-job duration table at Org admin → CI runners → Usage. Drives invoice line items via the metering_events table | Custom (runner_jobs aggregation) | — |
AI posture
| Control | What it does | Tool | Configurable |
|---|---|---|---|
| BYO AI — agent-native access | fremforge is AI-agnostic. Customer Claude Code / Cursor / Windsurf / Codex CLI / Aider operate against the same Git + REST surface as humans (machine-readable OpenAPI spec). Combined with Agent-native authentication (direct IdP JWT bearer, RFC 8693 token exchange + OBO, RFC 6749 client_credentials), agents authenticate as first-class principals — no human PAT borrowing. No forge-locked-in AI product, no agentic features that demand a specific vendor | Standards-compliant Git + REST | Customer-controlled |
| AI integrations (BYOK) | Org admin → AI integrations: register your own AI vendor key (Anthropic, OpenAI, Mistral, others). Enables: AI PR review (drafts review comments on diff), Renovate AI explanations (plain-English changelog summaries on dep-bump PRs), and the /api/v1/orgs/<slug>/ai/complete gateway for workflow-side LLM calls | Custom gateway (fremforge-written) | Per-org vendor + key |
Compliance + audit
| Control | What it does | Tool | Configurable |
|---|---|---|---|
| Audit log | Every state-changing operation (push, role change, secret create, runner override, billing change) logged with actor + timestamp + before/after. Two-tier retention: queryable hot tier (90 / 180 / 365 / 730 days, configurable per tenant) + 3-year cryptographic-chain archive in T Cloud OBS WORM | Custom append-only (audit_events table) | Per-tenant retention window |
| Audit chain | Hash-chained audit log + Merkle root anchored every 2 min into T Cloud OBS WORM. Verifier cron checks chain integrity hourly + full-sweep every 30 min. Customers can verify “no event was deleted or modified after the fact” | Custom (fremforge-written, BSI C5 alignment) | — |
| SIEM streaming | Real-time stream of audit events to a customer-provided endpoint (Splunk HEC, Sentinel, ELK, OpenSearch, generic HTTPS webhook). EU-resident relay, no data leaves the eu-de region. Per-tenant endpoint health visible to operator + tenant admin | Custom forwarder + siem_endpoints table | Per-customer endpoint config |
| Data export (GDPR portability) | Self-service tenant data export: repos (as git bundles), audit events (JSON), members, secrets metadata, billing invoices. Streamed to a one-time signed OBS URL valid 24h. Required for GDPR Art. 20 portability + offboarding | Custom exporter | Triggerable any time |
| Lifecycle policies | Per-tenant retention + deletion automation: stale-repo archive, runner-minute-cap behaviour, audit-log retention window, tenant-suspension grace period, end-of-contract data-erasure SLA | Custom (tenant_lifecycle table) | Per-tenant policy |
| Repo mirroring (inbound migrations) | Pull-mirror customer repos from GitHub, GitLab, Bitbucket, or any other Git host into fremforge with credential-based auth + periodic sync. Used during phased migrations; mirror is removable once cutover is complete | Forgejo native pull-mirror + fremforge admin proxy | Per-repo source + interval |
| Notification preferences | Org-wide event routing: which audit events emit mail/webhook/SIEM, which roles get paged on Critical findings, billing-event escalation contacts | Custom (notification_preferences table) | Per-tenant routing |
| Vulnerability disclosure | security.txt published, security@frem.sh 24h ack SLA, public hall-of-thanks page, no-litigation-for-good-faith-research policy | — | — |
| Severity SLAs | Per-org SLA pill next to every open finding. Default deadlines (Critical 7d / High 30d / Medium 90d / Low none) — tightenable per tenant. NIST SP 800-40r4-anchored | Custom (fremforge-written) | Per-tenant tightening |
What we explicitly don’t do
| Anti-feature | Why |
|---|---|
| No Microsoft footprint (no GitHub, no Azure AD, no Office 365, no Defender, no GHAS CodeQL) | EU sovereignty + Schrems II — see trust |
| No US-hosted Sigstore / Fulcio / Rekor in the verification path | Same. fremforge runs its own Fulcio + TSA on T Cloud eu-de with the root CA in DEW KMS (FIPS 140-2 Level 3 HSM, Germany). No public Sigstore, no Rekor / transparency log — TSA-only timestamping by design |
| No AWS, GCP, or any US-cloud-controlled dependency on the platform critical path | Same |
| No third-party CDN-loaded fonts (Google Fonts etc.) | Self-hosted at www.frem.sh/fonts/ via Bunny EU edge |
| No black-box scanners (proprietary detection rules you can’t audit) | Customer audit trail requires tool-named transparency |
| No long-lived service-account credentials in customer workflows | OIDC-only for cloud auth; long-lived keys are an opt-in deprecated path |
Tool transparency — full bill of materials
If you need this for an RFP, BSI C5 audit, or internal security review, the canonical list — with versions, pull sources, and the platform-foundation vendor row — lives at docs.frem.sh/security/bill-of-materials/. The table below is a quick-reference subset.
| Layer | Tool | Where used | License |
|---|---|---|---|
| Source-control core | Forgejo v15 | Repo hosting, code review, Actions runner protocol | GPLv3 |
| CI runner binary | forgejo-runner (act_runner) v6.2.1 | Per-job ephemeral pod | MIT |
| Secret scanning | Gitleaks v8 | Pre-receive hook | MIT |
| SAST | OpenGrep v1.21 | PR-time analysis | LGPLv2.1 |
| Container CVE scanning | Trivy | Customer CI + runner-image baked-in | Apache 2.0 |
| Dependency scanning | osv-scanner | PR-time analysis | Apache 2.0 |
| SBOM generation | Syft | Release-tag workflow | Apache 2.0 |
| Image signing + verify | cosign | Customer CI via cosign-verify-images.yaml template | Apache 2.0 |
| Keyless code signing — CA | Fulcio v1.8.5 (Helm chart 2.9.0) | Self-hosted on T Cloud eu-de at sign.frem.sh | Apache 2.0 |
| Keyless code signing — TSA | Sigstore TSA (timestamp authority) | Self-hosted on T Cloud eu-de at tsa.frem.sh | Apache 2.0 |
| Customer-side gitsign | gitsign | Customer git client; OIDC-bound commit signing | Apache 2.0 |
| Dependency bumper | Renovate | Hosted bot, 15-min cron, per-repo opt-out | AGPLv3 |
| Image build (rootless) | kaniko | Container build in customer workflows | Apache 2.0 |
| Malware scanning | ClamAV | Pre-receive scan + LFS upload | GPLv2 |
| OpenSSF best-practice scoring | scorecard | Weekly per-repo | Apache 2.0 |
| Platform CDN + WAF | Bunny CDN | EU-resident edge, no Cloudflare/Fastly | (Vendor — EU-based, no US sub-processor) |
| Cloud platform | Open Telekom Cloud (Deutsche Telekom) | Compute, storage, networking, DB | (Vendor — eu-de region exclusively) |
| Email (transactional) | Lettermint (NL) | Auth emails, invoices, alerts | (Vendor — EU) |
| Mailbox | mailbox.org | Operational mailbox | (Vendor — EU) |
| Payments | Mollie (NL) | Billing | (Vendor — EU) |
| Bookkeeping | Dinero (DK) | Invoice issuance | (Vendor — EU) |
Every vendor on this list is contractually EU-resident with no US sub-processor in the data path. See the trust page for the full DPA + sub-processor chain.
Roadmap (demand-gated)
| Feature | Status | Trigger |
|---|---|---|
Bring-your-own-KMS for MASTER_ENCRYPTION_KEY (customer-supplied DEW CMK in their own T Cloud account) | Designed | First customer commits |
| SLSA Level 3 (hardened builder posture for the runner image build pipeline) | Designed | Customer demand |
| MCP signing + verifier for AI-agent supply chain | Designed | Industry standard finalises |