# GovOPlaN Configuration Packages Configuration packages are reusable, versioned preconfigurations for a working GovOPlaN capability. They sit above modules: a module installs code, migrations, routes, permissions, and capabilities; a configuration package wires installed modules into a concrete operational setup. Example: an application-handling package could configure a public portal form, a case workflow, task creation, a mail template, payment processing, access roles, audit evidence, and the interface bindings between those modules. The guiding reference scenario is the government-operations permit journey in `docs/GOVOPLAN_MASTER_ROADMAP.md`: a person applies through the portal, uploads files, receives workflow-driven messages and appointment proposals, has a case opened, gets a permit generated from a template, and completes payment. Configuration packages are the mechanism that should make such processes reusable and safely importable. This document is durable architecture context and should be mirrored to the Gitea wiki. Active implementation should be tracked in Gitea issues. ## Goals - Import a preconfiguration from a trusted catalog or uploaded package. - Detect which modules, module versions, and capabilities are required. - Detect which configuration fragments must be created, updated, or bound. - Explain import problems and offer actionable resolution paths. - Ask the operator only for data needed to make the package work. - Export an existing working configuration as a reusable package. - Support signed catalogs so approved configurations can be shared, adapted, re-exported, and provided to other installations. ## Vocabulary | Term | Meaning | | --- | --- | | Module | Installable product code with manifest, migrations, routes, permissions, WebUI, events, and capabilities. | | Configuration | Module-owned settings and resources that make behavior concrete: workflows, forms, templates, roles, policies, connector profiles, routing rules, and defaults. | | Interface | A typed contract between modules: capabilities, commands, events, DTOs, data bindings, and UI extension points. | | Data | Operator- or tenant-provided values needed for a working setup: legal text, sender addresses, account mappings, payment provider credentials, templates, defaults, and optionally reference data. | The system should communicate these four layers explicitly: ```text module = what can exist configuration = what should exist here interface = how configured parts connect data = what the operator must provide for this deployment ``` ## Package Classes The same signed package mechanism supports several explicitly named classes: | Class | Purpose | | --- | --- | | `reference` | Prove a bounded journey, degraded states, recovery, and target-environment acceptance. | | `product` | Provide a reusable operating capability such as governed communication, service-to-decision, procurement/contracts, or governed BI. | | `sector` | Specialize terminology, forms, rules, process baselines, controls, reports, and integrations for an institutional sector without forking modules. | | `deployment` | Declare a supported infrastructure topology, operational assumptions, health gates, and recovery evidence. | | `integration` | Declare external systems, provider bindings, source-authority modes, maturity, required health, and reconciliation behavior. | Package class is metadata and validation context, not additional authority. A sector package does not become a module and cannot write another module's tables. Packages may extend other packages only through versioned fragments and must preserve provenance and parent constraints. The contract enforces class-specific evidence. Reference packages require target, recovery, security, operations, accessibility, privacy, and documentation evidence. Deployment and integration packages require their corresponding target/recovery/operations evidence, while integration packages also name provider authority and minimum-maturity expectations. Preflight blocks a missing, incompatible, or unhealthy provider. A derived package may tighten parent module, capability, and provider requirements but cannot remove or loosen them. Every non-documentation claim made by reference, deployment, or integration packages carries a `sha256:` binding. Repository checks recompute those hashes, while signed package verification protects the declared manifest during transport. ## Package Model A configuration package should be a signed, portable manifest plus module-owned configuration fragments. The package is not a database dump. It should be declarative, idempotent, tenant-aware, and explicit about secrets and external systems. Required package metadata: - stable package id, name, version, description, publisher, and license - supported GovOPlaN core/module compatibility bounds - required modules with version constraints - optional modules with conditional behavior - required capabilities, commands, event subscriptions, and UI extension points - configuration fragments grouped by owning module - interface bindings between fragments - data requirements to collect from the operator - preflight checks and post-import health checks - migration or transformation rules for older package versions - provenance, export source metadata, and signature metadata - package class and optional parent package/version constraints - source-authority bindings and provider-operation expectations for every external integration used by the package Portable configuration schemas follow `COMPATIBILITY_POLICY.md`: providers write only their current schema version and read that version plus the previous two versions. Older input must produce a version-specific staged-upgrade diagnostic. Configuration fragments are interpreted only by the module that owns them. For example, workflow imports workflow definitions; forms imports form schemas; mail imports mail templates and delivery defaults; payments imports payment profiles; access imports groups, roles, and permission assignments. ## Module Provider Contract Each module that wants to participate should expose a configuration-package provider capability. The core orchestrator should not understand module internals or write module-owned tables directly. Baseline provider responsibilities: - publish JSON Schema or equivalent typed schemas for importable/exportable fragments - publish data requirements that can be rendered by a generic wizard - validate fragments without applying them - report missing dependencies, missing permissions, conflicts, and unsafe changes - produce a dry-run plan with create, update, bind, skip, and blocked actions - apply fragments idempotently inside module-owned boundaries - export selected module-owned configuration into portable fragments - redact secrets and mark secret placeholders during export - provide post-apply health checks and operator-facing diagnostics Provider operations should be versioned. The first stable contract can be small: ```text describe() -> schemas, supported fragment types, exported scopes preflight(package_fragment, context) -> diagnostics, required_data, plan apply(package_fragment, supplied_data, context) -> result, created_refs export(selection, context) -> fragment, data_placeholders, warnings health(import_result, context) -> diagnostics ``` The initial core contract lives in `govoplan_core.core.configuration_packages`. Modules register providers through module-specific capability keys and implement the `ConfigurationProvider` protocol. The generic `configuration.provider` key names the contract and can be used in package requirements; concrete providers such as `access.configuration` are resolved by the admin package wizard. The first DTO surface includes package manifests, module/capability requirements, module-owned fragments, diagnostics, required operator data, dry-run plan items, apply results, export selections, and export results. The initial implementation includes provider-neutral orchestration helpers: - `dry_run_configuration_package(...)` - `apply_configuration_package(...)` - `export_configuration_package(...)` Portable fragments may bind deployment-specific operator input without placing that value in the signed reusable definition. A payload value of `{"$data": "requirement_key"}` references a key declared in the manifest's `data_requirements`. Preflight fails before invoking the owning provider when a reference is malformed, undeclared, or unresolved. Once supplied, Core replaces the reference in memory and passes only the resolved fragment to the provider. This mechanism is for deployment bindings and wording, not plaintext secrets: credential-envelope or environment references remain the normal portable boundary. The first concrete provider is `govoplan_access.backend.configuration_provider`. It supports access-owned `roles`, `groups`, and `group_role_assignments` fragments and applies them idempotently. Mail and Files also register providers for deployment configuration: Mail owns receipt-bound SMTP profiles and Files validates the deployment-owned managed-storage binding. ### Deployment capability receipt The installer mounts a bounded, non-secret infrastructure receipt at the path named by `GOVOPLAN_DEPLOYMENT_CAPABILITIES_PATH`. Core validates that document once for configuration-package context and exposes typed capability and post-install-task records to providers. Invalid receipts fail closed. Endpoint metadata is sanitized, and secret fields may cross this boundary only as `env:VARIABLE_NAME` references. Feature providers remain responsible for their own semantics: - Mail can derive host and port from `mail.smtp`, collect missing non-secret transport fields, and bind an existing credential-envelope id. It never accepts or exports a username, password, token, or decrypted credential. - Files compares `files.storage` with the effective runtime backend, endpoint, trust marker, bucket, and presence of referenced environment secrets. Storage remains deployment-owned, so the provider reports `skip` when they agree and blocks drift instead of rewriting process environment or storage credentials. - A system-scoped Mail profile requires system configuration authority. Tenant scope is the conservative default. - Existing Mail configuration is preserved unless a reviewed fragment explicitly selects `on_conflict: update`. Reapplying an unchanged fragment is a no-op. Ops projects the same Core-validated receipt. It must not maintain a second parser with different validation or secret-handling rules. Core also defines the inverse, read-only dependency-inventory contract used before the installer changes one of those infrastructure capabilities. An enabled module registers `infrastructure.dependency_inventory.` and returns bounded, stable references to its persisted configuration or data, a lifecycle state, scope, numeric metrics, and a required operator action. Providers must not return secrets or use this read to migrate state. The Core collector validates provider identity and capability coverage, orders records deterministically, and marks the complete inventory failed when any provider raises or violates the contract. Ops is the authorized projection boundary; the installer remains the consumer and must match installation id, freshness, completion and impacted capability coverage before apply. The admin wizard backend starts with these routes: - `GET /api/v1/admin/configuration-packages/catalog` - `POST /api/v1/admin/configuration-packages/dry-run` - `POST /api/v1/admin/configuration-packages/apply` - `POST /api/v1/admin/configuration-packages/export` ## Import Flow 1. Select a package from a trusted catalog or upload a package file. 2. Verify signature, channel, publisher trust, package compatibility, and schema. 3. Resolve required modules against installed modules and the module package catalog. 4. Produce a dependency plan for modules that must be installed or upgraded. 5. Ask the operator for required data using a focused wizard. 6. Run dry-run preflight across all participating module providers. 7. Show problems grouped by severity, owner module, and resolution. 8. Apply module/package changes in a dependency-safe order. 9. Run post-import health checks and show the final working status. 10. Store import provenance, package version, supplied non-secret metadata, and audit events. Provider applies may commit independently. Core therefore stops at the first apply or health blocker and reports an explicit rollback state. A blocked preflight or a no-op needs no recovery; a successful multi-provider mutation retains the reviewed pre-apply database snapshot as its generic rollback path; a later-provider failure is reported as a partial apply that requires snapshot recovery or an explicitly supported module-owned compensation. The generic wizard never claims atomic cross-module undo. The wizard should display everything necessary and nothing unnecessary. Generic sections should cover package trust, dependency plan, required data, conflicts, review, and result. Module-specific fields should appear only when the selected package and installed modules require them. ## Problem Model Import diagnostics should be structured and actionable, not free-text logs. Every problem should include severity, owner, affected object, explanation, and at least one suggested resolution when the system can infer it. Common diagnostic types: - missing module or incompatible module version - missing capability or disabled optional integration - missing operator-supplied data - missing permission or insufficient administrator scope - unresolved interface binding between modules - conflicting existing configuration - external service not reachable or credential test failed - policy or tenant-governance violation - unsafe overwrite, downgrade, or destructive change - schema validation failure - post-import health-check failure Resolution actions can include install module, upgrade module, enable integration, provide value, choose existing object, rename imported object, skip optional fragment, replace existing configuration, or cancel import. ## Export Flow Export should be possible from a working tenant or system configuration, but it must be intentional about data boundaries. 1. Select export scope: system, tenant, module set, workflow, form, case type, portal flow, or another domain object. 2. Ask participating modules to export owned fragments and data placeholders. 3. Classify exported material as configuration, reference data, sample data, secrets, or deployment-local data. 4. Redact secrets by default and replace them with data requirements. 5. Let the operator choose whether to include reference/sample data. 6. Validate the assembled package by running the same preflight path against a clean target context where possible. 7. Sign the package or produce an unsigned development package. 8. Optionally publish the package metadata to a configuration catalog. Exported packages should record provenance: source GovOPlaN version, module versions, exporter identity, timestamp, selected scope, redactions, and validation status. The orchestrator emits this provenance independently of provider payloads and lists secret requirement keys as redacted without serializing their supplied values. Providers still own the deeper rule that credentials, tokens, and decrypted envelope contents must never appear in exported fragments. ## Catalogs And Trust Configuration catalogs should follow the existing module package catalog model: a file-backed or remotely fetched JSON catalog with Ed25519 signatures, channel gating, trusted key ids, and operator-controlled trust policy. The initial catalog validator mirrors the module catalog environment model with configuration-specific names: ```bash GOVOPLAN_CONFIGURATION_PACKAGE_CATALOG=/srv/govoplan/configuration-catalogs/stable.json GOVOPLAN_CONFIGURATION_PACKAGE_CATALOG_URL=https://govoplan.example/configuration-catalogs/stable.json GOVOPLAN_CONFIGURATION_PACKAGE_CATALOG_CACHE=/srv/govoplan/runtime/configuration-catalog-cache/stable.json GOVOPLAN_CONFIGURATION_PACKAGE_CATALOG_REQUIRE_SIGNATURE=true GOVOPLAN_CONFIGURATION_PACKAGE_CATALOG_APPROVED_CHANNELS=stable,lts GOVOPLAN_CONFIGURATION_PACKAGE_CATALOG_TRUSTED_KEYS_FILE=/srv/govoplan/trust/configuration-catalog-keyring.json GOVOPLAN_CONFIGURATION_PACKAGE_CATALOG_SEQUENCE_STATE=/srv/govoplan/runtime/configuration-catalog-sequences.json GOVOPLAN_CONFIGURATION_PACKAGE_CATALOG_ENFORCE_SEQUENCE=true ``` Catalog entries should include: - package id, version, name, description, publisher, tags, and channel - package artifact URL or repository ref - signature metadata for the package artifact - required modules and version ranges for quick compatibility display - package category such as workflow, portal, case type, governance, connector, report, or tenant baseline - maturity flags such as official, verified, example, local, deprecated The catalog verifies that a package is approved to view and import. The package itself must still be signed and validated before use. ## Example Package Application handling through a public portal: Required modules: - `portal` for the public user-facing entry point - `forms` for the application form and validation - `cases` for the case record and case type - `workflow` for status transitions and automation - `tasks` for internal task creation - `templates` for mail/template rendering - `mail` for delivery profile and outbound message sending - `payments` for provider configuration and payment capture - `access` for roles, groups, and permissions - `audit` for import, case, mail, and payment evidence Required configuration: - portal route and access policy - form schema, validation rules, confirmation texts, and attachments - case type, fields, lifecycle states, and retention classification - workflow steps, transitions, assignees, and completion triggers - task template and queue/group assignment - mail template and delivery rule - payment product, amount rules, provider profile, and webhook binding - access roles/groups for clerks, reviewers, supervisors, and operators - audit event categories and evidence retention defaults Required operator data: - tenant or organizational unit - service name and public contact details - portal URL/path and legal imprint/privacy text - mail sender profile and reply-to mailbox - payment provider credentials or test-mode selection - responsible groups or users for task assignment - escalation contacts and deadlines - template wording and localized text overrides Potential problems: - `payments` is missing or the provider capability is unavailable - mail transport test fails for the selected sender profile - imported role names conflict with existing tenant roles - workflow references a task queue that does not exist - public portal base URL is not configured - required privacy/legal text is empty - webhook endpoint cannot be validated from the payment provider ## Ownership Core should own: - package and catalog signature validation - dependency resolution against installed modules and module catalogs - orchestration of provider preflight/apply/export operations - generic import/export APIs and audit envelope - generic wizard shell and problem display components Modules should own: - schemas and semantics for their own fragments - module-specific validation, apply, export, and health checks - module-specific UI capabilities only when generic generated controls are not sufficient - redaction and classification of module-owned secrets or sensitive data Access should own configuration fragments for users, groups, roles, permissions, API keys, and principal mappings. It should not own workflow, mail, payment, form, or portal semantics. Admin should expose the operator-facing catalog, import, export, and history screens through admin route contributions. The UI should keep the conceptual layers visible: modules, configuration, interfaces, and data. ## Implementation Slices 1. Define package manifest and diagnostic schemas. 2. Add core configuration-package provider capability contracts. 3. Implement catalog validation and package signature verification. 4. Add dry-run orchestration against mock providers. 5. Add admin catalog/import wizard screens using provider data requirements. 6. Implement export/import providers for access-owned roles/groups first. 7. Add providers in workflow/forms/templates/mail/payments/portal/cases/tasks as those modules mature. 8. Add round-trip tests: export a known setup, import into a clean tenant, verify health checks. 9. Add documentation and field-level help for package authors and operators. ## Acceptance Criteria For Tracking Issue - A Gitea tracking issue exists in `govoplan-core` for the cross-cutting feature. - The issue links module-specific follow-ups when implementation begins. - The first implementation exposes typed contracts rather than direct cross-module imports. - A signed example catalog and unsigned development fixture exist. - A dry-run import can identify required modules, missing data, and conflicts before applying changes. - An export can produce a package with secrets redacted into data requirements. - Admin UI shows a focused wizard and actionable diagnostic list. - Tests cover package validation, signature failure, dependency resolution, provider preflight, export redaction, and import idempotency.