Skip to content

backups - UI mockups #82

@edospadoni

Description

@edospadoni

Overview

Design the Configuration Backup subsystem that replaces the legacy backupd.nethesis.it service. Covers the end-to-end flow, storage layout, RBAC, retention, security posture and the admin UI surface for Alpha 2.

Architecture

  • Ingest path (appliance → collect): POST /api/systems/backups with HTTP Basic auth using system_key:system_secret. Body is a GPG-encrypted blob produced by the appliance; the server never sees plaintext.
  • Read path (operator → backend): GET /api/systems/:id/backups, GET /api/systems/:id/backups/:backup_id/download (presigned URL), DELETE /api/systems/:id/backups/:backup_id. RBAC gated identically to GET /api/systems/:id.
  • Storage: bring-your-own S3 (DigitalOcean Spaces, AWS S3, R2, MinIO, Garage). No server-managed storage component; operators configure BACKUP_S3_* env vars.
  • Object key layout: {org_id}/{system_key}/{backup_id}.{ext}system_key chosen over internal UUID so the bucket listing is human-readable from an operator's S3 console.
  • Retention: enforced inline at ingest under a Redis SET NX lock; default caps are 10 backups + 500 MB per system + optional aggregate cap per org.
  • GDPR: DestroySystem purges the system's S3 prefix before deleting the DB row; destroy is refused if the purge fails (operator retries).

Security

  • backup_id regex-pinned to UUIDv7 + known extension whitelist.
  • Streaming SHA-256 via io.TeeReader; metadata reconciled via same-key CopyObject.
  • Presigned download TTL capped at 15 m; per-system ingest rate limit; cross-service auth-cache invalidation bus.
  • All metadata fields sanitised before being stored as x-amz-meta-* headers.
  • Minimum non-forgeable metadata set: sha256, filename (sanitised), uploader_ip (peer TCP, X-Forwarded-For deliberately ignored).

Legacy-client migration

During the transition NS8 and NethSecurity keep uploading to backupd.nethesis.it and dual-send to the new MY through a translation proxy that maps system_id:auth_tokensystem_key:system_secret and streams the body to collect. No appliance registration rewrite is required for Alpha 2 — the proxy absorbs the credential format difference.

UI

Per-system detail page, visible next to the existing Alerts tab:

  • Backups tab with:
    • Table columns: uploaded-at, filename, size, SHA-256 (truncated with tooltip on full hash).
    • Kebab menu on each row with Download and Delete (destructive → red).
    • Retention summary tiles above the table: slots used / max, storage used / max, retention-policy description.
    • Manual Refresh button; empty / loading / error states; notification on delete success or failure.
  • Overview → Status card gains two rows:
    • Alerts — green check when 0 active, amber triangle when ≥ 1.
    • Backups — green check when ≥ 1 stored, amber triangle when 0.

Out of scope

  • Rewriting the backup client on the appliances (NS8 / NethSecurity keep their existing system_id:auth_token flow + dual-send via proxy).
  • Migration of existing backupd.nethesis.it archives (encryption keys differ; natural cutover on first new upload).

Related issue: #83

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions