Skill: diegofcornejo/totp (version 1.0.2)

--- name: totp description: TOTP-based OTP verification for sensitive operations (env vars, gateway restarts, backup deletions, critical config changes). Uses otplib with window:2 (1 minute tolerance). metadata: { "openclaw": { "requires": { "env": ["TOTP_SECRET"], "bins": ["node"] }, "primaryEnv": "TOTP_SECRET", "emoji": "🔐" } } --- # TOTP Verification Skill Secure OTP verification using TOTP (Time-based One-Time Password) for sensitive operations. ## Purpose Protect access to: - `.env` variables - `openclaw.json` configuration - Gateway restarts - Backup deletions - Critical configuration changes - External API key operations ## Setup 1. **Install dependencies:** ```bash npm install ``` 2. **Generate secret and QR:** ```bash npm run generate ``` Optionally pass service and account name: ```bash node scripts/generate-secret.js MyService myuser ``` 3. **Send the QR image** (`qr.png`) to the user, then delete it immediately: ```bash rm qr.png ``` 4. **Set TOTP_SECRET in `.env`:** ```env TOTP_SECRET=YOUR_BASE32_SECRET_HERE ``` 5. **Configure Google Authenticator/Authy** with the generated secret or QR. ## Usage When a sensitive operation is requested: 1. **Agent:** "Please provide your OTP" 2. **User:** Provides 6-digit code from authenticator app 3. **Agent:** Runs verification: ```bash TOTP_SECRET=$TOTP_SECRET node scripts/verify.js 123456 ``` 4. **If valid (exit 0):** Proceed with operation 5. **If invalid (exit 1):** Deny access ## Files - `scripts/generate-secret.js` - Generate new TOTP secret and QR - `scripts/verify.js` - Verify OTP tokens (window:2 = 1 minute tolerance) - `SKILL.md` - This documentation ## Security Notes - **Window:** 2 (1 minute tolerance) for time drift - **Algorithm:** SHA1 - **Digits:** 6 - **Period:** 30 seconds - **Secret:** Base32 encoded, stored in `.env` as `TOTP_SECRET` ## Integration This skill should be integrated into the agent's decision flow when: 1. User requests `.env` variables 2. User requests `openclaw.json` contents 3. User requests gateway restart 4. User requests backup deletion 5. Any operation marked as "critical"

path: package.json
content: {
  "name": "totp-skill",
  "version": "1.0.2",
  "description": "TOTP OTP verification for OpenClaw sensitive operations",
  "scripts": {
    "generate": "node scripts/generate-secret.js",
    "verify": "node scripts/verify.js",
    "zip": "zip -r totp-skill.zip SKILL.md scripts/ package.json"
  },
  "dependencies": {
    "@otplib/preset-default": "12.0.1",
    "qrcode": "1.5.3"
  },
  "keywords": ["totp", "otp", "security", "verification", "openclaw"],
  "license": "MIT"
}


path: scripts/generate-secret.js
content: #!/usr/bin/env node
// Generate new TOTP secret and QR code image
const path = require('path');
const { authenticator } = require('@otplib/preset-default');
const QRCode = require('qrcode');

const service = process.argv[2] || 'OpenClaw';
const account = process.argv[3] || 'admin';

// Generate new secret (base32)
const [REDACTED_SECRET]);
const otpauth = authenticator.keyuri(account, service, secret);
const qrPath = path.join(__dirname, '..', 'qr.png');

QRCode.toFile(qrPath, otpauth, { type: 'png', width: 200, margin: 2 }, (err) => {
  if (err) {
    console.error('Failed to generate QR image:', err.message);
    process.exit(1);
  }

  console.log('New TOTP_SECRET:');
  console.log(secret);
  console.log(`\nQR code saved to: ${qrPath}`);
  console.log('\nManual setup:');
  console.log('1. Open Google Authenticator/Authy');
  console.log('2. Tap "+" > "Enter a setup key"');
  console.log(`3. Account: ${account}`);
  console.log('4. Key:', secret);
  console.log('5. Type: Time-based (TOTP)');
  console.log('\nAdd this line to your .env:');
  console.log(`TOTP_SECRET=${secret}`);
});


path: scripts/verify.js
content: #!/usr/bin/env node
// Verify TOTP OTP tokens
const { authenticator } = require('@otplib/preset-default');

// Use window 2 (1 minute tolerance)
authenticator.options = { window: 2 };

const [REDACTED_SECRET];
const [REDACTED_SECRET];

if (!secret) {
	console.error('Error: TOTP_SECRET not set in environment');
	process.exit(1);
}

if (!token) {
	console.error('Usage: node verify.js <6-digit-token>');
	console.error('   Or: TOTP_SECRET=secret node verify.js <token>');
	process.exit(1);
}

const verified = authenticator.verify({ token, secret });

if (verified) {
	console.log('OTP_VALID');
	process.exit(0);
} else {
	console.log('OTP_INVALID');
	process.exit(1);
}


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (MEDIUM)