# Security Hardening

> **Status:** initial — opened 2026-06-14 (Pass 1 scaffold). **No
> items yet.**
> A federation-sibling-scoped security tracker for `mgf-cloud`. The
> repo is new at **0.1.0**; the credential-handling code, the
> adapters, the CLI guardrails, and the local web GUI land in
> Passes 2–5, so there is **no surface to audit yet**. This file
> establishes the canonical tracker shape + records the security
> design intent; items get opened as the surface lands. The full
> adversarial security review is **Pass 7**.
>
> **Scope (when populated):** mgf-cloud's OWN security posture —
> credential handling (read only from `clouds.yaml` / `OS_*` /
> `my_stuff`, never logged, never in tracebacks or the GUI), TLS
> verification on every outbound call, the local web GUI's
> localhost-only bind + no-auth posture, and the create/delete
> guardrails. NOT a re-audit of mgf-common's redactor / vault /
> crash reporter (inherited). NOT an audit of the provider SDKs or
> the cloud platform.
>
> **Audience:** the maintainer + future AI agents doing security
> work on this sibling.
> **Cross-references:**
> [`RELIABILITY_AND_ACCURACY.md`](RELIABILITY_AND_ACCURACY.md),
> [`../design/DESIGN.md`](../design/DESIGN.md) (§5 credentials, §10
> guardrails),
> [`mgf-standard/docs/standards/SECURITY_STANDARD.md`](https://codeberg.org/magogi-admin/mgf-standard/src/branch/main/docs/standards/SECURITY_STANDARD.md)
> (the SC-* rules), repo-root [`SECURITY.md`](../../SECURITY.md)
> (the vulnerability-reporting policy — distinct from this tracker).

`mgf-cloud` manages **live, billable infrastructure** and handles
**cloud credentials**, so security is first-class. Most
secret-handling primitives (Redactor, vault, crash reporter,
traceback scrubbing) are inherited from `mgf-common` and verified
elsewhere; this tracker covers the cloud-adapter-specific surface.

---

## §1 You are here

`mgf-cloud` is at 0.1.0 (Pass 1 — the conformant scaffold). The
only code today is the `__init__` + `__main__` CLI dispatch
skeleton; there is no credential-loading code, no adapter, and no
web GUI to audit. **No items are open.**

The first security-relevant surfaces arrive with:

- **Pass 2** — `config.py` (credential loading via pydantic-settings
  from `clouds.yaml` / `OS_*` / `my_stuff`) + `exceptions.py`. The
  load-bearing rule: credentials never serialise into errors.
- **Pass 3** — the Infomaniak adapter (openstacksdk TLS-verify-on,
  EC2/S3 key handling) + `remote.py` SSH bootstrap (host-key
  handling, no secret in the command log).
- **Pass 4** — the CLI guardrails: `--yes`/confirm to create or
  delete, `--dry-run` everywhere, secrets never printed.
- **Pass 5** — the local web GUI: bind `127.0.0.1` only, no auth,
  no credential surfaced in any view.
- **Pass 7** — the full adversarial security review.

**Counts (2026-06-14):**

| Priority | Open | Closed | Total |
|---|---|---|---|
| P0 — blockers | 0 | 0 | 0 |
| P1 — should land before/with 1.0 | 0 | 0 | 0 |
| P2 — hardening | 0 | 0 | 0 |
| **Total** | **0** | **0** | **0** |

**Do first:** nothing yet — open the first SH item when Pass 2/3
gives it a surface to audit.

---

## §2 Priority table

_No items yet._ Each item, when opened, ties to an SC-* rule +
concrete `file:line` evidence + a falsifiable concrete output.

| ID | Concern | One-liner | Effort | Status |
|---|---|---|---|---|
| _(none)_ | — | — | — | — |

Effort scale: XS (≤ 15 min); S (≤ 1 h); M (≤ 1 session).

---

## §3 Invariants we hold (design intent)

These are the security commitments from the design
([`../design/DESIGN.md`](../design/DESIGN.md) §5 + §10), to be
pinned by tests as the code lands:

- **SH-INV-1** — **Credentials read only from sanctioned sources.**
  `clouds.yaml`, the `OS_*` environment, or a token/clouds file
  under `my_stuff/` (gitignored per AG-18). No other source.
- **SH-INV-2** — **Credentials never logged.** No credential, app-
  credential secret, or EC2/S3 key is logged, serialised into an
  error/traceback, or surfaced in the web GUI. Inherits
  mgf-common's Redactor + traceback scrubbing (SC-09, SC-11).
- **SH-INV-3** — **TLS verification stays on.** openstacksdk (and
  any boto3) outbound calls verify TLS; never disabled (SC-06).
- **SH-INV-4** — **Web GUI is localhost-only.** The `mgf-cloud web`
  server binds `127.0.0.1` and has no public surface in v1.
- **SH-INV-5** — **Mutating ops are guarded.** Create/delete
  require `--yes` or an interactive confirmation; `--dry-run`
  plans before applying.

These are intent until the code exists; each becomes a pinned test
+ moves to a closed-item record as its surface lands.

---

## §4 Work units

_No work units yet._ When the first item opens, follow the
canonical shape: **Why** (with `file:line` evidence) → **Concrete
output** → **Locked in by** → **Cross-references** → **Status**.

---

## §5 Closed items

_None yet._

---

## §6 Notes on methodology

When the surface lands, the audit method mirrors mgf-common's SH
tracker:

1. Read each source file end-to-end with the **SC** rule set in
   mind (SC-01 secrets, SC-06 TLS, SC-09 sink redaction, SC-11
   traceback scrubbing, SC-10 vuln scan, SC-18 SBOM).
2. For every concern surfaced, verify `file:line` against the live
   source.
3. Cross-reference against the sibling's RA tracker (shared items
   get the security lens here, the correctness record there) and
   against mgf-common's SH tracker (confirm inherited invariants
   don't need re-tracking).
4. Triage: items that don't tie to an SC rule or a concrete
   secret-handling concern are observations.

The first pass should target credential loading (Pass 2) and the
adapter's TLS + secret-handling (Pass 3); the full adversarial
review (idempotency, partial-failure cleanup, leaks, retry, the
localhost web bind) is Pass 7.
