- dark2devil (UID 1002) aus der gesamten deklarierten State entfernt: derselbe Benutzer wie debugofen (Betreiberklärung 2026-10-28); GNAI-019 Entscheidung 11 revidiert, gn-media-Mitgliedschaft nur ghost - Share-ACLs im Inventar an die live smb.conf angeglichen (GNAI-018 R4): admin users auf elf Shares ergänzt, write list Dokumente/Extern ergänzt, Serien2 ohne force user/group; Template [printers] um browseable=no ergänzt - passdb-Asserts und Audit-Loops auf die drei deklarierten Medien-User umgestellt; Platzhalterzahl 11; provision-Script-Hash aktualisiert - AGENTS.md (Repo-Root) um Grundwissen für Agenten ergänzt: ghost-agent-Convention, Account-Landscape/Inventory-Pfade, Operator-Run-Steps, LXC-Konventionen, Repo-Konventionen Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
100 lines
6.0 KiB
Markdown
100 lines
6.0 KiB
Markdown
# Ghostnet.AI project context
|
|
|
|
Before infrastructure work, read `.codex/LOCAL_MEMORY.md` if it exists. It contains dated local observations and access hints; verify live state before making system changes. Keep secrets and private key material out of that file.
|
|
|
|
For read-only access to the KI server, use the tested SSH profile `ghostnet-ai-agent`, which logs in as the unprivileged account `ghost-agent` on `10.0.0.90`. On this workstation, invoke it as `ssh -F ~/.ssh/config ghostnet-ai-agent` because the system-wide SSH client configuration currently has an ownership/permissions error. Do not assume sudo access or make server changes without an explicit user request.
|
|
|
|
The KI server at `10.0.0.90` is deliberately a fresh base system. The operator plans to install the LLM application stack in a later Ansible sprint. Do not install applications or change server configuration as part of documentation review or access checks unless the operator explicitly requests that work.
|
|
|
|
## Agent access convention: `ghost-agent`
|
|
|
|
`ghost-agent` is the standard unprivileged account for the AI agent on the
|
|
Proxmox LXCs and the KI server (operator-confirmed 2026-10-28: "on the KI
|
|
server and many other Proxmox LXCs"). It is a convention, not a per-host
|
|
exception.
|
|
|
|
- Login is key-based with a **passphrase-less** Ed25519 key kept in the
|
|
operator's `~/.ssh` (`id_ed25519_ghostnet_<host>_agent`); `~/.ssh/config`
|
|
carries the matching `ghostnet-<host>-agent` aliases, which also work with
|
|
`ssh -o BatchMode=yes`. Private keys never enter the repository.
|
|
- `ghost-agent` has **no sudo** (verified on CT 100, CT 101, CT 103 and
|
|
ghostnet-ki): treat every agent session as read-only unless the operator
|
|
explicitly authorizes a change.
|
|
- Known aliases (verify live state before use; the WireGuard LXC has no
|
|
`ghost-agent` alias and uses the legacy `admin` account via alias `lxc`):
|
|
|
|
| Alias | System | IP |
|
|
| --- | --- | --- |
|
|
| `ghostnet-ct100-agent` | CT 100, Pi-hole/Split-DNS `dns` | 10.0.0.14 |
|
|
| `ghostnet-ct101-agent` | CT 101, Samba file server | 10.0.0.9 |
|
|
| `ghostnet-ct102-agent` | CT 102, Keycloak | 10.0.0.4 |
|
|
| `ghostnet-ct103-agent` | CT 103, reverse proxy (NPM) | 10.0.0.10 |
|
|
| `ghostnet-ct104-agent` | CT 104, Keycloak | 10.0.0.16 |
|
|
| `ghostnet-ai-agent` | ghostnet-ki, LLM/AI server | 10.0.0.90 |
|
|
|
|
- Invoke ssh as `ssh -F ~/.ssh/config <alias>`: a bare `ssh` currently rejects
|
|
`/etc/ssh/ssh_config.d/20-systemd-ssh-proxy.conf` because of its
|
|
ownership/permissions; `-F` deliberately uses the local profile without
|
|
loading that broken system configuration.
|
|
- Dated per-host observations (host-key fingerprints, verified identities,
|
|
account details) live in `.codex/LOCAL_MEMORY.md`, not here.
|
|
|
|
## Account landscape and Ansible inventory paths
|
|
|
|
| Account | Role | Key (operator `~/.ssh`) | sudo |
|
|
| --- | --- | --- | --- |
|
|
| `ghost-agent` | AI agent, read-only | `id_ed25519_ghostnet_<host>_agent` (no passphrase) | no |
|
|
| `ghost` | human operator/admin | `id_ed25519_ghostnet_<host>_ghost` (passphrase-protected) | yes, password-gated |
|
|
| `ansible-deploy` | Ansible deployment; created by the project's access role during adoption | `id_ed25519_ghostnet_<host>_ansible_deploy` (no passphrase) | `NOPASSWD: ALL` (treat the key as root-equivalent) |
|
|
|
|
Each Ansible LXC project (`proxmox/lxc/<ct>/ansible/`) maps these accounts to
|
|
three inventories: `agent` (`ghost-agent`, read-only preflight), `bootstrap`
|
|
(`ghost`, `--ask-become-pass`), `production` (`ansible-deploy`, NOPASSWD).
|
|
Legacy exceptions exist (CT 103 is root-only and bootstrapped via the Proxmox
|
|
console; the WireGuard LXC uses `admin`) — see `.codex/LOCAL_MEMORY.md`.
|
|
|
|
## Operator-run steps
|
|
|
|
- The workstation has **no Proxmox host access** (no `pct`): PVE-side commands
|
|
(`pct exec`, `pct reboot`, `vzdump`, editing `/etc/pve/lxc/*.conf`) are run by
|
|
the operator as root@pve. The agent prepares exact commands and reviews the
|
|
pasted output.
|
|
- Interactive secret steps are operator-run: `passwd`, `smbpasswd -a`, playbook
|
|
runs with `--ask-become-pass`, and key passphrase prompts. The agent hands
|
|
over copy-paste commands; the operator executes them.
|
|
- Secrets never enter the repository, inventories, playbooks or logs: SMB
|
|
passwords, the Samba passdb, the `ghost` password, private SSH keys, Podman
|
|
secrets. Only public keys belong in the repo (`ansible/files/ssh/`).
|
|
|
|
## LXC / Proxmox conventions
|
|
|
|
- Reboot caveat (GNAI-016 section 7): in LXC, `/proc/sys/kernel/random/boot_id`
|
|
belongs to the PVE host and does **not** change on a guest reboot — never use
|
|
boot_id-based waiters; reboot via PVE and verify independently over SSH.
|
|
- Unprivileged LXCs: keep the empty `lxc.seccomp.profile:` line (rootful
|
|
Podman/Ganesha containers need `open_by_handle_at`), mask
|
|
`sys-kernel-config.mount` (configfs is unavailable), and expect
|
|
`uid_map 0 100000 65536` — host UIDs appear as 65534 (nobody) inside the
|
|
guest.
|
|
- In-place dist-upgrades: take a `vzdump` safety net first and use
|
|
`--force-confold` so productive configuration files survive.
|
|
|
|
## Repository conventions
|
|
|
|
- Documentation: `docs/platform/proxmox-server/lxc/<ct>/GNAI-*.md` (German;
|
|
decisions carry operator/date stamps, findings are lettered a), b), …).
|
|
Ansible project READMEs are English. The central index is
|
|
`docs/GNAI-000-DOC_Index.md`.
|
|
- Ansible projects are self-contained under `proxmox/lxc/<ct>/ansible/`
|
|
(`ansible.cfg`, `inventories/{agent,bootstrap,production}`, `playbooks/`,
|
|
`roles/`, `files/ssh/`), use the repository-wide control venv (`.venv`, built
|
|
from `shared/ansible/requirements-control.txt`) and the shared roles in
|
|
`shared/ansible/roles/`.
|
|
- Change discipline: productive changes only with explicit operator go; preview
|
|
with `--check --diff` first; convergence must be idempotent (a second run
|
|
reports `changed=0`); commit only when the operator asks.
|
|
- Communicate with the operator in German.
|
|
- Verify account/identity assumptions with the operator before declaring them
|
|
(CT 101 example: `dark2devil` turned out to be the same person as
|
|
`debugofen`; GNAI-019 decision 11 was revised accordingly).
|