meta-acct: Accounts Center read API (list-linked, security-status, login-activity)\n\nImplements the read ops from META-ACCOUNTS-API.md via the agent browser\nsession. Key finding: phone-OTP login leaves a full Meta session -\naccountscenter.meta.com loads without redirect.\n\nAlso: 646 node fully registered (warp-646, CDP 9430, active).
This commit is contained in:
@@ -0,0 +1,174 @@
|
||||
# Meta Accounts Center API
|
||||
|
||||
**Status:** active (2026-10-03)
|
||||
**Motivation:** the phone number used in the muse.ai OTP pilot is linked to a
|
||||
Facebook account with its own credentials. Meta account management must be a
|
||||
separate, isolated API — never tangled with the phone-OTP flow.
|
||||
|
||||
## What it is
|
||||
|
||||
A dedicated operator CLI + privileged gateway for automating
|
||||
[Accounts Center](https://accountscenter.meta.com/) operations: the Meta hub
|
||||
where Facebook, Instagram, WhatsApp, and Meta accounts are linked, with
|
||||
shared login, security settings, and connected experiences.
|
||||
|
||||
It is **not** a general Facebook/Instagram automation tool. It manages the
|
||||
*account linkage and security surface* — which accounts are linked, how they
|
||||
log into each other, 2FA/password state, login activity. Content operations
|
||||
(posting, messaging) are out of scope.
|
||||
|
||||
## Separation guarantees
|
||||
|
||||
1. **Credential namespace:** uses `meta-creds.sh` types `facebook` /
|
||||
`instagram` only. The phone number is a *contact method* on the Facebook
|
||||
account, never a credential identifier. The `phone-otp` route (muse.ai
|
||||
SMS flow) and Meta credentials never share IDs, profiles, or audit logs.
|
||||
2. **Browser/session reuse:** Meta automation runs in the agent's
|
||||
existing chrome-box profile — the same profile serves muse.ai and
|
||||
accountscenter.meta.com. The 1:1 rule (node == agent == profile)
|
||||
already gives us one egress per agent; no separate Meta node needed.
|
||||
The phone-OTP login that established the muse.ai session also
|
||||
establishes the Meta session, so read ops reuse it without
|
||||
re-authenticating.
|
||||
3. **Authorization without exposure:** follows `CREDENTIAL-GATEWAY.md`.
|
||||
Agents know credential IDs and target actions; the privileged gateway
|
||||
decrypts from `store.age` and injects via CDP. Secrets never enter agent
|
||||
context, logs, or chat.
|
||||
4. **Audit:** every call logs `{ts, credential_id, action, target}` —
|
||||
never values. Separate audit trail from phone-OTP operations.
|
||||
|
||||
## Operations
|
||||
|
||||
### Read (operator may run freely)
|
||||
|
||||
| Command | What it returns |
|
||||
|---|---|
|
||||
| `meta-acct.sh list-linked <cred-id>` | Accounts in the Accounts Center (type, username, linked since) |
|
||||
| `meta-acct.sh login-activity <cred-id>` | Recent logins: device, IP/geo, time; flags unrecognized |
|
||||
| `meta-acct.sh security-status <cred-id>` | 2FA on/off + method, login alerts on/off, password age |
|
||||
| `meta-acct.sh connected-experiences <cred-id>` | Per-experience toggles: cross-app login, cross-posting, etc. |
|
||||
|
||||
### Write (human-gated via `/etc/netvm/approvals/`)
|
||||
|
||||
| Command | Gate reason |
|
||||
|---|---|
|
||||
| `meta-acct.sh add-account <cred-id> --type <facebook\|instagram>` | Links a new account; changes login blast radius |
|
||||
| `meta-acct.sh remove-account <cred-id> --account <id>` | Unlinks; some connected experiences don't revert cleanly |
|
||||
| `meta-acct.sh set-login-linking <cred-id> --on\|--off` | Controls cross-app login (see 2026 change below) |
|
||||
| `meta-acct.sh rotate-password <cred-id>` | Credential change; invalidates sessions |
|
||||
| `meta-acct.sh set-2fa <cred-id> --method <sms\|app\|key>` | Security-critical |
|
||||
|
||||
Human gates use the existing `netvm-approve.sh` flow: the agent prepares the
|
||||
exact action, the human approves the specific `(credential_id, action,
|
||||
target)` tuple, the gateway executes once.
|
||||
|
||||
## The early-2026 login change
|
||||
|
||||
Meta is removing the "Logging in with accounts" toggle: starting early 2026,
|
||||
**all accounts in the same Accounts Center log into each other by default**.
|
||||
Accounts Center membership *becomes* the login boundary.
|
||||
|
||||
Implications for this API:
|
||||
- `list-linked` is now security-critical: anyone with one account's
|
||||
credentials can reach the others.
|
||||
- The API must surface a "blast radius" view: for a given credential, which
|
||||
accounts are reachable through the Accounts Center.
|
||||
- `remove-account` becomes the only way to revoke cross-app login — it must
|
||||
stay human-gated and be auditable.
|
||||
- Recommend: keep each client's accounts in their own Accounts Center;
|
||||
never mix clients (consistent with the one-client-one-credential-set rule).
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Agent (untrusted) ──▶ meta-acct.sh (operator CLI)
|
||||
│ validates scope, checks human-gate
|
||||
▼
|
||||
Gateway (privileged, runs as operator)
|
||||
│ meta-creds.sh get <type> <id>
|
||||
│ decrypts store.age, never logs values
|
||||
▼
|
||||
CDP ──▶ accountscenter.meta.com
|
||||
(in the agent's chrome-box profile —
|
||||
same browser as the muse.ai session)
|
||||
```
|
||||
|
||||
- Transport: Unix socket IPC between agent and gateway (not network).
|
||||
- Injection: CDP `Runtime.evaluate` into the Accounts Center DOM; falls
|
||||
back to field-focus + virtual keyboard only if DOM injection fails.
|
||||
- 2FA during a write op: the gateway pauses, requests the code through the
|
||||
existing OTP handoff (human relays), resumes. The code is transient —
|
||||
used once, never stored.
|
||||
|
||||
## Registry
|
||||
|
||||
`ACCOUNTS.md` rows per Meta login, same discipline as today:
|
||||
`pending_auth` → `active`, `2fa-pending` where applicable. The `notes`
|
||||
column records the Accounts Center linkage (e.g. "facebook + instagram
|
||||
linked in one Accounts Center; blast radius = 2 accounts"). No credential
|
||||
values, no phone numbers.
|
||||
|
||||
## Change detection
|
||||
|
||||
`bin/meta-ac-snapshot.py` turns the smoke test into a change detector.
|
||||
Each run captures a structural snapshot via CDP inside the node's netns
|
||||
and diffs against `snapshots/meta-ac/baseline.json`:
|
||||
|
||||
- **redirect_chain** (normalized: query params stripped — nonces change
|
||||
every visit): seeded with the navigation target, then polls for where
|
||||
Meta sends us. Catches auth-flow reroutes.
|
||||
- **dom_markers**: form IDs, input names, button labels. Catches page
|
||||
restructures.
|
||||
- **final_title**: sanity signal.
|
||||
|
||||
Outcomes: `PASS` (matches), `CHANGED` (structural diff — baseline
|
||||
untouched, human reviews then `--promote`), `FAIL` (automation broke).
|
||||
Snapshots are timestamped JSON; the diff doubles as the audit trail for
|
||||
what Meta changed and when.
|
||||
|
||||
Validated 2026-10-03 on bl: headless Chromium in `warp-phone` netns via
|
||||
CDP reached accountscenter.meta.com → expected Meta auth redirect
|
||||
(auth.meta.com OIDC), login page renders. Baseline established; second
|
||||
run PASS.
|
||||
|
||||
## Out of scope (explicit)
|
||||
|
||||
- Posting, messaging, ad management, Page/Portfolio operations.
|
||||
- The phone-OTP / muse.ai flow (separate API, separate credentials —
|
||||
see `docs/PHONE-OTP.md`).
|
||||
- WhatsApp linking (not available in all regions; revisit later).
|
||||
- Business Suite / Partner access (different trust model; separate spec if
|
||||
needed).
|
||||
|
||||
## Open questions
|
||||
|
||||
1. Which NetVM node hosts Meta automation — new dedicated node, or reuse
|
||||
an existing client node? (Lean: dedicated `meta` node, one egress.)
|
||||
2. Should read ops also require the approvals flow for high-sensitivity
|
||||
accounts, or is operator-level enough?
|
||||
3. Recovery codes: store in `store.age` (retrievable) or human-only?
|
||||
|
||||
## Implementation status (2026-10-03)
|
||||
|
||||
**Read ops implemented** in bin/meta-acct.py + bin/meta-acct.sh:
|
||||
|
||||
- list-linked AGENT — linked profiles from account_overview. Returns
|
||||
email (if present), profiles array with name/type (instagram, ai_device).
|
||||
Verified on pip (1 Instagram + Muse) and 646 (Muse only, no email).
|
||||
- security-status AGENT — security checkup action count + section list
|
||||
from password_and_security.
|
||||
- login-activity AGENT — "Where you're logged in" section text.
|
||||
(Currently returns the section header; the expandable session list needs
|
||||
a click-through — future work.)
|
||||
|
||||
**Key finding:** the phone-OTP login for muse.ai leaves a full Meta session
|
||||
in the browser profile. accountscenter.meta.com loads without a login
|
||||
redirect. No separate Meta login needed — the agent profile IS the
|
||||
Accounts Center session.
|
||||
|
||||
**Usage:** runs inside the agent's netns via meta-acct.sh wrapper:
|
||||
|
||||
~/Projects/NetVM/bin/meta-acct.sh list-linked pip
|
||||
|
||||
Write ops (add-account, remove-account, etc.) remain human-gated per the
|
||||
spec above. Not yet implemented.
|
||||
Reference in New Issue
Block a user