docs: prepare public technical preview
CI / rust (push) Has been cancelled

This commit is contained in:
Julien Denizot
2026-06-24 16:09:22 +02:00
parent cebd8abe93
commit b9800bad10
22 changed files with 959 additions and 3 deletions
+18
View File
@@ -0,0 +1,18 @@
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.rs]
indent_style = space
indent_size = 4
[*.{yml,yaml}]
indent_style = space
indent_size = 2
[*.md]
trim_trailing_whitespace = false
+16
View File
@@ -0,0 +1,16 @@
# Shared
ENUXIA_AGENT_SOCKET=/run/user/1000/enuxia-frappe-aio/agent.sock
ENUXIA_COMPOSE_PROJECT=my-frappe-project
ENUXIA_SITE_NAME=site.example.test
# Agent only
ENUXIA_AGENT_STATE_DB=/home/user/.local/state/enuxia-frappe-aio/agent.sqlite3
ENUXIA_DOCKER_HOST=unix:///var/run/docker.sock
# Controller only
ENUXIA_INSTANCE_NAME=my-frappe-instance
ENUXIA_TARGET_NAME=local-node
ENUXIA_FRAPPE_VERSION=v16
ENUXIA_BUILD_VERSION=dev
# The controller intentionally does not use DOCKER_HOST or ENUXIA_DOCKER_HOST.
+15
View File
@@ -0,0 +1,15 @@
* text=auto eol=lf
*.rs text eol=lf
*.toml text eol=lf
*.md text eol=lf
*.yml text eol=lf
*.yaml text eol=lf
*.sh text eol=lf
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.webp binary
*.zip binary
+1
View File
@@ -0,0 +1 @@
* @luunz71
+35
View File
@@ -0,0 +1,35 @@
---
name: Bug report
about: Report reproducible incorrect behavior
title: "bug: "
labels:
- bug
---
## Environment
- Commit or release:
- Linux distribution:
- Docker version:
- Frappe/ERPNext version:
- Deployment layout:
## Description
## Reproduction
1.
2.
3.
## Expected behavior
## Observed behavior
## Logs
Remove secrets, tokens, personal data, and private application data before posting logs.
## Security impact
If this may be a vulnerability, stop and follow `SECURITY.md` instead of publishing the report.
+19
View File
@@ -0,0 +1,19 @@
---
name: Feature request
about: Propose a focused capability
title: "feat: "
labels:
- enhancement
---
## Problem
## Proposed behavior
## Security-boundary impact
Does the change affect the controller, agent, Docker access, protocol, SQLite state, backup storage, or destructive operations?
## Alternatives
## Additional context
+22
View File
@@ -0,0 +1,22 @@
## Summary
## Why
## Security-boundary impact
- [ ] No Docker access was added to the controller
- [ ] No arbitrary shell execution was added
- [ ] New protocol data is validated and bounded
- [ ] State-changing work is persisted
- [ ] Tests cover the change
## Verification
```text
cargo fmt --all -- --check
cargo check --workspace
cargo test --workspace
git diff --check
```
## Manual testing
+29
View File
@@ -0,0 +1,29 @@
name: CI
on:
push:
branches:
- main
pull_request:
jobs:
rust:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- name: Check formatting
run: cargo fmt --all -- --check
- name: Check workspace
run: cargo check --workspace
- name: Run tests
run: cargo test --workspace
+6 -3
View File
@@ -9,21 +9,24 @@ secrets/
*.secret
*.key
*.pem
# État dexécution local
*.sock
*.pid
state/
backups/
logs/
# Fichiers temporaires et sauvegardes d’éditeur
*.bak
*.tmp
*.swp
*~
.DS_Store
# IDE
.idea/
.vscode/
# Public repository safety
*.sqlite
*.sqlite3
*.db
*.log
/backups/
+29
View File
@@ -0,0 +1,29 @@
# Changelog
## [Unreleased]
### Planned
- Restore workflow
- Backup retention
- Scheduled backups
- Installation and service packaging
- Additional hardening and failure-injection tests
## [0.1.0] - 2026-06-24
### Added
- Rust workspace with protocol, agent, and controller components
- Typed JSON protocol over a Unix socket
- Mode `0600` agent socket
- SQLite operation persistence with WAL and restart recovery
- Docker Compose discovery through labels
- Complete Frappe backup workflow
- Backup manifests with sizes and SHA-256 checksums
- Backup history exposed through the agent
- Read-only backup integrity verification
- Typed service status API
- Bounded service log API
- Axum/Askama dashboard
- Unprivileged controller with no Docker or shell access
+9
View File
@@ -0,0 +1,9 @@
# Code of Conduct
We want the Enuxia Frappe AIO community to be constructive, technically rigorous, and welcoming.
Participants are expected to communicate respectfully, critique ideas rather than people, document security concerns responsibly, and respect privacy.
Harassment, discrimination, threats, deliberate disruption, publication of private information, and premature disclosure of vulnerabilities are not acceptable.
Maintainers may edit or remove contributions and restrict participation when behavior conflicts with this policy. Reports should be sent privately to the Enuxia organization maintainers.
+42
View File
@@ -0,0 +1,42 @@
# Contributing
## Development principles
Every change must preserve these rules:
1. The controller remains unprivileged.
2. The controller never accesses Docker directly.
3. The controller never executes arbitrary system commands.
4. Privileged behavior belongs in the local agent.
5. Agent operations are typed and explicitly allow-listed.
6. Requests and responses are bounded and validated.
7. State-changing work is persisted.
8. Backup verification remains read-only.
9. Docker resources are discovered through labels, not physical names.
10. Tests accompany protocol and security-boundary changes.
## Local verification
```bash
cargo fmt --all -- --check
cargo check --workspace
cargo test --workspace
git diff --check
```
## Commit messages
Use concise Conventional Commit-style messages where practical:
```text
feat: expose bounded service logs through agent
fix: reject unsafe backup identifiers
refactor: remove Docker access from controller
docs: document restore safety model
```
## Protocol changes
Protocol changes require stable JSON-shape tests, serialization round trips, compatibility consideration, and strict validation.
Do not add a generic shell-command request.
+202
View File
@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+4
View File
@@ -0,0 +1,4 @@
Enuxia Frappe AIO
Copyright 2026 Enuxia
This product is an independent open-source project and is not affiliated with or endorsed by Frappe Technologies.
+132
View File
@@ -0,0 +1,132 @@
# Enuxia Frappe AIO
[English version](README.md)
Contrôleur local, sécurisé et orienté exploitation pour une stack Frappe ou ERPNext.
> **Aperçu technique — v0.1.0**
>
> La version actuelle prend en charge l’état des services, les journaux bornés, la création de sauvegardes Frappe, leur historique et leur vérification dintégrité en lecture seule. La restauration, la rétention, la planification, le packaging et le durcissement de production restent à développer.
## Pourquoi ce projet
Lexploitation dune stack Frappe auto-hébergée demande souvent un accès direct à Docker, des commandes shell et une connaissance précise du déploiement. Enuxia Frappe AIO vise une couche dexploitation plus sûre :
- le contrôleur web naccède pas au socket Docker ;
- le contrôleur nexécute aucune commande système ;
- les actions privilégiées sont exposées par des opérations typées et autorisées ;
- les opérations et leurs résultats sont persistés dans SQLite ;
- les sauvegardes contiennent un manifeste et des empreintes SHA-256 ;
- la vérification dintégrité est réalisée en lecture seule ;
- l’état et les journaux des services passent par lagent local.
## Fonctionnalités actuelles
- Agent local Rust avec accès à lAPI Docker
- Contrôleur Axum/Askama non privilégié
- Protocole JSON typé sur socket Unix en mode `0600`
- File dopérations persistée dans SQLite
- Sauvegarde complète dun site Frappe
- Historique des sauvegardes
- Vérification dintégrité en lecture seule
- Vérification des tailles et SHA-256
- État typé des services Frappe attendus
- Consultation bornée des journaux
- Découverte par labels Docker Compose
- Récupération des opérations interrompues après redémarrage de lagent
## Architecture
```text
Navigateur
|
v
enuxia-aio-controller
- non privilégié
- aucun socket Docker
- aucune commande shell
|
| JSON typé / socket Unix
v
enuxia-aio-agent
- opérations autorisées
- état SQLite
- accès API Docker
|
v
Conteneurs Frappe et conteneurs temporaires dopération
```
Consultez [larchitecture](docs/ARCHITECTURE.md) et le [modèle de sécurité](docs/SECURITY-MODEL.md).
## État du projet
| Fonction | État |
|---|---|
| État des services | Disponible |
| Journaux bornés | Disponible |
| Création de sauvegarde | Disponible |
| Historique | Disponible |
| Vérification dintégrité | Disponible |
| Restauration | Planifiée |
| Politique de rétention | Planifiée |
| Sauvegardes planifiées | Planifiées |
| Packaging | Planifié |
| Audit de sécurité de production | Non réalisé |
## Démarrage en développement
```bash
cargo fmt --all -- --check
cargo check --workspace
cargo test --workspace
```
### Agent
```bash
export ENUXIA_AGENT_SOCKET="${XDG_RUNTIME_DIR}/enuxia-frappe-aio/agent.sock"
export ENUXIA_AGENT_STATE_DB="${XDG_STATE_HOME:-$HOME/.local/state}/enuxia-frappe-aio/agent.sqlite3"
export ENUXIA_DOCKER_HOST="unix:///var/run/docker.sock"
export ENUXIA_COMPOSE_PROJECT="mon-projet-frappe"
export ENUXIA_SITE_NAME="site.example.test"
cargo run -p enuxia-aio-agent
```
### Contrôleur
```bash
unset ENUXIA_DOCKER_HOST
unset DOCKER_HOST
export ENUXIA_AGENT_SOCKET="${XDG_RUNTIME_DIR}/enuxia-frappe-aio/agent.sock"
export ENUXIA_COMPOSE_PROJECT="mon-projet-frappe"
export ENUXIA_INSTANCE_NAME="mon-instance-frappe"
export ENUXIA_SITE_NAME="site.example.test"
export ENUXIA_TARGET_NAME="nœud-local"
cargo run -p enuxia-aio-controller
```
Ouvrir `http://127.0.0.1:3000`.
## Sécurité
Lire [SECURITY.md](SECURITY.md) avant de signaler une vulnérabilité.
Contraintes principales :
- ne jamais exposer le socket de lagent sur TCP ;
- ne jamais exposer le socket Docker au contrôleur ;
- ne jamais ajouter dexécution shell arbitraire au protocole ;
- considérer lagent comme un composant local privilégié ;
- ne pas utiliser cet aperçu technique comme unique mécanisme de sauvegarde.
## Licence
Apache License 2.0. Voir [LICENSE](LICENSE).
## Avertissement
Ce projet open source indépendant est développé par Enuxia. Il nest ni affilié ni approuvé par Frappe Technologies.
+177
View File
@@ -0,0 +1,177 @@
# Enuxia Frappe AIO
[Version française](README.fr.md)
A local, security-oriented controller for operating a Frappe or ERPNext stack.
> **Technical Preview — v0.1.0**
>
> The current release supports service monitoring, bounded logs, Frappe backups, backup history, and read-only integrity verification. Restore, retention, scheduling, packaging, and production hardening are still in progress.
## Why this project exists
Operating a self-hosted Frappe stack often requires direct Docker access, shell commands, and knowledge of the deployment layout. Enuxia Frappe AIO introduces a safer operational layer:
- the web controller has no Docker socket access;
- the controller executes no system commands;
- privileged actions are exposed as typed, allow-listed agent operations;
- operations and results are persisted in SQLite;
- backups include a manifest and SHA-256 checksums;
- integrity verification runs read-only;
- service state and logs are obtained through the local agent.
## Current capabilities
- Local Rust agent with Docker API access
- Unprivileged Axum/Askama controller
- Typed JSON protocol over a mode `0600` Unix socket
- Persistent operation queue and results in SQLite
- Complete Frappe backup workflow
- Four backup artifact roles: database, configuration, public files, private files
- Backup history
- Read-only integrity verification
- Size and SHA-256 verification for every artifact
- Typed status for the expected Frappe services
- Bounded service log retrieval
- Docker Compose discovery through labels
- Recovery of interrupted operations after agent restart
## Architecture
```text
Browser
|
v
enuxia-aio-controller
- unprivileged
- no Docker socket
- no shell execution
|
| typed JSON / Unix socket
v
enuxia-aio-agent
- allow-listed operations
- SQLite state
- Docker API access
|
v
Frappe containers and temporary operation containers
```
See [Architecture](docs/ARCHITECTURE.md) and [Security model](docs/SECURITY-MODEL.md).
## Project status
| Capability | Status |
|---|---|
| Service status | Available |
| Bounded service logs | Available |
| Create backup | Available |
| Backup history | Available |
| Verify backup integrity | Available |
| Restore backup | Planned |
| Retention policy | Planned |
| Scheduled backups | Planned |
| Installation packaging | Planned |
| Production security audit | Not completed |
## Requirements
- Linux
- Rust stable toolchain
- Docker Engine
- A Docker Compose-managed Frappe stack
- A dedicated local Unix socket for controller-to-agent communication
The agent requires Docker access. Treat access to a Docker socket as highly privileged.
## Development quick start
```bash
cargo fmt --all -- --check
cargo check --workspace
cargo test --workspace
```
### Start the agent
```bash
export ENUXIA_AGENT_SOCKET="${XDG_RUNTIME_DIR}/enuxia-frappe-aio/agent.sock"
export ENUXIA_AGENT_STATE_DB="${XDG_STATE_HOME:-$HOME/.local/state}/enuxia-frappe-aio/agent.sqlite3"
export ENUXIA_DOCKER_HOST="unix:///var/run/docker.sock"
export ENUXIA_COMPOSE_PROJECT="my-frappe-project"
export ENUXIA_SITE_NAME="site.example.test"
cargo run -p enuxia-aio-agent
```
### Start the controller
```bash
unset ENUXIA_DOCKER_HOST
unset DOCKER_HOST
export ENUXIA_AGENT_SOCKET="${XDG_RUNTIME_DIR}/enuxia-frappe-aio/agent.sock"
export ENUXIA_COMPOSE_PROJECT="my-frappe-project"
export ENUXIA_INSTANCE_NAME="my-frappe-instance"
export ENUXIA_SITE_NAME="site.example.test"
export ENUXIA_TARGET_NAME="local-node"
cargo run -p enuxia-aio-controller
```
Open `http://127.0.0.1:3000`.
Additional variables are documented in [.env.example](.env.example).
## Expected Compose services
The current dashboard expects these Compose service labels:
- `frontend`
- `backend`
- `db`
- `redis-cache`
- `redis-queue`
- `websocket`
- `queue-short`
- `queue-long`
- `scheduler`
Physical container names are not part of the public contract.
## Backup model
Each successful backup records a unique identifier, site, timestamp, total size, storage location, four artifacts, and one SHA-256 checksum per artifact.
Integrity verification reloads the persisted manifest, mounts backup storage read-only, recomputes sizes and checksums, and persists a structured verification result.
This is not a replacement for off-site backups, restore testing, or a disaster-recovery plan.
## Security
Read [SECURITY.md](SECURITY.md) before reporting a vulnerability.
Important constraints:
- never expose the agent socket over TCP;
- never expose the Docker socket to the controller;
- never add arbitrary shell execution to the protocol;
- treat the agent as a privileged local component;
- do not use this technical preview as the only backup mechanism.
## Contributing
Read [CONTRIBUTING.md](CONTRIBUTING.md) before opening a pull request.
## Roadmap
See [ROADMAP.md](ROADMAP.md).
## License
Apache License 2.0. See [LICENSE](LICENSE).
## Disclaimer
This is an independent open-source project by Enuxia. It is not affiliated with or endorsed by Frappe Technologies.
+40
View File
@@ -0,0 +1,40 @@
# Roadmap
This roadmap describes intent, not a delivery commitment.
## v0.2 — Restore V1
- Select only a valid, manifested backup
- Explicit destructive-action confirmation
- Persisted restore operation
- Pre-restore safety checks
- Maintenance-mode handling
- Database and file restoration
- Post-restore migration and health checks
- Failure reporting and recovery plan
- Real restore tests on disposable environments
## v0.3 — Backup operations
- Retention policies
- Manual deletion
- Scheduled backups
- Automatic post-backup verification
- Storage-capacity checks
- Off-site export interface
## v0.4 — Packaging
- systemd units
- Dedicated users and groups
- Installation and upgrade tooling
- Configuration validation
- Release artifacts
## v1.0 — Stable foundation
- Security review
- Restore workflow validated
- Upgrade and rollback documentation
- Stable protocol policy
- Production deployment guide
+44
View File
@@ -0,0 +1,44 @@
# Security Policy
## Project status
Enuxia Frappe AIO is a technical preview. It has not received a formal independent security audit and must not be treated as a complete production backup or disaster-recovery solution.
## Reporting a vulnerability
Do not open a public issue for a suspected vulnerability.
Use a private communication channel with the Enuxia organization maintainers on the Gitea instance. Include the affected commit, reproduction steps, impact, and any proposed mitigation.
## Security boundaries
### Controller
The controller must not:
- access the Docker socket;
- execute system commands;
- read the agent SQLite database directly;
- expose privileged operations outside the typed protocol.
### Agent
The agent is privileged because it can access Docker. It must:
- remain local;
- expose only allow-listed typed operations;
- use a mode `0600` Unix socket;
- validate every identifier and bound;
- avoid arbitrary command execution;
- keep responses bounded;
- persist state-changing operations safely.
## Operational guidance
- Restrict access to the agent socket.
- Do not bind the agent protocol to TCP.
- Protect the SQLite state database.
- Use off-site backups.
- Test restoration on disposable infrastructure.
- Do not rely solely on checksum verification.
- Review configuration before exposing the web interface beyond localhost.
+57
View File
@@ -0,0 +1,57 @@
# Architecture
## Overview
```text
Browser
|
v
Controller
|
| typed JSON / Unix socket 0600
v
Agent
|\
| \__ SQLite operation state
|
\____ Docker API
|
+-- Frappe Compose services
+-- temporary operation containers
```
## Controller
The controller displays agent health, service state, logs, backup history, and operation results. It has no Docker access and no direct SQLite access.
## Agent
The agent validates typed requests, owns Docker access, discovers resources through Compose labels, persists operations, runs the worker, and returns bounded structured responses.
## Worker
The worker atomically claims queued operations, marks them running, executes an allow-listed operation, and persists a result or error. Interrupted running operations are marked failed after restart.
## Backup workflow
```text
Controller -> StartOperation(Backup)
Agent -> persist queued operation
Worker -> discover runtime -> run backup -> hash artifacts -> persist BackupResult
Controller -> poll status -> display result and history
```
## Verification workflow
```text
Controller -> StartOperation(VerifyBackup)
Agent -> load persisted manifest
Worker -> mount storage read-only -> recompute sizes and SHA-256 -> persist result
Controller -> display global and per-artifact result
```
## Discovery contract
The implementation relies on Docker Compose labels such as `com.docker.compose.project`, `com.docker.compose.service`, and `com.docker.compose.volume`.
Physical container names are display information, not stable identifiers.
+35
View File
@@ -0,0 +1,35 @@
# Security Model
## Trust boundaries
### Browser to controller
The web interface is currently intended for local or otherwise protected access. Authentication and reverse-proxy hardening are not yet provided by the technical preview.
### Controller to agent
Controls include filesystem permissions, typed requests, protocol-version validation, strict identifier validation, bounded responses, and no generic command request.
### Agent to Docker
This is the strongest privilege boundary. Docker access can provide effective control over the host. Compromise of the agent must be treated as severe.
## Core invariants
- The controller has no Docker socket.
- The controller has no shell-execution facility.
- The controller does not read SQLite directly.
- The agent accepts only known request variants.
- Operation parameters are validated.
- Backup identifiers cannot contain path traversal.
- Service identifiers are restricted.
- Verification storage is mounted read-only.
- Backup artifacts must be regular files during verification.
- Service logs are bounded.
- State-changing operations are persisted.
## Integrity limitations
Checksums detect unexpected artifact changes. They do not prove semantic database validity, successful restoration, off-site durability, or the absence of coordinated tampering with both data and metadata.
Regular restoration tests remain necessary.
+20
View File
@@ -0,0 +1,20 @@
#!/usr/bin/env bash
set -euo pipefail
if [[ -n "$(git status --porcelain)" ]]; then
echo "The working tree is not clean." >&2
git status --short
exit 1
fi
cargo fmt --all -- --check
cargo check --workspace
cargo test --workspace
git diff --check
if git ls-files | grep -Ei '(^|/)(\.env($|\.)|.*\.pem$|.*\.key$|id_rsa$|id_ed25519$|.*\.sqlite3?$|.*\.db$)'; then
echo "Potentially sensitive tracked file found." >&2
exit 1
fi
echo "Public release checks passed."
+7
View File
@@ -0,0 +1,7 @@
#!/usr/bin/env bash
set -euo pipefail
cargo fmt --all -- --check
cargo check --workspace
cargo test --workspace
git diff --check