fadenstack 0.4.5__tar.gz → 0.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. {fadenstack-0.4.5 → fadenstack-0.5.0}/PKG-INFO +15 -5
  2. {fadenstack-0.4.5 → fadenstack-0.5.0}/README.md +13 -4
  3. {fadenstack-0.4.5 → fadenstack-0.5.0}/hatch_build.py +9 -1
  4. {fadenstack-0.4.5 → fadenstack-0.5.0}/pyproject.toml +2 -1
  5. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/__init__.py +1 -1
  6. fadenstack-0.5.0/src/faden_cli/bundle/pii-catalog.json +44 -0
  7. fadenstack-0.5.0/src/faden_cli/bundle/shared/docker-compose.pii-gpu.yaml +10 -0
  8. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/bundle/shared/docker-compose.yaml +223 -38
  9. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/bundle/shared/initdb/01-init.sql +2 -0
  10. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/bundle/shared/nginx/locations.conf +4 -1
  11. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/bundle/shared/nginx/rate-limits.conf +10 -0
  12. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/cli.py +4 -0
  13. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/admin.py +41 -68
  14. fadenstack-0.5.0/src/faden_cli/commands/audit.py +34 -0
  15. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/backup.py +116 -0
  16. fadenstack-0.5.0/src/faden_cli/commands/chats.py +68 -0
  17. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/deploy.py +113 -14
  18. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/dev/dev_down.py +1 -0
  19. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/dev/dev_up.py +26 -14
  20. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/doctor.py +63 -0
  21. fadenstack-0.5.0/src/faden_cli/commands/module.py +206 -0
  22. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/rebuild.py +27 -14
  23. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/restore.py +71 -6
  24. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/secrets.py +72 -14
  25. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/up.py +6 -0
  26. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/upgrade.py +107 -4
  27. fadenstack-0.5.0/src/faden_cli/core/backend_tool.py +65 -0
  28. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/backup.py +102 -11
  29. fadenstack-0.5.0/src/faden_cli/core/backup_crypto.py +334 -0
  30. fadenstack-0.5.0/src/faden_cli/core/backup_key.py +217 -0
  31. fadenstack-0.5.0/src/faden_cli/core/chat_retention.py +67 -0
  32. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/compose.py +46 -1
  33. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/detect.py +1 -1
  34. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/dev_modules.py +11 -4
  35. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/env_gen.py +97 -91
  36. fadenstack-0.5.0/src/faden_cli/core/pii_artifacts.py +103 -0
  37. fadenstack-0.5.0/src/faden_cli/core/pii_catalog.py +36 -0
  38. fadenstack-0.5.0/src/faden_cli/core/pii_hardware.py +113 -0
  39. fadenstack-0.5.0/src/faden_cli/core/pii_runtime.py +431 -0
  40. fadenstack-0.5.0/src/faden_cli/core/provenance_keys.py +448 -0
  41. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/registry.py +59 -2
  42. fadenstack-0.5.0/src/faden_cli/core/release_notice.py +71 -0
  43. fadenstack-0.5.0/src/faden_cli/core/sealing.py +65 -0
  44. fadenstack-0.5.0/src/faden_cli/core/secret_files.py +91 -0
  45. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/secret_rotation.py +51 -7
  46. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/settings.py +7 -0
  47. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/sysinfo.py +47 -11
  48. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/tune.py +2 -0
  49. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/conftest.py +6 -1
  50. fadenstack-0.5.0/tests/test_backup_encryption.py +449 -0
  51. fadenstack-0.5.0/tests/test_backup_migration_heads.py +61 -0
  52. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_backup_schedule.py +1 -0
  53. fadenstack-0.5.0/tests/test_chat_retention.py +66 -0
  54. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_dev_modules.py +12 -3
  55. fadenstack-0.5.0/tests/test_generated_env_reaches_compose.py +77 -0
  56. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_inactive_modules.py +2 -2
  57. fadenstack-0.5.0/tests/test_module_secrets.py +135 -0
  58. fadenstack-0.5.0/tests/test_pii_artifacts.py +41 -0
  59. fadenstack-0.5.0/tests/test_pii_catalog.py +115 -0
  60. fadenstack-0.5.0/tests/test_pii_hardware.py +153 -0
  61. fadenstack-0.5.0/tests/test_pii_runtime.py +60 -0
  62. fadenstack-0.5.0/tests/test_pii_upgrade.py +54 -0
  63. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_postgres_logins.py +1 -1
  64. fadenstack-0.5.0/tests/test_provenance_keys.py +727 -0
  65. fadenstack-0.5.0/tests/test_provenance_module.py +173 -0
  66. fadenstack-0.5.0/tests/test_provenance_on_by_default.py +229 -0
  67. fadenstack-0.5.0/tests/test_release_notice.py +51 -0
  68. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_required_env.py +5 -1
  69. fadenstack-0.5.0/tests/test_secret_files.py +142 -0
  70. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_service_logins.py +13 -10
  71. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_tune.py +3 -3
  72. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_tune_memory.py +6 -6
  73. fadenstack-0.4.5/src/faden_cli/commands/module.py +0 -114
  74. fadenstack-0.4.5/tests/test_generated_env_reaches_compose.py +0 -58
  75. {fadenstack-0.4.5 → fadenstack-0.5.0}/.gitignore +0 -0
  76. {fadenstack-0.4.5 → fadenstack-0.5.0}/LICENSE +0 -0
  77. {fadenstack-0.4.5 → fadenstack-0.5.0}/NOTICE +0 -0
  78. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/__main__.py +0 -0
  79. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/bundle/shared/.gitignore +0 -0
  80. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/bundle/shared/LICENSE +0 -0
  81. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/bundle/shared/NOTICE +0 -0
  82. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/bundle/shared/README.md +0 -0
  83. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/bundle/shared/agent-binaries/.gitignore +0 -0
  84. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/bundle/shared/alloy/config.alloy +0 -0
  85. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/bundle/shared/clickhouse/config.d/system-logs.xml +0 -0
  86. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/bundle/shared/docker-compose.gpu.yaml +0 -0
  87. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/bundle/shared/grafana/dashboards/templates/vllm-runtime.json +0 -0
  88. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/bundle/shared/grafana/provisioning/dashboards/dashboard.yml +0 -0
  89. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/bundle/shared/grafana/provisioning/dashboards/json/faden-overview.json +0 -0
  90. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/bundle/shared/grafana/provisioning/datasources/ds.yaml +0 -0
  91. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/bundle/shared/grafana/provisioning/datasources/prometheus.yaml +0 -0
  92. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/bundle/shared/loki/local-config.yaml +0 -0
  93. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/bundle/shared/nginx/maintenance.html +0 -0
  94. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/bundle/shared/nginx/nginx-tls.conf +0 -0
  95. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/bundle/shared/nginx/nginx.conf +0 -0
  96. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/bundle/shared/nginx/security-headers.conf +0 -0
  97. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/bundle/shared/nginx/select-config.sh +0 -0
  98. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/bundle/shared/prometheus/prometheus.yml +0 -0
  99. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/bundle/shared/rabbitmq/definitions.json.example +0 -0
  100. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/bundle/shared/tls/README.md +0 -0
  101. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/__init__.py +0 -0
  102. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/config.py +0 -0
  103. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/dev/__init__.py +0 -0
  104. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/dev/dev_doctor.py +0 -0
  105. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/dev/dev_group.py +0 -0
  106. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/dev/dev_init.py +0 -0
  107. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/dev/dev_pull.py +0 -0
  108. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/dev/dev_status.py +0 -0
  109. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/down.py +0 -0
  110. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/logs_cmd.py +0 -0
  111. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/maintenance.py +0 -0
  112. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/observe.py +0 -0
  113. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/ports.py +0 -0
  114. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/runtime_images.py +0 -0
  115. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/status.py +0 -0
  116. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/tls.py +0 -0
  117. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/tune.py +0 -0
  118. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/commands/version.py +0 -0
  119. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/__init__.py +0 -0
  120. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/api_client.py +0 -0
  121. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/bootstrap.py +0 -0
  122. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/bundle.py +0 -0
  123. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/clickhouse.py +0 -0
  124. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/console.py +0 -0
  125. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/docker_env.py +0 -0
  126. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/edge.py +0 -0
  127. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/git.py +0 -0
  128. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/install.py +0 -0
  129. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/installation.py +0 -0
  130. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/local_node.py +0 -0
  131. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/maintenance.py +0 -0
  132. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/private_files.py +0 -0
  133. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/release_feed.py +0 -0
  134. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/rmq.py +0 -0
  135. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/runtime_images.py +0 -0
  136. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/schedule.py +0 -0
  137. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/tls.py +0 -0
  138. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/update_check.py +0 -0
  139. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/core/workspace.py +0 -0
  140. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/templates/env.j2 +0 -0
  141. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/tui/__init__.py +0 -0
  142. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/tui/widgets/__init__.py +0 -0
  143. {fadenstack-0.4.5 → fadenstack-0.5.0}/src/faden_cli/tui/wizard/__init__.py +0 -0
  144. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_backup_retention.py +0 -0
  145. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_backup_tls.py +0 -0
  146. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_backup_volumes.py +0 -0
  147. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_binary_notices.py +0 -0
  148. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_bootstrap_token.py +0 -0
  149. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_cli_output_encoding.py +0 -0
  150. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_data_dir_move.py +0 -0
  151. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_data_volumes_logs.py +0 -0
  152. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_deploy_summary.py +0 -0
  153. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_dev_env_loopback.py +0 -0
  154. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_dev_up_port_holders.py +0 -0
  155. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_dev_up_reclaim.py +0 -0
  156. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_dev_up_service_hosts.py +0 -0
  157. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_dev_up_terminal.py +0 -0
  158. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_docker_env.py +0 -0
  159. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_doctor_ports.py +0 -0
  160. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_edge.py +0 -0
  161. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_installation.py +0 -0
  162. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_internal_token_env.py +0 -0
  163. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_local_node.py +0 -0
  164. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_main.py +0 -0
  165. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_maintenance.py +0 -0
  166. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_module_env.py +0 -0
  167. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_private_files.py +0 -0
  168. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_rebuild.py +0 -0
  169. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_redis_limits.py +0 -0
  170. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_registry_gateway_env.py +0 -0
  171. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_release_bundle.py +0 -0
  172. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_release_feed.py +0 -0
  173. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_release_versions.py +0 -0
  174. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_restore_maintenance.py +0 -0
  175. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_runtime_images.py +0 -0
  176. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_secret_rotation.py +0 -0
  177. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_shared_compose_ports.py +0 -0
  178. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_tls.py +0 -0
  179. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_tls_renew.py +0 -0
  180. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_trusted_keys.py +0 -0
  181. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_update_check.py +0 -0
  182. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_update_feed.py +0 -0
  183. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_upgrade_housekeeping.py +0 -0
  184. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_upgrade_rabbitmq.py +0 -0
  185. {fadenstack-0.4.5 → fadenstack-0.5.0}/tests/test_workspace_detection.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: fadenstack
3
- Version: 0.4.5
3
+ Version: 0.5.0
4
4
  Summary: CLI installer and management tool for the Fadenstack platform
5
5
  Project-URL: Homepage, https://fadenstack.com
6
6
  Project-URL: Repository, https://github.com/fadenstack/fadenstack
@@ -21,6 +21,7 @@ Classifier: Programming Language :: Python :: 3.13
21
21
  Classifier: Topic :: System :: Installation/Setup
22
22
  Classifier: Topic :: System :: Systems Administration
23
23
  Requires-Python: <4.0,>=3.12
24
+ Requires-Dist: certifi>=2026.10.19
24
25
  Requires-Dist: click<9,>=8.1
25
26
  Requires-Dist: cryptography>=43
26
27
  Requires-Dist: httpx<1,>=0.27
@@ -65,7 +66,7 @@ upgrade the CLI and run `faden upgrade`. See
65
66
  - **Auto-tuning** — detects host CPU / RAM and computes optimal worker counts,
66
67
  DB pool sizes, and queue channel pools.
67
68
  - **Module management** — enable / disable optional services
68
- (PII redaction, MCP tools, skills) via Docker Compose profiles.
69
+ (PII redaction, MCP tools, skills, provenance) via Docker Compose profiles.
69
70
  - **GPU detection** — `faden doctor` lists the host's GPUs; `faden deploy`
70
71
  adds the NVIDIA GPU overlay when the host has an NVIDIA runtime.
71
72
  - **Developer workflow** — clone all repos, install deps, run infra + migrations,
@@ -165,6 +166,12 @@ faden module enable pii skills # enable modules
165
166
  faden module disable mcp # disable a module
166
167
  ```
167
168
 
169
+ Provenance marks AI-generated content (EU AI Act Art. 50(2)) and is on by
170
+ default: `faden deploy` and `faden upgrade` switch it on. `faden module disable
171
+ provenance` warns that generated content will no longer be marked, asks first
172
+ (`--yes` for scripts), and records in faden.yaml who switched it off and when;
173
+ upgrades then leave it off until `faden module enable provenance`.
174
+
168
175
  ### Configuration
169
176
 
170
177
  ```bash
@@ -201,7 +208,7 @@ faden dev init ~/projects/fadenstack --overwrite # re-clone existing repos
201
208
  faden dev up # on this machine only (127.0.0.1)
202
209
  faden dev up --lan # on every interface, for one run
203
210
  faden dev up --backend-only
204
- faden dev up --modules pii,mcp,skills # also run the optional modules
211
+ faden dev up --modules pii,mcp,skills,provenance # also run the optional modules
205
212
  faden dev up --local-node
206
213
  faden dev up --local-node --local-node-host ubuntu@10.0.0.12
207
214
  faden dev down
@@ -212,8 +219,11 @@ faden dev doctor
212
219
  faden dev doctor --install --yes
213
220
  ```
214
221
 
215
- `--modules` runs PII (8003), MCP (8007) and skills (8008) on the host beside
216
- the backend, and points the gateway and backend at them. Without it, the
222
+ `--modules` runs PII (8003), MCP (8007), skills (8008) and provenance (8009)
223
+ on the host beside the backend, and points the gateway and backend at them.
224
+ Provenance has a repository of its own: it runs from a checkout beside the
225
+ core one (`../fadenstack-provenance`), and without that checkout `dev up`
226
+ says so and starts the rest. Without `--modules`, the
217
227
  modules switched on with `faden module enable` run; the others are switched
218
228
  off in the gateway and backend. See
219
229
  [What happens to a request](../docs/help/pages/administer/requests.md).
@@ -30,7 +30,7 @@ upgrade the CLI and run `faden upgrade`. See
30
30
  - **Auto-tuning** — detects host CPU / RAM and computes optimal worker counts,
31
31
  DB pool sizes, and queue channel pools.
32
32
  - **Module management** — enable / disable optional services
33
- (PII redaction, MCP tools, skills) via Docker Compose profiles.
33
+ (PII redaction, MCP tools, skills, provenance) via Docker Compose profiles.
34
34
  - **GPU detection** — `faden doctor` lists the host's GPUs; `faden deploy`
35
35
  adds the NVIDIA GPU overlay when the host has an NVIDIA runtime.
36
36
  - **Developer workflow** — clone all repos, install deps, run infra + migrations,
@@ -130,6 +130,12 @@ faden module enable pii skills # enable modules
130
130
  faden module disable mcp # disable a module
131
131
  ```
132
132
 
133
+ Provenance marks AI-generated content (EU AI Act Art. 50(2)) and is on by
134
+ default: `faden deploy` and `faden upgrade` switch it on. `faden module disable
135
+ provenance` warns that generated content will no longer be marked, asks first
136
+ (`--yes` for scripts), and records in faden.yaml who switched it off and when;
137
+ upgrades then leave it off until `faden module enable provenance`.
138
+
133
139
  ### Configuration
134
140
 
135
141
  ```bash
@@ -166,7 +172,7 @@ faden dev init ~/projects/fadenstack --overwrite # re-clone existing repos
166
172
  faden dev up # on this machine only (127.0.0.1)
167
173
  faden dev up --lan # on every interface, for one run
168
174
  faden dev up --backend-only
169
- faden dev up --modules pii,mcp,skills # also run the optional modules
175
+ faden dev up --modules pii,mcp,skills,provenance # also run the optional modules
170
176
  faden dev up --local-node
171
177
  faden dev up --local-node --local-node-host ubuntu@10.0.0.12
172
178
  faden dev down
@@ -177,8 +183,11 @@ faden dev doctor
177
183
  faden dev doctor --install --yes
178
184
  ```
179
185
 
180
- `--modules` runs PII (8003), MCP (8007) and skills (8008) on the host beside
181
- the backend, and points the gateway and backend at them. Without it, the
186
+ `--modules` runs PII (8003), MCP (8007), skills (8008) and provenance (8009)
187
+ on the host beside the backend, and points the gateway and backend at them.
188
+ Provenance has a repository of its own: it runs from a checkout beside the
189
+ core one (`../fadenstack-provenance`), and without that checkout `dev up`
190
+ says so and starts the rest. Without `--modules`, the
182
191
  modules switched on with `faden module enable` run; the others are switched
183
192
  off in the gateway and backend. See
184
193
  [What happens to a request](../docs/help/pages/administer/requests.md).
@@ -22,7 +22,7 @@ except ImportError: # the tests load this file for bundle_files() alone
22
22
 
23
23
  #: What an install writes or generates for itself, and what is only for
24
24
  #: building from source. None of it belongs in a release.
25
- _SKIP_DIRS = {"backups", "base", ".empty-hf-cache", "__pycache__"}
25
+ _SKIP_DIRS = {"backups", "base", ".empty-hf-cache", "__pycache__", "secrets"}
26
26
  _SKIP_FILES = {
27
27
  ".env",
28
28
  ".bootstrap-credentials",
@@ -77,7 +77,15 @@ class CustomBuildHook(BuildHookInterface):
77
77
  """Add the shared deployment files to the wheel or sdist being built."""
78
78
 
79
79
  def initialize(self, version: str, build_data: dict) -> None: # noqa: ARG002
80
+ catalog = Path(self.root).parent / "pii/faden_pii/pii-catalog.json"
80
81
  shared = Path(self.root).parent / "shared"
82
+ if catalog.is_file():
83
+ prefix = "src/faden_cli" if self.target_name == "sdist" else "faden_cli"
84
+ build_data["force_include"][str(catalog)] = f"{prefix}/bundle/pii-catalog.json"
85
+ elif shared.is_dir():
86
+ # From a checkout that lacks pii/: the CLI would not start (deploy reads the catalog on import).
87
+ msg = f"The PII catalog {catalog} is missing; the CLI cannot be built without it."
88
+ raise FileNotFoundError(msg)
81
89
  if not shared.is_dir():
82
90
  # Building from an sdist: the files are already in the package.
83
91
  return
@@ -10,7 +10,7 @@ packages = ["src/faden_cli"]
10
10
 
11
11
  [project]
12
12
  name = "fadenstack"
13
- version = "0.4.5"
13
+ version = "0.5.0"
14
14
  requires-python = ">=3.12,<4.0"
15
15
  description = "CLI installer and management tool for the Fadenstack platform"
16
16
  authors = [
@@ -46,6 +46,7 @@ dependencies = [
46
46
  "cryptography >=43",
47
47
  # Release versions in the update check and upgrade (0.5.0rc1 < 0.5.0).
48
48
  "packaging >=23",
49
+ "certifi>=2026.10.19", # >=2026.10.19: GHSA-6q48-6c7w-9gw2 (emSign roots with compromised intermediate keys)
49
50
  ]
50
51
 
51
52
  [project.urls]
@@ -13,4 +13,4 @@ Module activation via Docker Compose profiles.
13
13
  All secrets generated securely during init phase.
14
14
  """
15
15
 
16
- __version__ = "0.4.5"
16
+ __version__ = "0.5.0"
@@ -0,0 +1,44 @@
1
+ {
2
+ "version": "local-pii-1",
3
+ "rules_version": "presidio-local-v2",
4
+ "default_locale": "europe-west-v1",
5
+ "locales": {
6
+ "europe-west-v1": {"name": "Western European multilingual (EN/DE/FR/ES)", "languages": ["en", "de", "fr", "es"], "scripts": ["Latin"], "recommended_model": "patronus-onnx-v1"},
7
+ "english-v1": {"name": "English", "languages": ["en"], "scripts": ["Latin"], "recommended_model": "patronus-onnx-v1"},
8
+ "german-v1": {"name": "German", "languages": ["de"], "scripts": ["Latin"], "recommended_model": "patronus-onnx-v1"},
9
+ "french-v1": {"name": "French", "languages": ["fr"], "scripts": ["Latin"], "recommended_model": "patronus-onnx-v1"},
10
+ "spanish-v1": {"name": "Spanish", "languages": ["es"], "scripts": ["Latin"], "recommended_model": "patronus-onnx-v1"}
11
+ },
12
+ "models": {
13
+ "patronus-onnx-v1": {
14
+ "name": "Patronus small FP16 ONNX",
15
+ "adapter": "gliner-onnx", "adapter_version": 1,
16
+ "repository": "patronus-studio/gliner_small-v2.5-edge",
17
+ "revision": "6cfcbd93d7fc6f5e1658f80afa38f73891b91693",
18
+ "license": "Apache-2.0; backbone MIT",
19
+ "languages": ["en", "de", "fr", "es"], "scripts": ["Latin"],
20
+ "execution": ["cpu"], "precision": "float16", "build_target": "prod-cpu",
21
+ "patterns": ["*.json", "*.model", "onnx/fp16/*", "LICENSE*", "tokenizer*"],
22
+ "required_files": ["gliner_config.json", "onnx/fp16/model_fp16.onnx"],
23
+ "labels": {"person": "PERSON", "first_name": "PERSON", "last_name": "PERSON", "full_name": "PERSON", "address": "LOCATION", "city": "LOCATION"},
24
+ "offsets": "python-codepoints", "max_window_tokens": 256,
25
+ "max_batch_short": 8, "max_batch_long": 2,
26
+ "qualification": "EN/DE/FR/ES service evaluation; detection remains incomplete"
27
+ },
28
+ "gliner2-multi-v1": {
29
+ "name": "GLiNER2 multilingual PII",
30
+ "adapter": "gliner2", "adapter_version": 1,
31
+ "repository": "fastino/gliner2-privacy-filter-PII-multi",
32
+ "revision": "1cb4166094dc58fa8d836429f060d6c95f62b495",
33
+ "license": "Apache-2.0",
34
+ "languages": ["en", "de", "fr", "es"], "scripts": ["Latin"],
35
+ "execution": ["cpu", "gpu-shared", "gpu-dedicated"], "precision": "float32", "build_target": "prod-gpu",
36
+ "patterns": ["*.json", "*.safetensors", "*.model", "*.txt", "encoder_config/*", "LICENSE*"],
37
+ "required_files": ["config.json", "model.safetensors"],
38
+ "labels": {"person": "PERSON", "first_name": "PERSON", "last_name": "PERSON", "full_name": "PERSON", "address": "LOCATION", "city": "LOCATION"},
39
+ "offsets": "python-codepoints", "max_window_tokens": 256,
40
+ "max_batch_short": 32, "max_batch_long": 8,
41
+ "qualification": "EN/DE/FR/ES service evaluation; CPU operation is slow; detection remains incomplete"
42
+ }
43
+ }
44
+ }
@@ -0,0 +1,10 @@
1
+ # Included only when an installed PII execution profile selects CUDA.
2
+ services:
3
+ faden-pii:
4
+ deploy:
5
+ resources:
6
+ reservations:
7
+ devices:
8
+ - driver: nvidia
9
+ device_ids: ["${FADEN_PII_GPU_ID:-0}"]
10
+ capabilities: [gpu]
@@ -85,8 +85,8 @@ services:
85
85
  # segment"). pgvector's README asks for more.
86
86
  shm_size: 1g
87
87
  # Every worker of every service keeps its own pool, and they all share this
88
- # server: with PII, MCP and skills an install from this file alone can open
89
- # about 130 connections at its peak, past Postgres' default of 100 (see
88
+ # server: with PII, MCP, skills and provenance an install from this file
89
+ # alone can open about 145 connections at its peak, past Postgres' default of 100 (see
90
90
  # docs/help/pages/operate/requirements.md, The server). A connection is a
91
91
  # process of about 6 MB, so 250 at once is about 1.5 GB.
92
92
  command: ["postgres", "-c", "max_connections=${POSTGRES_MAX_CONNECTIONS:-250}"]
@@ -356,15 +356,20 @@ services:
356
356
  depends_on:
357
357
  postgres:
358
358
  condition: service_healthy
359
+ # The keys that open content, as files under /run/secrets (secrets: at the end), not environment.
360
+ secrets:
361
+ - source: settings_master_key
362
+ target: FADEN_GATEWAY_SETTINGS_MASTER_KEY
363
+ - source: gateway_encryption_key
364
+ target: FADEN_GATEWAY_ENCRYPTION_KEY
365
+ - source: gateway_encryption_key_previous
366
+ target: FADEN_GATEWAY_ENCRYPTION_KEY_PREVIOUS
359
367
  environment:
360
368
  FADEN_GATEWAY_DB_HOST: postgres
361
369
  FADEN_GATEWAY_DB_PORT: 5432
362
370
  FADEN_GATEWAY_DB_USER: ${POSTGRES_USER:-postgres}
363
371
  FADEN_GATEWAY_DB_PASS: ${POSTGRES_PASSWORD:?set it in .env; an install that ran without it keeps its data only with the old default value (Help, Installing, Secrets in .env)}
364
372
  FADEN_GATEWAY_DB_BASE: faden_gateway
365
- # The migration that seals the provider API keys (pr0vk3yg) uses the backend's master key; without it
366
- # the migrator used the published development default.
367
- FADEN_GATEWAY_SETTINGS_MASTER_KEY: ${FADEN_BACKEND_SETTINGS_MASTER_KEY:?set it in .env; an install that ran without it keeps its data only with the old default value (Help, Installing, Secrets in .env)}
368
373
  # That migration refuses the published development key unless the install keeps it on purpose.
369
374
  FADEN_GATEWAY_ALLOW_PUBLISHED_KEYS: ${FADEN_ALLOW_PUBLISHED_KEYS:-false}
370
375
 
@@ -393,6 +398,16 @@ services:
393
398
  condition: service_completed_successfully
394
399
  ports:
395
400
  - "127.0.0.1:8001:8000"
401
+ # The keys that open content, as files under /run/secrets (secrets: at the end), not environment.
402
+ secrets:
403
+ - source: settings_master_key
404
+ target: FADEN_GATEWAY_SETTINGS_MASTER_KEY
405
+ - source: settings_master_key_previous
406
+ target: FADEN_GATEWAY_SETTINGS_MASTER_KEY_PREVIOUS
407
+ - source: gateway_encryption_key_previous
408
+ target: FADEN_GATEWAY_ENCRYPTION_KEY_PREVIOUS
409
+ - source: gateway_encryption_key
410
+ target: FADEN_GATEWAY_ENCRYPTION_KEY
396
411
  environment:
397
412
  FADEN_GATEWAY_HOST: 0.0.0.0
398
413
  FADEN_GATEWAY_PORT: 8000
@@ -406,21 +421,12 @@ services:
406
421
  # JWT secret is read from backend DB at startup (faden_gateway.jwt_secret system setting).
407
422
  # These two env vars enable that path; no static JWT_SECRET env var is needed.
408
423
  FADEN_GATEWAY_BACKEND_DB_BASE: faden_backend
409
- FADEN_GATEWAY_SETTINGS_MASTER_KEY: ${FADEN_BACKEND_SETTINGS_MASTER_KEY:?set it in .env; an install that ran without it keeps its data only with the old default value (Help, Installing, Secrets in .env)}
410
- # Set only while `faden secrets rotate` is unfinished: values sealed with the old key still open.
411
- FADEN_GATEWAY_SETTINGS_MASTER_KEY_PREVIOUS: ${FADEN_BACKEND_SETTINGS_MASTER_KEY_PREVIOUS:-}
412
- FADEN_GATEWAY_ENCRYPTION_KEY_PREVIOUS: ${FADEN_GATEWAY_ENCRYPTION_KEY_PREVIOUS:-}
413
424
  # An install that has stored data under the published development key may
414
425
  # keep it, with a warning at every start, until it is changed (Help:
415
426
  # Installing, Secrets in .env). Outside development the service refuses it otherwise.
416
427
  FADEN_GATEWAY_ALLOW_PUBLISHED_KEYS: ${FADEN_ALLOW_PUBLISHED_KEYS:-false}
417
- # The key chats are encrypted with at rest: messages, titles, memory, a
418
- # reply's events in Redis. `faden deploy` writes one into .env; it never
419
- # reached the gateway, and every install stored its chats in plain text
420
- # (2026-10-02). Empty still stores plain text. Rows from before stay
421
- # readable. Without this key the encrypted chats cannot be read: .env
422
- # belongs in every backup (`faden backup` takes it; --db-only does not).
423
- FADEN_GATEWAY_ENCRYPTION_KEY: ${FADEN_GATEWAY_ENCRYPTION_KEY:-}
428
+ # Days a chat someone deleted is kept before it is erased (faden deploy asks; Settings > Chat wins).
429
+ FADEN_GATEWAY_CHAT_DELETED_RETENTION_DAYS: ${FADEN_GATEWAY_CHAT_DELETED_RETENTION_DAYS:-30}
424
430
  FADEN_GATEWAY_JWT_ALGORITHM: HS256
425
431
  FADEN_GATEWAY_DB_HOST: postgres
426
432
  FADEN_GATEWAY_DB_PORT: 5432
@@ -452,6 +458,10 @@ services:
452
458
  FADEN_GATEWAY_SKILLS_ENABLED: ${FADEN_GATEWAY_SKILLS_ENABLED:-false}
453
459
  FADEN_GATEWAY_SKILLS_SERVICE_URL: ${FADEN_GATEWAY_SKILLS_SERVICE_URL:-http://faden-skills:8000}
454
460
  FADEN_GATEWAY_SKILLS_SERVICE_TOKEN: ${FADEN_GATEWAY_SKILLS_SERVICE_TOKEN:?set it in .env, as faden deploy and faden upgrade do (Help, Installing, Secrets in .env)}
461
+ # Provenance: marks AI-generated content (set via .env or COMPOSE_PROFILES)
462
+ FADEN_GATEWAY_PROVENANCE_ENABLED: ${FADEN_GATEWAY_PROVENANCE_ENABLED:-false}
463
+ FADEN_GATEWAY_PROVENANCE_SERVICE_URL: ${FADEN_GATEWAY_PROVENANCE_SERVICE_URL:-http://faden-provenance:8000}
464
+ FADEN_GATEWAY_PROVENANCE_SERVICE_TOKEN: ${FADEN_GATEWAY_PROVENANCE_SERVICE_TOKEN:?set it in .env, as faden deploy and faden upgrade do (Help, Installing, Secrets in .env)}
455
465
  # Knowledge search runs in the backend. The default, 127.0.0.1:8000, is this container's own port:
456
466
  # every search reached the gateway itself and failed with 404.
457
467
  FADEN_GATEWAY_RAG_LITE_BACKEND_URL: ${FADEN_GATEWAY_RAG_LITE_BACKEND_URL:-http://faden-backend:8000}
@@ -495,15 +505,16 @@ services:
495
505
  depends_on:
496
506
  postgres:
497
507
  condition: service_healthy
508
+ # The keys that open content, as files under /run/secrets (secrets: at the end), not environment.
509
+ secrets:
510
+ - source: settings_master_key
511
+ target: FADEN_BACKEND_SETTINGS_MASTER_KEY
498
512
  environment:
499
513
  FADEN_BACKEND_DB_HOST: postgres
500
514
  FADEN_BACKEND_DB_PORT: 5432
501
515
  FADEN_BACKEND_DB_USER: ${POSTGRES_USER:-postgres}
502
516
  FADEN_BACKEND_DB_PASS: ${POSTGRES_PASSWORD:?set it in .env; an install that ran without it keeps its data only with the old default value (Help, Installing, Secrets in .env)}
503
517
  FADEN_BACKEND_DB_BASE: faden_backend
504
- # The migration that seals the remote providers' API keys (pr0vk3ys) seals them with this key.
505
- # Without it the migrator used the published development default, and the backend could not open them.
506
- FADEN_BACKEND_SETTINGS_MASTER_KEY: ${FADEN_BACKEND_SETTINGS_MASTER_KEY:?set it in .env; an install that ran without it keeps its data only with the old default value (Help, Installing, Secrets in .env)}
507
518
  # That migration refuses the published development key unless the install keeps it on purpose.
508
519
  FADEN_BACKEND_ALLOW_PUBLISHED_KEYS: ${FADEN_ALLOW_PUBLISHED_KEYS:-false}
509
520
 
@@ -531,6 +542,17 @@ services:
531
542
  faden-backend-migrator:
532
543
  condition: service_completed_successfully
533
544
  # No host port — accessed via nginx reverse proxy
545
+ # The keys that open content, as files under /run/secrets (secrets: at the end), not environment.
546
+ secrets:
547
+ - source: settings_master_key
548
+ target: FADEN_BACKEND_SETTINGS_MASTER_KEY
549
+ - source: settings_master_key_previous
550
+ target: FADEN_BACKEND_SETTINGS_MASTER_KEY_PREVIOUS
551
+ - source: credential_pepper
552
+ target: FADEN_BACKEND_CREDENTIAL_PEPPER
553
+ # The text watermark keys: the current one goes to the models it starts (core/provenance_keys.py).
554
+ - source: provenance_watermark_keys
555
+ target: FADEN_BACKEND_PROVENANCE_WATERMARK_KEYS
534
556
  environment:
535
557
  FADEN_BACKEND_HOST: 0.0.0.0
536
558
  FADEN_BACKEND_PORT: 8000
@@ -556,12 +578,6 @@ services:
556
578
  FADEN_BACKEND_RABBIT_PASS: ${RABBITMQ_BACKEND_PASS:?set it in .env, as faden deploy and faden upgrade do (Help, Installing, Secrets in .env)}
557
579
  FADEN_BACKEND_RABBIT_VHOST: /
558
580
  FADEN_BACKEND_GATEWAY_URL: ${FADEN_BACKEND_GATEWAY_URL:-http://faden-gateway:8000}
559
- FADEN_BACKEND_SETTINGS_MASTER_KEY: ${FADEN_BACKEND_SETTINGS_MASTER_KEY:?set it in .env; an install that ran without it keeps its data only with the old default value (Help, Installing, Secrets in .env)}
560
- # Set only while `faden secrets rotate` is unfinished: values sealed with the old key still open.
561
- FADEN_BACKEND_SETTINGS_MASTER_KEY_PREVIOUS: ${FADEN_BACKEND_SETTINGS_MASTER_KEY_PREVIOUS:-}
562
- # What the machines' credential hashes are keyed with. Once the master key itself; a rotation
563
- # changes the master key and must not change this, or every machine would have to enroll again.
564
- FADEN_BACKEND_CREDENTIAL_PEPPER: ${FADEN_BACKEND_CREDENTIAL_PEPPER:?set it in .env, as faden upgrade does (it keeps the machines' credentials valid; Help, Rotating the keys)}
565
581
  # An install that has stored data under the published development key may
566
582
  # keep it, with a warning at every start, until it is changed (Help:
567
583
  # Installing, Secrets in .env). Outside development the service refuses it otherwise.
@@ -597,6 +613,9 @@ services:
597
613
  FADEN_BACKEND_DOCLING_SERVICE_URL: ${FADEN_BACKEND_DOCLING_SERVICE_URL:-http://faden-docling:8000}
598
614
  FADEN_BACKEND_SKILLS_SERVICE_URL: ${FADEN_BACKEND_SKILLS_SERVICE_URL:-http://faden-skills:8000}
599
615
  FADEN_BACKEND_SKILLS_SERVICE_TOKEN: ${FADEN_BACKEND_SKILLS_SERVICE_TOKEN:?set it in .env, as faden deploy and faden upgrade do (Help, Installing, Secrets in .env)}
616
+ FADEN_BACKEND_PROVENANCE_ENABLED: ${FADEN_BACKEND_PROVENANCE_ENABLED:-false}
617
+ FADEN_BACKEND_PROVENANCE_SERVICE_URL: ${FADEN_BACKEND_PROVENANCE_SERVICE_URL:-http://faden-provenance:8000}
618
+ FADEN_BACKEND_PROVENANCE_SERVICE_TOKEN: ${FADEN_BACKEND_PROVENANCE_SERVICE_TOKEN:?set it in .env, as faden deploy and faden upgrade do (Help, Installing, Secrets in .env)}
600
619
  # Scalability tuning (set via faden tune)
601
620
  FADEN_BACKEND_WORKERS_COUNT: ${FADEN_BACKEND_WORKERS_COUNT:-4}
602
621
  FADEN_BACKEND_DB_POOL_SIZE: ${FADEN_BACKEND_DB_POOL_SIZE:-5}
@@ -624,6 +643,9 @@ services:
624
643
  # directory plus /knowledge on the host; empty, the named volume. The CLI copies the volume's files
625
644
  # into the folder before the container is created.
626
645
  - ${FADEN_DATA_DIR:-faden_rag_lite}${FADEN_DATA_DIR:+/knowledge}:/data/faden/rag-lite
646
+ # The audit trail's file copy (services/audit/chain.py): one line per event, never deleted, in every
647
+ # backup. Someone who edits the audit table cannot edit this from the database.
648
+ - faden_audit:/data/faden/audit
627
649
  # Runtime monitoring — shared with the prometheus + grafana
628
650
  # services (see their mounts). The backend generates
629
651
  # prometheus/targets.json and dashboards/*.json here; grafana
@@ -666,6 +688,17 @@ services:
666
688
  condition: service_healthy
667
689
  faden-backend-migrator:
668
690
  condition: service_completed_successfully
691
+ # The keys that open content, as files under /run/secrets (secrets: at the end), not environment.
692
+ secrets:
693
+ - source: settings_master_key
694
+ target: FADEN_BACKEND_SETTINGS_MASTER_KEY
695
+ - source: settings_master_key_previous
696
+ target: FADEN_BACKEND_SETTINGS_MASTER_KEY_PREVIOUS
697
+ - source: credential_pepper
698
+ target: FADEN_BACKEND_CREDENTIAL_PEPPER
699
+ # The text watermark keys: the current one goes to the models it starts (core/provenance_keys.py).
700
+ - source: provenance_watermark_keys
701
+ target: FADEN_BACKEND_PROVENANCE_WATERMARK_KEYS
669
702
  environment:
670
703
  FADEN_BACKEND_ENVIRONMENT: ${FADEN_BACKEND_ENVIRONMENT:-production}
671
704
  FADEN_BACKEND_DB_HOST: postgres
@@ -682,12 +715,6 @@ services:
682
715
  FADEN_BACKEND_RABBIT_PASS: ${RABBITMQ_BACKEND_PASS:?set it in .env, as faden deploy and faden upgrade do (Help, Installing, Secrets in .env)}
683
716
  FADEN_BACKEND_RABBIT_VHOST: /
684
717
  FADEN_BACKEND_GATEWAY_URL: ${FADEN_BACKEND_GATEWAY_URL:-http://faden-gateway:8000}
685
- FADEN_BACKEND_SETTINGS_MASTER_KEY: ${FADEN_BACKEND_SETTINGS_MASTER_KEY:?set it in .env; an install that ran without it keeps its data only with the old default value (Help, Installing, Secrets in .env)}
686
- # Set only while `faden secrets rotate` is unfinished: values sealed with the old key still open.
687
- FADEN_BACKEND_SETTINGS_MASTER_KEY_PREVIOUS: ${FADEN_BACKEND_SETTINGS_MASTER_KEY_PREVIOUS:-}
688
- # What the machines' credential hashes are keyed with. Once the master key itself; a rotation
689
- # changes the master key and must not change this, or every machine would have to enroll again.
690
- FADEN_BACKEND_CREDENTIAL_PEPPER: ${FADEN_BACKEND_CREDENTIAL_PEPPER:?set it in .env, as faden upgrade does (it keeps the machines' credentials valid; Help, Rotating the keys)}
691
718
  FADEN_BACKEND_LLM_GRAPH_DB_HOST: postgres
692
719
  FADEN_BACKEND_LLM_GRAPH_DB_USER: ${POSTGRES_USER:-postgres}
693
720
  FADEN_BACKEND_LLM_GRAPH_DB_PASS: ${POSTGRES_PASSWORD:?set it in .env; an install that ran without it keeps its data only with the old default value (Help, Installing, Secrets in .env)}
@@ -707,6 +734,9 @@ services:
707
734
  FADEN_BACKEND_DOCLING_SERVICE_URL: ${FADEN_BACKEND_DOCLING_SERVICE_URL:-http://faden-docling:8000}
708
735
  FADEN_BACKEND_SKILLS_SERVICE_URL: ${FADEN_BACKEND_SKILLS_SERVICE_URL:-http://faden-skills:8000}
709
736
  FADEN_BACKEND_SKILLS_SERVICE_TOKEN: ${FADEN_BACKEND_SKILLS_SERVICE_TOKEN:?set it in .env, as faden deploy and faden upgrade do (Help, Installing, Secrets in .env)}
737
+ FADEN_BACKEND_PROVENANCE_ENABLED: ${FADEN_BACKEND_PROVENANCE_ENABLED:-false}
738
+ FADEN_BACKEND_PROVENANCE_SERVICE_URL: ${FADEN_BACKEND_PROVENANCE_SERVICE_URL:-http://faden-provenance:8000}
739
+ FADEN_BACKEND_PROVENANCE_SERVICE_TOKEN: ${FADEN_BACKEND_PROVENANCE_SERVICE_TOKEN:?set it in .env, as faden deploy and faden upgrade do (Help, Installing, Secrets in .env)}
710
740
  # Scalability tuning (set via faden tune)
711
741
  FADEN_BACKEND_DB_POOL_SIZE: ${FADEN_BACKEND_DB_POOL_SIZE:-5}
712
742
  FADEN_BACKEND_DB_MAX_OVERFLOW: ${FADEN_BACKEND_DB_MAX_OVERFLOW:-5}
@@ -721,6 +751,7 @@ services:
721
751
  - /var/run/docker.sock:/var/run/docker.sock:ro
722
752
  - faden_models:/srv/faden/models
723
753
  - ${FADEN_DATA_DIR:-faden_rag_lite}${FADEN_DATA_DIR:+/knowledge}:/data/faden/rag-lite
754
+ - faden_audit:/data/faden/audit
724
755
 
725
756
  # -----------------------------
726
757
  # frontend (React admin console)
@@ -752,11 +783,12 @@ services:
752
783
  # =====================================================================
753
784
  faden-pii:
754
785
  profiles: ["pii"]
755
- image: ${REGISTRY:-ghcr.io/fadenstack}/pii:${VERSION:-latest}
786
+ mem_limit: ${FADEN_PII_MEMORY_LIMIT:-4g}
787
+ image: ${FADEN_PII_IMAGE:-${REGISTRY:-ghcr.io/fadenstack}/pii:${VERSION:-latest}}
756
788
  build:
757
789
  context: ../pii
758
790
  dockerfile: Dockerfile
759
- target: prod
791
+ target: ${FADEN_PII_BUILD_TARGET:-prod}
760
792
  args:
761
793
  BASE_IMAGE: ${REGISTRY:-ghcr.io/fadenstack}/base:${VERSION:-latest}
762
794
  container_name: faden-pii
@@ -781,17 +813,53 @@ services:
781
813
  FADEN_PII_RABBIT_PASS: ${RABBITMQ_PII_PASS:?set it in .env, as faden deploy and faden upgrade do (Help, Installing, Secrets in .env)}
782
814
  FADEN_PII_RABBIT_VHOST: /
783
815
  # Scalability tuning (set via faden tune)
784
- FADEN_PII_WORKERS_COUNT: ${FADEN_PII_WORKERS_COUNT:-4}
816
+ FADEN_PII_WORKERS_COUNT: ${FADEN_PII_WORKERS_COUNT:-1}
785
817
  FADEN_PII_DB_POOL_SIZE: ${FADEN_PII_DB_POOL_SIZE:-5}
786
818
  FADEN_PII_DB_MAX_OVERFLOW: ${FADEN_PII_DB_MAX_OVERFLOW:-5}
819
+ FADEN_PII_BACKEND: ${FADEN_PII_BACKEND:-presidio}
820
+ FADEN_PII_MODEL_ID: ${FADEN_PII_MODEL_ID:-}
821
+ FADEN_PII_MODEL_REVISION: ${FADEN_PII_MODEL_REVISION:-}
822
+ FADEN_PII_LOCALE_PACK: ${FADEN_PII_LOCALE_PACK:-}
823
+ FADEN_PII_CATALOG_VERSION: ${FADEN_PII_CATALOG_VERSION:-}
824
+ FADEN_PII_RULES_VERSION: ${FADEN_PII_RULES_VERSION:-}
825
+ FADEN_PII_ENTITY_PROFILE: ${FADEN_PII_ENTITY_PROFILE:-standard}
826
+ FADEN_PII_EXECUTION_PROFILE: ${FADEN_PII_EXECUTION_PROFILE:-cpu}
827
+ FADEN_PII_DEVICE: ${FADEN_PII_DEVICE:-cuda:0}
828
+ FADEN_PII_PRECISION: ${FADEN_PII_PRECISION:-float32}
829
+ FADEN_PII_MODEL_PATH: ${FADEN_PII_MODEL_PATH:-/models}
830
+ FADEN_PII_MANIFEST_PATH: ${FADEN_PII_MANIFEST_PATH:-/models/manifest.json}
831
+ FADEN_PII_CALIBRATION_PATH: ${FADEN_PII_CALIBRATION_PATH:-}
832
+ FADEN_PII_CPU_THREADS: ${FADEN_PII_CPU_THREADS:-}
833
+ FADEN_PII_GPU_MEMORY_MIB: ${FADEN_PII_GPU_MEMORY_MIB:-4096}
834
+ FADEN_PII_DEFAULT_LANGUAGE: ${FADEN_PII_DEFAULT_LANGUAGE:-en}
835
+ FADEN_PII_SCORE_THRESHOLD: ${FADEN_PII_SCORE_THRESHOLD:-0.35}
836
+ FADEN_PII_PENDING_REQUESTS: ${FADEN_PII_PENDING_REQUESTS:-64}
837
+ FADEN_PII_PENDING_WINDOWS: ${FADEN_PII_PENDING_WINDOWS:-512}
838
+ FADEN_PII_PENDING_TOKENS: ${FADEN_PII_PENDING_TOKENS:-131072}
839
+ FADEN_PII_PENDING_BYTES: ${FADEN_PII_PENDING_BYTES:-33554432}
840
+ FADEN_PII_WINDOW_TOKENS: ${FADEN_PII_WINDOW_TOKENS:-256}
841
+ FADEN_PII_WINDOW_OVERLAP: ${FADEN_PII_WINDOW_OVERLAP:-24}
842
+ # Empty means the selected image/backend defaults (CPU 8/2, GPU 32/8).
843
+ FADEN_PII_BATCH_SHORT: ${FADEN_PII_BATCH_SHORT:-}
844
+ FADEN_PII_BATCH_LONG: ${FADEN_PII_BATCH_LONG:-}
845
+ FADEN_PII_WORK_TIMEOUT_SECONDS: ${FADEN_PII_WORK_TIMEOUT_SECONDS:-8}
846
+ FADEN_PII_MAX_RECOVERIES: ${FADEN_PII_MAX_RECOVERIES:-1}
847
+ FADEN_PII_RECOVERY_DELAY_SECONDS: ${FADEN_PII_RECOVERY_DELAY_SECONDS:-1}
848
+ FADEN_PII_CACHE_ENTRIES: ${FADEN_PII_CACHE_ENTRIES:-20000}
849
+ FADEN_PII_CACHE_BYTES: ${FADEN_PII_CACHE_BYTES:-134217728}
850
+ FADEN_PII_LOCK_DIR: /run/pii-locks
851
+ volumes:
852
+ - ${FADEN_PII_MODEL_DIR:-faden_pii_models}:/models:ro
853
+ - faden_pii_locks:/run/pii-locks
787
854
  healthcheck:
788
- test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/api/health', timeout=3).read()"]
855
+ test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/api/ready', timeout=3).read()"]
789
856
  interval: 5s
790
857
  timeout: 5s
791
858
  retries: 20
859
+ start_period: 120s
792
860
 
793
861
  faden-pii-worker:
794
- profiles: ["pii"]
862
+ profiles: ["pii-tasks"]
795
863
  image: ${REGISTRY:-ghcr.io/fadenstack}/pii:${VERSION:-latest}
796
864
  container_name: faden-pii-worker
797
865
  logging: *faden-logging
@@ -856,6 +924,12 @@ services:
856
924
  condition: service_healthy
857
925
  faden-mcp-migrator:
858
926
  condition: service_completed_successfully
927
+ # The keys that open content, as files under /run/secrets (secrets: at the end), not environment.
928
+ secrets:
929
+ - source: mcp_encryption_key
930
+ target: FADEN_MCP_ENCRYPTION_KEY
931
+ - source: mcp_encryption_key_previous
932
+ target: FADEN_MCP_ENCRYPTION_KEY_PREVIOUS
859
933
  environment:
860
934
  FADEN_MCP_HOST: 0.0.0.0
861
935
  FADEN_MCP_PORT: 8000
@@ -873,8 +947,6 @@ services:
873
947
  FADEN_MCP_PII_SERVICE_URL: ${FADEN_MCP_PII_SERVICE_URL:-http://faden-pii:8000}
874
948
  FADEN_MCP_PII_SERVICE_TOKEN: ${FADEN_MCP_PII_SERVICE_TOKEN:?set it in .env, as faden deploy and faden upgrade do (Help, Installing, Secrets in .env)}
875
949
  FADEN_MCP_SERVICE_TOKEN: ${FADEN_MCP_SERVICE_TOKEN:?set it in .env, as faden deploy and faden upgrade do (Help, Installing, Secrets in .env)}
876
- FADEN_MCP_ENCRYPTION_KEY: ${FADEN_MCP_ENCRYPTION_KEY:?set it in .env; an install that ran without it keeps its data only with the old default value (Help, Installing, Secrets in .env)}
877
- FADEN_MCP_ENCRYPTION_KEY_PREVIOUS: ${FADEN_MCP_ENCRYPTION_KEY_PREVIOUS:-}
878
950
  # An install that has stored data under the published development key may
879
951
  # keep it, with a warning at every start, until it is changed (Help:
880
952
  # Installing, Secrets in .env). Outside development the service refuses it otherwise.
@@ -952,6 +1024,73 @@ services:
952
1024
  timeout: 5s
953
1025
  retries: 20
954
1026
 
1027
+ # =====================================================================
1028
+ # Provenance (profile: provenance)
1029
+ #
1030
+ # Marks AI-generated content and checks marks (EU AI Act Art. 50(2)).
1031
+ # Published as an image only; switched on by default by faden deploy
1032
+ # and faden upgrade. The migrator makes the database faden_provenance
1033
+ # when an install created before the module has none.
1034
+ # =====================================================================
1035
+ faden-provenance-migrator:
1036
+ profiles: ["provenance"]
1037
+ image: ${REGISTRY:-ghcr.io/fadenstack}/provenance:${VERSION:-latest}
1038
+ container_name: faden-provenance-migrator
1039
+ logging: *faden-logging
1040
+ restart: on-failure:5
1041
+ command: ["sh", "-c", "sleep 5 && python -m faden_provenance.db.ensure && alembic upgrade head"]
1042
+ depends_on:
1043
+ postgres:
1044
+ condition: service_healthy
1045
+ environment:
1046
+ FADEN_PROVENANCE_DB_HOST: postgres
1047
+ FADEN_PROVENANCE_DB_PORT: 5432
1048
+ FADEN_PROVENANCE_DB_USER: ${POSTGRES_USER:-postgres}
1049
+ FADEN_PROVENANCE_DB_PASS: ${POSTGRES_PASSWORD:?set it in .env; an install that ran without it keeps its data only with the old default value (Help, Installing, Secrets in .env)}
1050
+ FADEN_PROVENANCE_DB_BASE: faden_provenance
1051
+
1052
+ faden-provenance:
1053
+ profiles: ["provenance"]
1054
+ image: ${REGISTRY:-ghcr.io/fadenstack}/provenance:${VERSION:-latest}
1055
+ container_name: faden-provenance
1056
+ logging: *faden-logging
1057
+ restart: unless-stopped
1058
+ depends_on:
1059
+ postgres:
1060
+ condition: service_healthy
1061
+ faden-provenance-migrator:
1062
+ condition: service_completed_successfully
1063
+ # Its signer, hash keys and watermark keys, as files under /run/secrets (secrets: at the end), not environment.
1064
+ secrets:
1065
+ - source: provenance_signing_key
1066
+ target: FADEN_PROVENANCE_SIGNING_KEY
1067
+ - source: provenance_signing_certs
1068
+ target: FADEN_PROVENANCE_SIGNING_CERTS
1069
+ - source: provenance_hash_keys
1070
+ target: FADEN_PROVENANCE_HASH_KEYS
1071
+ - source: provenance_watermark_keys
1072
+ target: FADEN_PROVENANCE_WATERMARK_KEYS
1073
+ # The server's model store, read only: the tokenizers a text's watermark is checked with.
1074
+ volumes:
1075
+ - faden_models:/srv/faden/models:ro
1076
+ environment:
1077
+ FADEN_PROVENANCE_HOST: 0.0.0.0
1078
+ FADEN_PROVENANCE_PORT: 8000
1079
+ FADEN_PROVENANCE_RELOAD: "false"
1080
+ FADEN_PROVENANCE_ENVIRONMENT: ${FADEN_PROVENANCE_ENVIRONMENT:-production}
1081
+ FADEN_PROVENANCE_DB_HOST: postgres
1082
+ FADEN_PROVENANCE_DB_PORT: 5432
1083
+ FADEN_PROVENANCE_DB_USER: ${POSTGRES_USER:-postgres}
1084
+ FADEN_PROVENANCE_DB_PASS: ${POSTGRES_PASSWORD:?set it in .env; an install that ran without it keeps its data only with the old default value (Help, Installing, Secrets in .env)}
1085
+ FADEN_PROVENANCE_DB_BASE: faden_provenance
1086
+ FADEN_PROVENANCE_SERVICE_TOKEN: ${FADEN_PROVENANCE_SERVICE_TOKEN:?set it in .env, as faden deploy and faden upgrade do (Help, Installing, Secrets in .env)}
1087
+ FADEN_PROVENANCE_PLUGINS: ${FADEN_PROVENANCE_PLUGINS:-}
1088
+ healthcheck:
1089
+ test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/api/health', timeout=3).read()"]
1090
+ interval: 5s
1091
+ timeout: 5s
1092
+ retries: 20
1093
+
955
1094
  # -----------------------------
956
1095
  # Observability: Loki + Grafana + Alloy + Prometheus
957
1096
  # -----------------------------
@@ -1081,3 +1220,49 @@ volumes:
1081
1220
  faden_models:
1082
1221
  faden_rag_lite:
1083
1222
  faden_chat_files:
1223
+ faden_audit:
1224
+ faden_pii_models:
1225
+ faden_pii_locks:
1226
+
1227
+ # The keys that open content: the chats, the sealed settings and provider keys, the machines' credentials, the
1228
+ # MCP servers' credentials; and the provenance engine's signer and hash keys. They are kept and changed in .env
1229
+ # as before; `faden` writes them into secrets/ (readable by the install's user only) before every compose
1230
+ # command it runs, and compose mounts them read-only under /run/secrets, where the services read them. They
1231
+ # are in no container's environment, so neither `docker inspect` nor the console's container pages show them.
1232
+ # Run compose through `faden`, or `faden up` once after changing one of them in .env by hand.
1233
+ secrets:
1234
+ gateway_encryption_key:
1235
+ # The key chats are encrypted with at rest: messages, titles, memory, attachment names and files, a reply's
1236
+ # events in Redis. Required: the gateway refuses to start without it, and without it the chats cannot be
1237
+ # read. .env belongs in every backup (`faden backup` takes it; --db-only does not).
1238
+ file: ./secrets/FADEN_GATEWAY_ENCRYPTION_KEY
1239
+ gateway_encryption_key_previous:
1240
+ # Only while `faden secrets rotate` is unfinished: chats sealed with the old key still open. Empty otherwise.
1241
+ file: ./secrets/FADEN_GATEWAY_ENCRYPTION_KEY_PREVIOUS
1242
+ settings_master_key:
1243
+ # Seals secret settings and the remote providers' API keys (the migrations pr0vk3ys and pr0vk3yg use it too).
1244
+ file: ./secrets/FADEN_BACKEND_SETTINGS_MASTER_KEY
1245
+ settings_master_key_previous:
1246
+ # Only while `faden secrets rotate` is unfinished: values sealed with the old key still open.
1247
+ file: ./secrets/FADEN_BACKEND_SETTINGS_MASTER_KEY_PREVIOUS
1248
+ credential_pepper:
1249
+ # What the machines' credential hashes are keyed with. Once the master key itself; a rotation changes the
1250
+ # master key and must not change this, or every machine would have to enroll again.
1251
+ file: ./secrets/FADEN_BACKEND_CREDENTIAL_PEPPER
1252
+ mcp_encryption_key:
1253
+ file: ./secrets/FADEN_MCP_ENCRYPTION_KEY
1254
+ mcp_encryption_key_previous:
1255
+ file: ./secrets/FADEN_MCP_ENCRYPTION_KEY_PREVIOUS
1256
+ provenance_signing_key:
1257
+ # The key C2PA manifests on generated pictures are signed with (PKCS#8 DER, base64); new with each certificate.
1258
+ file: ./secrets/FADEN_PROVENANCE_SIGNING_KEY
1259
+ provenance_signing_certs:
1260
+ # Its certificate from the install's authority, then the authority (PEM, base64); renewed 30 days ahead.
1261
+ file: ./secrets/FADEN_PROVENANCE_SIGNING_CERTS
1262
+ provenance_hash_keys:
1263
+ # The keys of the provenance records' hashes: every version ever used, the highest current (`1:...,2:...`).
1264
+ file: ./secrets/FADEN_PROVENANCE_HASH_KEYS
1265
+ provenance_watermark_keys:
1266
+ # The keys of the text watermark the model runtimes put into answers (vLLM's --watermark-config): every
1267
+ # version ever used, the highest current (`1:<whole number>,...`). Empty while the module is off.
1268
+ file: ./secrets/FADEN_PROVENANCE_WATERMARK_KEYS
@@ -23,6 +23,8 @@ CREATE DATABASE faden_gateway;
23
23
  CREATE DATABASE faden_mcp;
24
24
  -- DB for Skills Registry
25
25
  CREATE DATABASE faden_skills;
26
+ -- DB for Provenance (its migrator also makes it on installs created before)
27
+ CREATE DATABASE faden_provenance;
26
28
 
27
29
  -- Optional: enable pgvector in rag DB
28
30
  \connect rag