Files

93 lines
3.6 KiB
Markdown
Raw Permalink Normal View History

# 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 <id> # output JSON (never log this)
sudo meta-creds.sh add muse <id> # 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": {
"<id>": {
"email": "...",
"phone": "...",
"via_meta_account": "<facebook|instagram id>",
"age_verified": "true",
"instagram_linked": "<handle>",
"verified_by": "human", "verified_at": "2026-10-03T...",
"notes": "..."
}
},
"instagram": {
"<id>": {
"username": "...", "password": "...",
"email": "...", "phone": "...",
"accounts_center": "<alias>",
"linked_to": ["<other store id>", "..."],
"login_methods": ["password", "phone_otp"]
}
},
"facebook": {
"<id>": {
"email": "...", "password": "...", "phone": "...",
"accounts_center": "<alias>",
"linked_to": ["<other store id>", "..."],
"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.