# Meta Credential Store (operator-only) Centralized encrypted store for Muse, Instagram, Facebook account credentials. ## Location (VM only) - `/etc/netvm/meta-credentials/store.age` — age-encrypted JSON (600 root) - `/etc/netvm/meta-credentials/.age-key` — age private key (600 root) - `/usr/local/bin/meta-creds.sh` — CLI (700 root) ## Usage ```bash sudo meta-creds.sh list muse # list account IDs (no secrets) sudo meta-creds.sh get muse # output JSON (never log this) sudo meta-creds.sh add muse # interactive prompts ``` ## Naming Store ID == `ACCOUNTS.md` `agent` name (e.g. `646`, `pip`, `muse`). The secret store and the secret-free registry join on this ID — same account, different jobs (secrets vs. state). ## Schema ```json { "muse": { "": { "email": "...", "phone": "...", "via_meta_account": "", "age_verified": "true", "instagram_linked": "", "verified_by": "human", "verified_at": "2026-10-03T...", "notes": "..." } }, "instagram": { "": { "username": "...", "password": "...", "email": "...", "phone": "...", "accounts_center": "", "linked_to": ["", "..."], "login_methods": ["password", "phone_otp"] } }, "facebook": { "": { "email": "...", "password": "...", "phone": "...", "accounts_center": "", "linked_to": ["", "..."], "login_methods": ["password", "phone_otp"] } } } ``` ### Field notes - `phone`: mobile number for login/2FA. **May be stored here** (encrypted); one phone can map to multiple accounts (observed: 646 + piparada share a number) — never treat it as a unique key. - `via_meta_account` (muse): when muse.ai auth runs through a Meta account (phone OTP → Meta account → muse.ai), points at the `facebook`/`instagram` entry. This is the 646/pip intersection. - `accounts_center`: local alias for the Accounts Center (e.g. `ac-646`). Post early-2026 this is the login blast-radius boundary — every account in one Center logs into every other by default. - `linked_to`: other store IDs in the same Accounts Center. Cached from the Meta API's `list-linked`; **the API is ground truth** — when they disagree, the API wins and the store gets updated. - `login_methods`: how the account can be authenticated. Drives which flow the automation attempts. ## Intersections - **Phone ↔ accounts (1:many):** the store holds the number (encrypted); the human is no longer the sole holder, but the number still never appears in logs, chat, memory, or the secret-free registry. - **Meta credential → muse.ai session:** a `facebook`/`instagram` entry can be the auth path for a `muse` login. Follow `via_meta_account`. - **Store ↔ ACCOUNTS.md:** joined on ID. Store = secrets, registry = state. - **Store ↔ Meta Accounts Center API** (`docs/META-ACCOUNTS-API.md`): the API reads linkage ground truth; the store caches it in `linked_to` / `accounts_center`. ## Rules - Operators only. Developers never get access (prevents board leaks). - Decrypt transiently, never log values, never put in chat/memory. - Phone numbers and PII **may** live in `store.age` (age-encrypted, 600 root, VM only). They must never appear in plaintext anywhere else: no logs, no chat, no memory, no registry, no board. - Human validates Instagram linking and Meta account ownership; operators automate after. - When adding an account, fill `accounts_center` / `linked_to` from the Meta API (`list-linked`), not from memory.