Documentation · v0.30.0

Administration Manual

Hardening, tenants, roles, policies, compliance, attestation, operations.

Manual for operators and administrators: commissioning and hardening, users and roles, tenants and budgets, adapter governance, policy-as-code, compliance profiles, attestation and audit export, supply chain, operations.

As of version 0.30.0. Deutsche Version: administrationshandbuch.md. The end-user manual is the user manual.

Contents

  1. Who this manual is for
  2. Commissioning and hardening
  3. Users and roles
  4. Tenants
  5. Adapter and model governance
  6. Approvals and segregation of duties
  7. Policy-as-code
  8. Compliance profiles
  9. Attestation and chain verification
  10. Why-trace and audit export
  11. Supply chain: SBOM and dependency scan
  12. Cost and budgets
  13. Skill and plugin library
  14. Operations: monitoring, backup, air-gap
  15. Settings reference
  16. Troubleshooting for administrators
  17. Known limits

1. Who this manual is for

This manual addresses operators (installation, hardening, backup) and administrators (users, tenants, rules, evidence). It assumes the user manual, which covers project creation, runs and the quality gate from an end-user perspective.

Supported operating modes:

Mode Description
Single seat One person, one machine, usually a coding CLI in subscription mode
Team Several users on one instance, RBAC active
Multi-tenant Several mutually isolated tenants on one instance
Air-gap No network: local model, network-less sandbox, licence without callback

Not covered: public SaaS with self-registration (see ../production-scope.md).


2. Commissioning and hardening

2.1 Mandatory values before the first start

Variable Requirement
SOFTWAREFABRIK_DB_PASSWORD β‰₯ 16 chars, random (openssl rand -base64 16)
SOFTWAREFABRIK_SECRETS_MASTER_KEY β‰₯ 32 chars, random (openssl rand -base64 48)
SOFTWAREFABRIK_ADMIN_USER / _PASSWORD Bootstrap admin; without a password no admin is created
SOFTWAREFABRIK_WORKSPACES_ROOT Directory for project workspaces

The application deliberately fails fast:

  • Docker Compose aborts without .env (${VAR:?…}).
  • In the container profile SecretsEncryptor hard-rejects known demo values and keys that are too short.
  • DbCredentialsValidator checks database credentials at startup.
  • In the Compose stack PostgreSQL is bound to 127.0.0.1.

2.2 Attestation key

SOFTWAREFABRIK_ATTESTATION_SIGNING_ENABLED=true
SOFTWAREFABRIK_ATTESTATION_KEY_ID=<meaningful-id>
SOFTWAREFABRIK_ATTESTATION_PRIVATE_KEY=/path/to/ed25519-key.pem
# optional: SOFTWAREFABRIK_ATTESTATION_KEYRING_PATH for key rotation

Development and test use an ephemeral key. In the container/prod profiles, enabled without a key is a startup error. Running without signatures must be declared explicitly (…SIGNING_ENABLED=false). Security should be a decision, not an oversight.

The key must go into the backup. Without it the audit chain can no longer be verified later.

2.3 Remote hardening

SOFTWAREFABRIK_GIT_ALLOWED_HOSTS=github.com,git.company.com   # allowlist
SOFTWAREFABRIK_GIT_PR_FEEDBACK_ENABLED=false                  # default

The factory uses the GitHub token and issues API calls only for hosts on the allowlist. Without that boundary a manipulated remote URL could exfiltrate the factory-wide token (SSRF). GIT_ALLOW_PROTOCOL is set as well, to rule out attacks via the git ext:: remote helper.

The PR/CI poller is deliberately opt-in: unattended periodic remote contact should be a conscious operational decision.

2.4 Sandbox

Settings β†’ execution.sandbox.variant = local | container
           execution.sandbox.image
           execution.sandbox.docker-binary

Container mode starts every agent run in an ephemeral container with --cpus 2 --memory 4g --pids-limit 512 --read-only, a bind mount restricted to the workspace and --network=none. If Docker is missing from the PATH the platform falls back to the local process sandbox with a log warning.

Recommendation: build runs execute agent-generated code. Run them on a host without sensitive access and enable container mode.

2.5 Demo profile

The demo profile installs an auto-login filter that treats every visitor as a shared demo user, plus a demo banner. It is meant exclusively for a public demo instance, never for production.


3. Users and roles

UI: /admin/nutzer (ADMIN only)

Create accounts, assign tenant and role, activate/deactivate accounts and reset passwords. A lockout guard kicks in after repeated failures.

Role model

VIEWER < DEVELOPER < MAINTAINER < OWNER < ADMIN

Capability from role
read VIEWER
execute runs DEVELOPER
approve runs MAINTAINER
manage integrations/secrets MAINTAINER
tenant administration OWNER

Important: ADMIN is not a data super-admin. Administrators remain tenant-scoped for projects, runs, logs and cost. Only account management and project assignment are isolation-free. A genuine operator view goes through the operator endpoints, not through an elevated data role.

SSO (OIDC)

Optional and config-gated (see ../sso-oidc.md). JIT-provisioned users deliberately get VIEWER without a tenant β€” an SSO connection must never widen access by accident. Assigning tenant and role stays an administrative act.


4. Tenants

UI: /mandanten

  • Create tenants and assign projects.
  • A user belongs to one tenant (app_user.tenant_id); null means single-tenant operation.
  • Projects, runs and all derived data are tenant-scoped. Access via a foreign ID fails (covered by an IDOR test).
  • Policy, audit, cost and export are separated per tenant.

For hard separation: tenants are sufficient in most cases. Where maximum separation is required (e.g. VS-NfD), one instance per tenant remains the most conservative option.


5. Adapter and model governance

Three levels, from wide to narrow:

  1. Global: execution.adapter.default and execution.<adapter>.model in Settings.
  2. Project: allowed adapters per project (project_allowed_adapters) plus a model policy (/projects/{id} β†’ model policy). It is enforced when a run is created and attested as RUN_MODELL_AUFGELOEST.
  3. Tenant: policy-as-code (chapter 7) can restrict allowed adapters tenant-wide; a tenant policy can only tighten the global one, never undercut it (global policy floor).

Capability routing: run.routing.plan-model and run.routing.build-model separate model choice for planning and implementation. Planning may get a stronger, more expensive model than mechanical implementation β€” without hard-wiring a model name anywhere.

Operating mode: betrieb.modus distinguishes single-seat subscription from a team API pool.

Subscription modes (execution.<adapter>.auth-mode = api-key | subscription) for Claude, Codex and Kimi. In subscription mode the factory actively strips the corresponding API key from the subprocess β€” otherwise the CLI would silently take the paid path.


6. Approvals and segregation of duties

There are two approval points per build run:

Point Effect
before EXECUTION The agent only runs after approval
before the merge (in VALIDATION) The validated state is merged or turned into a PR only after approval

The second point is decisive for regulated profiles: without it the signed assurance would be a faΓ§ade β€” the code would already be on the base branch before anyone agreed.

Controls:

  • run.approval-vor-merge β€” mandatory approval before merging
  • run.approval-segregation β€” segregation of duties: whoever triggered the run (run.triggered_by) cannot approve it
  • Approval policies under /policies

Approving requires role MAINTAINER or higher. Every decision is recorded as an approval_decision and as an attested audit event.


7. Policy-as-code

UI: /policy-as-code (ADMIN only)

Rules are not configuration state but a versioned, signed document:

Field Meaning
erlaubteAdapter vendor restriction (empty = unrestricted)
gateModus off / advisory / blocking
pflichtFreigabePhasen e.g. EXECUTION, VALIDATION
pflichtAttestierung signing mandatory

Properties:

  • Exactly one active version per tenant β€” technically enforced.
  • Ed25519-signed over the canonical text.
  • Enforced twice: when a run is created and again at execution time. Otherwise a run created before activation could bypass the policy; besides, why-trace and export must report the version that was actually enforced.

Workflow: edit content β†’ publish (creates a new signed version and deactivates the previous one) β†’ verify checks the signature.

Rejected runs produce RUN_POLICY_DENIED β€” the rejection is evidence too.


8. Compliance profiles

UI: /compliance-profile (ADMIN only)

Applying a profile publishes a matching signed policy version and emits COMPLIANCE_PROFILE_APPLIED.

Profile Gate Mandatory approvals Attestation
Baseline advisory β€” no
EU AI Act blocking EXECUTION yes
BAIT / MaRisk / DORA blocking EXECUTION, VALIDATION yes
BSI Grundschutz / VS-NfD blocking EXECUTION, VALIDATION yes

Regulatory reference: EU AI Act = Regulation (EU) 2024/1689, Art. 12 (record-keeping) and Art. 14 (human oversight); BAIT/MaRisk (BaFin) and DORA (EU 2022/2554) = ICT and third-party risk, evidence duties; BSI IT-Grundschutz and VS-NfD for the public sector.

Honest framing: the profiles enforce the technically enforceable parts. They do not replace legal advice and do not cover organisational duties. For VS-NfD the adapter choice must additionally be restricted to local/sovereign backends per project β€” regional data residency is enforced through gateway configuration, not through the profile.


9. Attestation and chain verification

UI: /attestierung (ADMIN only)

Every audit event carries seq, prev_hash, entry_hash, signature and key_id. Verification distinguishes three failure modes:

Finding Meaning
HASH_MISMATCH an entry was modified after the fact
CHAIN_BREAK an entry was removed or inserted
BAD_SIGNATURE the entry does not come from the expected key

Legacy entries without a signature are reported transparently as such instead of failing the check.

Attested events (selection): run lifecycle, model resolution, policy application and denial, guardrails application, quality-gate result, SBOM creation, artifact signature, policy publication, profile application, approvals.

Operational advice: run the chain check after every restore and on a regular schedule. An incomplete backup shows up as CHAIN_BREAK β€” the evidence structure doubles as an integrity check of the backup.


10. Why-trace and audit export

Why-trace: /runs/{id}/trace answers, for a single run, why the code came about the way it did: which model, which policy version, which approvals by whom, which gate result, which plan origin, which cost.

Audit export: /export (ADMIN only) produces an auditable bundle per project or run β€” JSON and HTML β€” from why-trace, chain verification, the governing policy state and the public key.

The bundle is deliberately serialized deterministically (strings, primitives and UUIDs only, timestamps as ISO-8601). Evidence that looks different depending on the library version is not evidence.

Typical audit case: the auditor asks about a specific change β†’ find the run β†’ the why-trace shows model, rule, approval β†’ export produces the bundle β†’ the auditor verifies signatures offline with the enclosed public key.


11. Supply chain: SBOM and dependency scan

Building block Control
SBOM per build run.sbom.mode (default off); requires Trivy on the PATH, degrades gracefully otherwise
Artifact signature Ed25519 over the SBOM digest, event ARTEFAKT_SIGNIERT
Dependency/licence scan Reviewer dependency-scan in the quality gate; CVE findings in the SECURITY category block the merge

For regulated environments: set SBOM to on and the quality gate to blocking; then every delivered state can be shown to have declared and checked its dependencies.


12. Cost and budgets

Views:

Route Content
/analytics cost per project, run, provider, comparison; each as CSV
/mandanten/kosten consumption per tenant (+ .csv)
/mandanten/seat-kosten consumption per seat β€” the triggering user, derived from run.triggered_by (+ .csv)

Setting limits:

  • mandant_budget β€” monthly EUR budget per tenant, either observing only or as a hard cap (enforce). Exceeding it prevents new runs.
  • budget.daily.tokens / budget.weekly.tokens β€” token limits with a soft threshold.
  • The capacity guard limits the number of concurrent runs.

Prices: the model price table lives in application.yml (softwarefabrik.models; input/output/cached per 1M tokens). Unknown models are valued at €0 β€” deliberately conservative. Subscription models (k3, kimi-for-coding) are also at €0 because a flat rate incurs no token cost; the cost view therefore reflects marginal cost, not licence cost.


13. Skill and plugin library

UI: /skills

Entries are tenant-scoped and versioned; origin is typed: CATALOG (curated), INSTALLED (adopted), FORKED (adapted). Before each run the platform materializes them into the workspace:

<workspace>/.claude/skills/<name>/SKILL.md
<workspace>/.claude/agents/<role>.md
<workspace>/.claude/settings.local.json

This makes it answerable which extension, in which version, was in the agent's context at the time of a run β€” the question every reproducibility discussion otherwise founders on.

Engineering guardrails (run.guardrails.mode) are separate: a vendor-neutral behavioural policy projected into the repo as AGENTS.md (plus a minimal CLAUDE.md pointing at it). Its version is a SHA-256 short hash of the content and is recorded as RUN_GUARDRAILS_ANGEWENDET.


14. Operations: monitoring, backup, air-gap

Monitoring

Endpoint Content
/actuator/health incl. secrets health indicator
/actuator/info version and build number
/actuator/prometheus metrics (ROLE_ADMIN only)

Logback writes projectId, runId and phase into the MDC.

Backup

Three things must be backed up:

  1. the PostgreSQL database,
  2. the workspace directory (contains the projects' Git repositories),
  3. the attestation key and the secrets master key.

Procedure: ../backup-restore.md. After a restore, run the chain check under /attestierung.

Air-gap

Requirement Implementation
No vendor cloud access adapter local-llm (Ollama/vLLM/LM Studio)
No network for the agent container sandbox with --network=none
No licence callback ADR-0009 (refresh-required=false)
No remote coupling PR poller off, allowlist empty or internal

Delivery: ../runbooks/airgap-auslieferung.md.


15. Settings reference

All settings follow the scope hierarchy PROJECT > USER > GLOBAL > YAML and take effect without a restart (max. 5 minutes of caching).

Key Meaning
betrieb.modus single-seat subscription or team API pool
execution.adapter.default default adapter
execution.<adapter>.model default model per adapter
execution.<adapter>.auth-mode api-key or subscription (claude, codex, kimi)
execution.<adapter>.subscription.config-dir alternate credential directory
execution.sandbox.variant local or container
execution.sandbox.image / .docker-binary container sandbox details
run.quality-gate.mode off / advisory / blocking
run.quality-gate.policy strict or lenient
run.approval-vor-merge mandatory approval before merging
run.approval-segregation segregation of duties
run.auto-followup-plan follow-up plan run after a successful build
run.guardrails.mode guardrails projection
run.sbom.mode SBOM creation per build
run.routing.plan-model / .build-model capability routing
budget.daily.tokens / budget.weekly.tokens token limits
git.pr-feedback.enabled PR/CI poller
workspace.root workspace root

Vendor keys are not managed here but under /integrations (AES-GCM encrypted, with provider validation for Anthropic, OpenAI, Gemini, Kimi, GitHub and NVD).


16. Troubleshooting for administrators

  • Application won't start, message about master key / demo value β€” the container profile deliberately forbids demo values and short keys. Set a random value.
  • Startup aborts with an attestation error β€” signing is enabled but no key is configured. Either provide a key or set …SIGNING_ENABLED=false explicitly.
  • Chain check reports BAD_SIGNATURE after a key rotation β€” keep the old key available via the keyring path; otherwise older entries can no longer be verified.
  • A user (even ADMIN) does not see foreign projects β€” correct: ADMIN is not a data super-admin. Work through tenant assignment.
  • Run rejected with RUN_POLICY_DENIED β€” the active policy does not allow the chosen adapter or model. Check the policy or switch adapters; the rejection is documented in the audit trail.
  • Run stuck in WAITING_FOR_APPROVAL β€” mandatory approval is active. Check who may approve (MAINTAINER and above) and whether segregation of duties excludes the triggering user.
  • Quality gate reports ERROR β€” a reviewer crashed (e.g. missing CLI). Deliberately not a silent pass: install the CLI or adjust the gate mode.
  • No SBOM produced β€” run.sbom.mode is off or Trivy is missing from the PATH.
  • Cost shows €0 β€” either a subscription model (flat rate, correct) or a model without an entry in the price table.

17. Known limits

Limit Meaning
One active run per project Different projects run in parallel; runs of the same project run sequentially
Budget caps per tenant The seat view reports but does not constrain
PR/CI feedback for GitHub only GitLab/Bitbucket/Azure DevOps not connected; the local merge applies there
Cloud gateways experimental Bedrock/Vertex/Azure OpenAI not verified end-to-end
Sandbox default is local Container mode is available but not the default

Current version: ../production-scope.md. Technical depth: ../governance-compliance.md.