TR 03187-Conformance Statement
CIVITAS/CORE aims to conform to Level 1 of BSI TR-03187, a German security recommendation for Urban Data Platforms. In the context of BSI TR-03187, CIVITAS/CORE implements requirements that pertain to "Entwickler" (Software Developers) and "Lösungsanbieter" (Integrators). Requirements that pertain to "Betreiber" (Operators) are out of scope.
The following sections detail how the pertinent requirements of BSI TR-03187 are fulfilled in CIVITAS/CORE.
Scope note on 3rd party components: The conformance assessment currently covers components developed by the CIVITAS/CORE project. Verification of 3rd party components (e.g. upstream container images, external libraries) is out of scope for the time being.
| Requirement | Status | Description |
|---|---|---|
| AR-1 Geringstmögliche Privilegien | Done | Least privilege enforced at multiple layers: OPA default allow := false with explicit permission grants only. Containers run as non-root (UID 1000/1001) with drop: [ALL] capabilities, readOnlyRootFilesystem: true, allowPrivilegeEscalation: false. Dedicated Kubernetes ServiceAccounts per deployment. Spring Security anyRequest().authenticated() catch-all. Mandated through Security Architecture Principles. |
| AR-2 Legacy-Clienttechnologien vermeiden | Done | For components developed by CIVITAS/CORE, ESLint rules block legacy HTML elements (<object>, <embed>, <applet>) at error level in the CI pipeline (see ESLint config and implementation ticket). |
| AR-3 Nicht verwendete Abhängigkeiten entfernen | In Progress | SSDLC policy (Section 6.6) and the Deployment Checklist (section "Production Requirements") mandate a reasonable effort to be made towards minimizing shipped artifacts. Todo: config adapters are not shipped piecemeal; all of them are in one container, should be changed. |
| AR-4 Version Pinning | In Progress | Ensured through Deployment Standards for container images (section "Version Management"), Front End Style guide for npm (section "Imports / Exports") and Back End Style guide for Java (section "Imports"). Java dependencies: all pinned in pom.xml. Frontend: pnpm-lock.yaml exists. Dockerfiles: version-tagged (some with SHA256 digests). Gap: Helm values for portal use tag: latest (backend + frontend images). Config-adapter and model-atlas have tag: "" (empty = latest). appVersion in config-adapter Chart.yaml = latest, model-atlas = snapshot. Model Atlas image tag resolved from images.yaml via gotmpl; default values.yaml falls back to Chart appVersion with pullPolicy: Always (mutable tags). |
| AR-5 Sitzungs-IDs zufällig und eindeutig | Done | All JPA entities use @GeneratedValue(strategy = GenerationType.UUID) (Level 4 random UUIDs). Frontend session IDs (UML modeler, pipeline editor) use crypto.randomUUID(). Backend is stateless (SessionCreationPolicy.STATELESS), no server-side session IDs. Auth sessions delegated to Keycloak. |
| AR-6 Sitzungsablauf nach Inaktivität | Done | Frontend inactivity timeout stops background session refresh after idle period (default 55 min) and signs the user out, aligning with Keycloak 60-min ssoSessionIdleTimeout. Configurable via NEXT_PUBLIC_SESSION_IDLE_TIMEOUT_SECONDS. (MR !277 -- in review) |
| AR-7 Rollenbasierte Benutzerverwaltung | Done | Role-based user management is implemented. Users are assigned role "Standard User" on registration. For details, see Authorization Data Model. |
| AR-8 Replay-Schutz | Done | User authentication is performed system-wide by OpenID Connect with signed JWT tokens including timestamps. Kafka messages use CloudEvents with unique UUIDs and timestamps per message. Portal-backend has enable.idempotence: true (exactly-once per partition). Config-adapter saga engine deduplicates per dataset (existsForDataset() check). Manual synchronous offset commits ensure at-least-once delivery. mTLS via Linkerd provides transport-layer replay protection. |
| AR-9 Geheimnisse müssen änderbar sein | Done | As per SSDLC (section 9) and Deployment Standards (Section "Security"), secrets are stored through Kubernetes secrets or other secure means external to the application, in a changable manner. Exception: Keycloak stores secrets (passwords, signing keys) in database; all of them are changable through regular Keycloak mechanisms. |
| AR-10 Geheimnisse von Benutzern dürfen nicht zur Sicherstellung von Vertraulichkeit verwendet werden | Done | User credentials are managed exclusively by Keycloak and never used for data confidentiality. All confidentiality mechanisms (TLS, K8s secrets) use system-managed credentials. Architectural separation: Keycloak handles user secrets, everything else uses infrastructure-level secrets. The requirement is also part of the Security Architecture Principles. |
| AR-11 Kryptografische Verfahren sollen TR-2101-1 entsprechen | Done | Production code uses BSI-approved algorithms: AES-256-GCM for credential encryption (CryptoUtils.java), PBKDF2-HMAC-SHA256 with 600k iterations for key derivation (CryptoKeyLoader.java), HKDF-SHA256 for per-credential key isolation, RS256 and ES256 for JWT/WebAuthn signatures (Keycloak realm config). No weak ciphers (DES/3DES/RC4/Blowfish) in production code. Requirement to use BSI-approved cryptography is also part of Backend Code Style Guide and Deployment Standards. |
| AR-12 Standardframeworks für sicherheitskritische Funktionen | Done | Standard frameworks used for all security-critical functions: Spring Security (backend auth/authz), Keycloak (identity management), NextAuth (frontend session management), Jackson (deserialization), OPA (policy enforcement), Linkerd (mTLS). No custom cryptography or authentication implementations. Ensured through inclusion in Security Architecture Principles document. |
| AR-13 Ganze Zertifikatkette validieren | Open | Ingress-side TLS validation is the operator's responsibility. In-cluster, Linkerd service mesh is configured for mTLS (namespace-level sidecar injection enabled in prepare/helmfile.yaml.gotmpl). Application-level TLS verification (ssl_verify, NODE_TLS_REJECT_UNAUTHORIZED) is intentionally delegated to the mesh layer.Gap: Linkerd mTLS is currently opportunistic — no Server/AuthorizationPolicy CRDs enforce it, meaning connections could fall back to plaintext if a sidecar is missing. Action needed: add Linkerd AuthorizationPolicy resources to enforce mTLS and reject non-meshed connections. |
| AR-14 Alle vorgesehenen Sicherheitsmechanismen defaultmäßig anschalten | In Progress | Security mechanisms enabled by default: Frontend sets CSP (nonce-based), X-Content-Type-Options, X-Frame-Options, Referrer-Policy via Next.js middleware. Keycloak has brute force protection enabled in production (10-attempt lockout). Trivy container scanning feeds into GitLab Security Dashboard. CSRF intentionally disabled (stateless JWT API). Kyverno policies enforce pod security standards (drop-all-caps, read-only rootfs, probes, resource limits). Gaps: (1) Kyverno policies are in Audit mode (not Enforce). (2) APISIX does not strip inbound headers used for authorization decisions (risk: header injection/spoofing to bypass APISIX→OPA filtering). (3) APISIX does not set security response headers on API responses. |
| AR-15 Verschlüsselte Kommunikation | Open | Encryption between container instances is implemented through TLS via Linkerd service mesh. Namespace-level sidecar injection is enabled. Application-level TLS verification is delegated to the mesh layer. Gap: Linkerd mTLS is currently opportunistic — no AuthorizationPolicy CRDs enforce it. Action needed: same as AR-13. |
| AR-16 Abschirmung unterschiedlicher Vertrauenszonen | In Progress | Namespace-based isolation is implemented: 12+ component-specific namespaces when singleNamespace: false (portal, keycloak, authz, postgres, kafka, etcd, apisix, config-adapters, model-atlas, apicurio, frost, redpanda-connect). NetworkPolicies exist for 11 components with pod-level ingress restrictions. Linkerd mTLS between pods.Gaps: default deployment uses singleNamespace: true. No namespace-level default-deny NetworkPolicies. Recommendation: switch default to singleNamespace: false and add default-deny policies.Concept Ticket |
| AR-17 Integritätsgeschützter Kanal für Deployment | In Progress | CIVITAS/CORE is deployed as source code and helm charts through Gitlab and container images through Gitlab container registry. Gitlab enforces TLS, so integrity and authentication are ensured. TODO: implement signing for containers (implementation ticket) |
| CT-1 Container-Hardening | In Progress | All CIVITAS/CORE-developed components (Portal, AuthZ, Model-Atlas, Config-Adapter, ETCD) implement full container hardening: runAsNonRoot: true, drop: [ALL] capabilities, readOnlyRootFilesystem: true, allowPrivilegeEscalation: false, runAsUser: 1000. Dockerfiles set non-root users (UID 1001).Gap: Apicurio (3rd party) has no securityContext configured. Kyverno policies for hardening exist but are in Audit mode (not Enforce). |
| CT-2 Werkzeuggestützte Prüfung auf Container-Sicherheitslücken | Done | Trivy scans are used to scan container images. (implementation ticket) |
| CT-3 Basisimages aus vertrauenswürdigen Quellen | Done | All container base images are sourced from trusted, well-established providers: - eclipse-temurin (Adoptium/Eclipse Foundation) — Java components (portal-backend, config-adapter) - node (Docker Official Image) — portal-frontend - alpine (Docker Official Image) — build stages - openpolicyagent/opa (CNCF project) — policy engine (authz) - busybox (Docker Official Image) — Model Atlas init container AuthZ repository uses SHA256 digest pinning for reproducible builds. Model Atlas uses eclipse-temurin:21-jre-alpine.Mandated through Deployment Standards (section "Version Management"). |
| CT-4 Minimalistische Basisimages | In Progress | Alpine-based images are used for all components (eclipse-temurin:21-jre-alpine, node:22-alpine), which are minimal compared to full OS images. JLink for custom minimal JRE is not yet implemented but is a planned improvement per the Backend Style Guide. Model Atlas: same eclipse-temurin:21-jre-alpine, single OSGi fat JAR, no JLink. |
| CT-5 Geheimnisse zur Laufzeit dynamisch bereitstellen | Done | As per SSDLC (section 9) and Deployment Standards (Section "Security"), secrets are stored through Kubernetes secrets or other secure means external to the application. Helm templates use secretKeyRef to inject secrets from Kubernetes Secrets at runtime. No secrets are baked into container images. CI pipeline includes secret scanning to prevent hardcoded secrets from being merged.Exception: Keycloak stores secrets (passwords, signing keys) in database; all of them are changeable through regular Keycloak mechanisms. |
| CT-6 Gehärtete Clusterknoten | Not Applicable | Since CIVITAS/CORE assumes it runs on an existies kubernetes cluster, this requirement is out of scope for CIVITAS/CORE. |
| CT-8 Geringstmögliche Privilegien für Container-Images | Done | All CIVITAS/CORE-developed containers run as non-root: Helm deployments set runAsUser: 1000, runAsNonRoot: true. Dockerfiles create non-root users (UID 1001). Additionally: drop: [ALL] capabilities, readOnlyRootFilesystem: true, allowPrivilegeEscalation: false. Ensured through Deployment Standards (section "Security").Note: Apicurio (3rd party) does not have a securityContext configured. |
| CT-9 Transportverschlüsselung & Integrität zwischen Pods | In Progress | Encryption between container instances is implemented through TLS via Linkerd service mesh. Namespace-level sidecar injection is enabled. NetworkPolicies for Linkerd proxy ports (4143, 4190, 4191) are configured. Gap: Linkerd mTLS is opportunistic — no AuthorizationPolicy CRDs enforce it. See AR-13 for details. |
| MS-3 Vermeidung fester Credentials für Managed-Service-Zugriffe | Not Applicable | Not applicable, as any possible managed service access is outside the scope of the application's design. |
| AUT-1 Einheitliche Vertrauensniveaus in der Authentifizierung | Done | Authentication is centralized through Keycloak. For Keycloak, no fallback methods (e.g. password reset through security questions) are defined. Single trust level for all users. |
| AUT-2 Multi-Faktor-Authentisierung | In Progress | CIVITAS/CORE uses Keycloak as the identity provider for all components. MFA support is available through Keycloak (WebAuthn/OTP with ES256/RS256), and a custom browser flow with conditional 2FA is configured. MFA is not yet enabled by default in the installation — enabling MFA is a planned improvement. |
| AUT-3 Dedizierte Serviceaccounts | Done | Dedicated ServiceAccounts are used per Deployment (see section "Security" in the Deployment Standards). Verified in Helm deployment templates: each component (Portal, AuthZ, Model-Atlas, Config-Adapter, ETCD) has its own ServiceAccount definition. |
| AUT-4 Kryptografisch abgesicherter Zugriff auf Infrastruktur | Done | Infrastructure access is the operator's responsibility. CIVITAS/CORE provides Keycloak with WebAuthn support (ES256/RS256) as an available cryptographic authentication mechanism. Operators can enable cryptographically secured access for administration. Direct Keycloak admin access is not a supported use case in the CIVITAS/CORE operational model. |
| AUT-5 Zugriffskontrollmodell definieren | Done | The authorization model is documented here |
| AUT-6 Sitzungs-IDs invalidieren | Done | CIVITAS/CORE uses Keycloak for authentication and Keycloak supports this out of the box. |
| AUT-7 Passwortrichtlinien | Done | Keycloak enforces password policies per TR-03187: user realm requires min 12 characters with uppercase, lowercase, and digit (length(12) and upperCase(1) and lowerCase(1) and digits(1)). Master/admin realm requires min 20 characters with additional special character. Authentication is centralized through Keycloak via NextAuth (OIDC), so these policies apply to all user-facing authentication. |
| W-1 Deny All als Default | Done | Four-layer deny-all-by-default: (1) OPA default allow := false with explicit permission-based allow rules only (main.rego). (2) APISIX bearer_only: true rejects requests without valid JWT. (3) Spring Security anyRequest().authenticated() catch-all (SecurityConfig.java). (4) NextAuth middleware denies unauthenticated access to all non-public paths. This is mandated as part of the SSDLC (Section "3. Requirements you need to fulfill"). |
| W-2 Zugriffskontrollmodell definieren | Done | The authorization model is documented in the Authorization Data Model and implemented via OPA Rego policies (permission evaluation with provider-based endpoint mapping) and Keycloak RBAC. |
| W-3 Einheitlicher Zugriffskontrollmechanismus | Done | Unified access control via APISIX (API gateway) + OPA (policy engine). All /v2/* API routes pass through the same OIDC authentication + OPA authorization chain (plugin_config: openid_opa_proxy_rewrite_request_id). Frontend access control handled through NextAuth middleware. |
| W-4 Restriktive CORS-Policy | Done | No CORS configuration in backend (no @CrossOrigin annotations, no CorsConfiguration beans, no wildcard origins). Backend is not directly exposed to browsers — APISIX handles API gateway concerns. Ingress-level CORS is operator responsibility (see also W-17). CORS policy mandated through Backend Style Guide (section "CORS-Policy"). |
| W-5 Web-Server-Verzeichnisauflistung deaktivieren | Done | Spring Boot embedded Tomcat disables directory listing by default; no override found. Next.js serves only explicitly referenced assets from public/. No ResourceHandlerRegistry configured. Model Atlas uses Jetty, which also cannot list directories by default. |
| W-6 Nicht benötigte Datei-Metadaten und Sicherungskopien vermeiden | Done | Dockerfiles COPY only production artifacts (JARs, .next/, public/). No backup or metadata files in deployed images. AuthZ has explicit .dockerignore. Spring Boot and Jetty do not serve static files without specific provisions. |
| W-7 Sitzungs-IDs nach Logout invalidieren | Done | Federated logout implemented: NextAuth signOut() clears the JWT session and calls Keycloak's OIDC logout endpoint with id_token_hint (auth.config.ts signOut event). Both the local NextAuth JWT and the Keycloak SSO session are terminated. Implementation details documented in Authentication Flow. |
| W-8 Kurzlebige JWTs | Done | Keycloak token lifetimes (base-values.yaml.gotmpl): access token 5 minutes (accessTokenLifespan: 300), SSO Session Idle 60 minutes, SSO Session Max 10 hours. Admin realm stricter: SSO idle 30 minutes. Frontend session maxAge 10 hours.(Implementation ticket) |
| W-9 Sichere DB-Zugriffe (ORM/Prepared) | Done | Spring Data JPA with parameterized @Query annotations used throughout. All queries use :paramName binding — no raw SQL or string concatenation detected. Enforced through Backend Style Guide (section "Security"). |
| W-10 Vom Benutzer übergebene Objekte defensiv deserialisieren | Done | Jackson ObjectMapper without dangerous enableDefaultTyping()/activateDefaultTyping(). Custom deserializers (e.g. UpstreamNodes.NodesDeserializer) validate JSON token types explicitly before deserializing. No XXE-vulnerable XML parsing. Handled through Backend Style guide (section "Security") and Model Atlas EMF/Jackson validation. Model Atlas: Jackson configured via Gecko codec framework (no dangerous typing). Also accepts XMI/Ecore deserialization via EMF (EcoreMessageBodyHandler) — EMF deserialization creates model objects from schema (not arbitrary Java objects), safe by design. |
| W-11 Clientseitige Eingabevalidierung | Done | Client-side validation implemented through React Hook Form with Zod schemas. Forms enforce email validation, length constraints (min/max), regex patterns, and required fields. Examples: UserInputDTO uses z.email(), z.string().min(2), phone validation with regex; DatasourceInputDTO uses z.string().trim().max(150). Mandated through Frontend Style Guide (section "Security Principles").Model Atlas gap: /models/ HTML listing endpoint inserts EPackage names and nsUri values unescaped into HTML output (XSS risk). Mitigated by NetworkPolicy (only portal-backend can reach Model Atlas), but output encoding should be added. |
| W-12 Serverseitige Eingabevalidierung | In Progress | Server-side validation via Jakarta Bean Validation: @Validated on BaseController, @Valid @RequestBody on create/update endpoints. 16 of 21 input DTOs have constraint annotations (@NotBlank, @Email, @Size).Gap: DistributionInputDTO (accessUrl), ResourceInputDTO, and DataSourceInputDTO lack validation annotations. Enforced through Backend Style Guide (section "Security"). Model Atlas gap: zero Bean Validation on any REST endpoint. EPackageResource accepts full EPackage objects with only null-check on nsUri. Query params (nsUri, eClass, docType) are raw unsanitized strings. Internal-only access (NetworkPolicy) does not exempt from TR conformance. |
| W-13 Limitierung Anzahl Ergebnisse Datenbankabfragen | Done | Pagination enforced via @PageableDefault(size=20, sort="createdAt", direction=DESC) on BaseController.getAll(). All list endpoints inherit pagination. No unbounded result sets. All controllers extend BaseController and inherit pagination enforcement.Model Atlas: EPackageResource accepts skip/limit query params with @DefaultValue("0")/@DefaultValue("100"). Pagination exists but no max bound on limit. Accepted given internal-only access (NetworkPolicy restricts to portal-backend only). |
| W-14 Standardzugangsdaten ändern | Done | Authentication is centralized through Keycloak. The Keycloak admin password is injected from a Kubernetes Secret (keycloak-admin-user) generated by the secrets component at installation time. No hardcoded default credentials exist in the codebase. |
| W-15 Whitelisting für Eingabedaten | In Progress | Standard Bean Validation annotations are in place across portal-backend input DTOs (@NotBlank, @Email, @Size).Gap: No explicit allowlist regex patterns or enum constraints are used. Validation relies on type-level and format-level checks rather than strict value whitelisting. Mandated through Backend Style Guide (section "Security"). |
| W-16 Whitelisting für URLs in Eingabedaten | In Progress | Mandated through Backend Style Guide (Section "Security") |
| W-17 Whitelisting für Allow-Origin | Not Applicable | Should be done at ingress and is thus responsibility of the operator. We recommend the following CORS settings: * Access-Control-Allow-Origin allows only specific domains, not . Access-Control-Allow-Methods contains only the HTTP verbs required by the use case (e.g. GET, POST). * Access-Control-Allow-Headers is defined explicitly, not through wildcards. * Access-Control-Allow-Credentials is only set when required by the use base. |
| W-18 Detaillierte Fehlermeldungen Produktivsystemen vermeiden | Done | This is mandated as part of the SSDLC (Section "3. Requirements you need to fulfill") |
| W-19 Minimale Auskunft über Komponenten | Done | Actuator endpoints restricted to health, info, and prometheus (application.yaml). No server header configured (Spring Boot default: no disclosure). Stack traces not exposed (default NEVER in production). Next.js x-powered-by disabled. AuthZ health endpoint: show-details: never. Mandated as part of SSDLC policy (section 3). Model Atlas (internal-only): e.getMessage() returned in 500 responses from XMI deserialization errors. Swagger UI at /swagger-api/. No ExceptionMapper for unhandled errors. Not a conformance issue as Model Atlas is internal-only (NetworkPolicy restricts to portal-backend, no ingress) — absence of auth/authz means these are defense-in-depth concerns only. |
| W-21 Keine sensiblen Daten in URLs | Done | Tokens transmitted exclusively in Authorization headers (Bearer), never in URLs. Refresh tokens sent via POST body (application/x-www-form-urlencoded). Frontend proxy explicitly strips cookies from forwarded requests. API path parameters used only for UUIDs, never for tokens or passwords. This is mandated as part of the SSDLC (Section "3. Requirements you need to fulfill"). |
| W-22 Clientseitiges Caching und Autocomplete abschalten | In Progress | Mandated in the Frontend Style Guide (section "Security Principles"). |
| W-23 HSTS aktivieren | Not Applicable | This needs to be set at the egress and is thus responsibility of the Operator. |
| IoT-1 Zugang allen IoT-Ressourcen standardmäßig verweigern | Not Applicable | Not applicable, as there is no direct traffic from IoT devices to CIVITAS/CORE. |
| IoT-2 Einheitlicher Zugriffskontrollmechanismus | Not Applicable | Not applicable, as there is no direct traffic from IoT devices to CIVITAS/CORE. h Security Architecture Principles |
| IoT-3 Authentifizierung und Autorisierung für IoT-Geräte | Not Applicable | Not applicable, as there is no direct traffic from IoT devices to CIVITAS/CORE. |
| IoT-4 Standardzugangsdaten ändern | Not Applicable | Not applicable, as there is no direct traffic from IoT devices to CIVITAS/CORE. |
| IoT-5 Device Onboarding | Not Applicable | Not applicable, as there is no direct traffic from IoT devices to CIVITAS/CORE. |
| IoT-6 Generierung von Netzschlüsseln nach Zufallsprinzip | Not Applicable | Not applicable, as there is no direct traffic from IoT devices to CIVITAS/CORE. h Security Architecture Principles |
| IoT-7 Erneuerung Netzschlüssel | Not Applicable | Not applicable, as there is no direct traffic from IoT devices to CIVITAS/CORE. |
| IoT-8 Replay-Schutz | Not Applicable | Not applicable, as there is no direct traffic from IoT devices to CIVITAS/CORE. |
| IoT-9 Eindeutige Identifikation von IoT-Geräten | Not Applicable | Not applicable, as there is no direct traffic from IoT devices to CIVITAS/CORE. |
| VPN-1 VPN-Verschlüsselungsverfahren gemäß TR-02101-1 | Not Applicable | Not applicable, as VPN is assumed to be handled by the Operator at an infrastructure level. Document in a suitable "Product Scope" type document. |
| VPN-2 Sichere Konfiguration VPN-Gateway | Not Applicable | Not applicable, as VPN is assumed to be handled by the Operator at an infrastructure level. Document in a suitable "Product Scope" type document. |
| L-1 Logging von Sicherheitsereignissen | Done | Security event logging implemented across components: OPA decision logs enabled (JSON, console) with sensitive header masking via mask.rego. Keycloak logs 68 event types (LOGIN, LOGIN_ERROR, admin events with details, account changes, token events, MFA events; 30-day retention). Backend SecurityExceptionHandler logs auth failures (401), access denied (403), and JWT validation failures at WARN level. Config-adapter logs connector lifecycle events. Frontend logs proxy auth events via Pino (JSON in production). See concept ticket. |
| L-2 Logging von fehlgeschlagenen Authentisierungsvorgängen und allen Authorisierungvorgängen | Done | Failed authentication logged by: Keycloak LOGIN_ERROR + all *_ERROR event types (68 event types configured). Backend SecurityExceptionHandler catches 401/403 at WARN level. OPA decision logs capture authorization denials with reason codes (default_deny, permission_denied, unknown_endpoint). OPA mask.rego redacts tokens, authorization headers, and userinfo from decision logs. See concept ticket. |
| L-3 Schutz von Logs vor unbefugtem Zugriff | Done | All CIVITAS/CORE components write logs exclusively to stdout without storing them. OPA decision logs mask sensitive headers (tokens, authorization, userinfo) via mask.rego. Keycloak stores events in its database with 30-day retention; that database is only accessible by the Keycloak service. Log storage, integrity, and access control are the operator's responsibility; the hardening guide documents minimum expectations. |
| L-4 Sensible Informationen nicht loggen | In Progress | Sensitive data masking implemented across all CIVITAS/CORE-developed components: - Portal-backend: OWASP Encode ( Encode.forJava()) for log injection prevention. maskSensitiveFields() with MASKED_VALUE = "********" for connector secrets.- Config-adapter: OWASP Encode for log injection prevention. - AuthZ: UUID masking ( ab12****ef34) in decision logs. OPA mask.rego masks tokens, authorization headers, and base64-encoded userinfo (PII).- Frontend: Pino header filtering (only non-sensitive headers logged). Mandated by Backend Style Guide (section "Logging"). Gap (Model Atlas, planned for 26.2): Uses raw System.out/err.println bypassing the logging framework. EMFFileWatcher.java dumps full serialized .jsonschema content to stderr. Multiple e.printStackTrace() calls. No structured logging or sensitive data masking. |
| DH-1 Verschlüsselung At-Rest | Not Applicable | Not applicable, as this is considered the responsibility of the operator. CIVITAS/CORE assumes encryption to be handled transparently at a volume level. |
| DH-2 Schutz geheimer Schlüssel | Done | As per SSDLC (section 9) and Deployment Standards (Section "Security"), secrets are stored through Kubernetes secrets or other secure means external to the application. Exception: Keycloak stores secrets (passwords, signing keys) in database. |
| DH-4 Data Governance-Vorgaben etablieren | Open | CIVITAS/CORE provides a variety of features through which organizations can implement data governance: * Fine grained permission management * Separation of Data Sources and Data Sets * Data Sets, Data Sources and Data Models can have custom metadata tags * Data Provience tracking is enabled by making the Data Source a first-class-citizen. Furthermore, Data Sets can be Data Sources aswell, which creates a explicitly trackable graph of data provenance/data lineage *Data Sets have metadata describing the data semantically and organizational based on the DCAT-AP.de 3.0 standard |
| ORG-7 Tests nur auf dedizierter Umgebung | Not Applicable | Neither Civitas Connect nor any of the members of the project team provide a production environment. Therefore this requirement is not applicable. All tests are run on dedicated environments with synthetic data. The requirement for synthetic data is part of the Security Architecture Principles. |
| ORG-8 Penetrationstests | In Progress | Penetration Tests are planned and tracked through Gitlab Epic Penetration Test |
Generated on 10 March 2026, 12:27 UTC from https://gitlab.com/civitas-connect/civitas-core/requirements (labels: requirement-source::tr-03187, tr-level::1).