openclaw-mfa-gate
v2.0.1
Published
Mist channel adapter — routes OpenClaw approvals through AirVaults mobile app
Maintainers
Readme
Mist Channel — AirVaults MFA for OpenClaw
Routes OpenClaw approval requests through the AirVaults mobile app. When OpenClaw's built-in approval engine flags a risky action, the approval request flows through the mist channel to your phone — you tap approve or deny, and the decision is injected back into OpenClaw.
How It Works
User runs risky command in OpenClaw
-> OpenClaw approval engine detects risk
-> Sends approval request to mist channel (outbound.sendText)
-> mist-channel.js parses approval ID
-> Creates challenge: POST /api/v2/mfa_vaults/:uid/challenge (PENDING)
-> Polls: GET /api/v2/mfa_vaults/:uid/challenge/:id
-> Mobile app sees pending challenge, user taps approve/deny
-> Mobile app: POST /api/v2/mfa_vaults/:uid/challenge/:id/respond
-> Poll returns decision
-> mist-channel.js injects /approve or /deny back into OpenClaw
-> OpenClaw executes or blocks the actionInstallation
openclaw plugins install openclaw-mfa-gate
openclaw gateway restartOr run the setup wizard standalone via npx:
npx openclaw-mfa-gateVerify:
openclaw plugins list
# Should show: Mist Channel (AirVaults MFA) — loaded — v2.0.0Managing the plugin
openclaw plugins info openclaw-mfa-gate # Show details
openclaw plugins disable openclaw-mfa-gate # Disable (keeps files)
openclaw plugins enable openclaw-mfa-gate # Re-enableSetup (QR Onboarding)
Generate QR code:
openclaw mfaOr in chat: use the
mfa_setuptool.Scan QR with AirVaults mobile app — the app creates an MFA vault.
Copy the binding key the app shows (
mfa:bind:vault_uid:access_token).Bind — send the key via the
mfa_bindtool or paste it in any OpenClaw channel.Restart the gateway. The mist channel is now active.
Configuration
Config is stored in config/mfa-config.json (auto-saved by mfa_bind):
{
"enabled": true,
"instanceId": "oc_abc123...",
"vaultUid": "v12345...",
"accessToken": "abc123...",
"apiBaseUrl": "http://localhost:3000",
"pollIntervalMs": 500,
"pollTimeoutMs": 120000
}Or configure via openclaw.json under plugins.entries.openclaw-mfa-gate.
Tools
| Tool | Description |
| ------------ | ---------------------------------------- |
| mfa_setup | Generate QR code for mobile app binding |
| mfa_bind | Bind vault with key from mobile app |
| mfa_status | Check vault status and recent challenges |
CLI
Via OpenClaw:
openclaw mfa # Setup wizard with QR code
openclaw mfa --api-url URL # Custom API URL
openclaw mfa --name NAME # Custom instance nameStandalone via npx:
npx openclaw-mfa-gate # Setup wizard (default)
npx openclaw-mfa-gate status # Check vault status
npx openclaw-mfa-gate bind <key> # Manual bind
npx openclaw-mfa-gate --help # HelpAPI Endpoints
| Method | Endpoint | Description |
| ------ | ----------------------------------------------- | -------------------------- |
| POST | /api/v2/mfa_vaults | Create MFA vault |
| POST | /api/v2/mfa_vaults/:uid/bind | Bind instance |
| POST | /api/v2/mfa_vaults/:uid/challenge | Create challenge (pending) |
| GET | /api/v2/mfa_vaults/:uid/challenge/:id | Poll challenge status |
| POST | /api/v2/mfa_vaults/:uid/challenge/:id/respond | Approve/deny challenge |
| GET | /api/v2/mfa_vaults/:uid/pending_challenges | List pending challenges |
| GET | /api/v2/mfa_vaults/:uid/status | Vault status |
Architecture
This plugin is a pure channel adapter. It does not detect risky actions — that's OpenClaw's job. The plugin only:
- Receives approval requests from OpenClaw's approval engine
- Creates challenges in the AirVaults API
- Polls until the mobile app user responds
- Injects
/approveor/denyback into OpenClaw
No WebSocket, no hooks, no risk classification. Just HTTP polling.
License
MIT
