{"id":7502,"plugin_id":"Plugin_c266c85897248191be15eb07c415f89e","kind":"skill","collection_source":null,"comparison_source":null,"observed_at":"2026-09-30T22:50:44.451Z","digest":"d068489f3c1a295d259ed9670b5ff873bafb200203b642ede12dc036fd71fbe8","against":null,"payload":{"name":"twilio-iam-auth-setup","description":"Set up and manage Twilio authentication credentials: Auth Tokens, API keys (Standard, Main, Restricted), Access Tokens for client-side SDKs, and credential rotation. Use this skill as a prerequisite foundation before making any Twilio API calls.","included_files":[{"relative_path":"agents/openai.yaml","size_in_bytes":223}],"skill_md_contents":"---\nname: twilio-iam-auth-setup\ndescription: >\n  Set up and manage Twilio authentication credentials: Auth Tokens, API keys\n  (Standard, Main, Restricted), Access Tokens for client-side SDKs, and\n  credential rotation. Use this skill as a prerequisite foundation before\n  making any Twilio API calls.\n---\n\n## Overview\n\nTwilio supports multiple authentication methods. For most developers: use Auth Token for local prototyping, then move to API Keys in production.\n\n| Method | Use for | Security |\n|--------|---------|----------|\n| Account SID + Auth Token | Local prototyping, initial testing | Full account access — avoid in production |\n| Account SID + API Key (Standard) + Secret | All production code | Recommended — revocable, no access to /Accounts or /Keys |\n| Account SID + API Key (Restricted) + Secret | Fine-grained production access | Best — limit to specific resources only |\n| Account SID + API Key (Main) + Secret | Account management automation | Full access like Auth Token, but revocable |\n\n**For beginners / vibe-coders:** Start with Auth Token to get your first API call working, then create a Standard API Key before deploying anything. The key difference: if an API Key leaks, you revoke just that key. If your Auth Token leaks, your entire account is exposed until you rotate it.\n\n---\n\n## Prerequisites\n\n- Twilio account — see `twilio-account-setup` if you don't have one\n- Access to the [Twilio Console](https://console.twilio.com)\n\n---\n\n## Quickstart\n\nFind your Account SID and Auth Token in the Console dashboard.\n\n**Python**\n```python\nimport os\nfrom twilio.rest import Client\n\nclient = Client(os.environ[\"TWILIO_ACCOUNT_SID\"], os.environ[\"TWILIO_AUTH_TOKEN\"])\n```\n\n**Node.js**\n```node\nconst client = require(\"twilio\")(\n    process.env.TWILIO_ACCOUNT_SID,\n    process.env.TWILIO_AUTH_TOKEN\n);\n```\n\n**Never commit Auth Token to version control or use in production.**\n\n---\n\n## Key Patterns\n\n### API Keys (production)\n\n**Create:** Console > Account > API keys & tokens > Create API key\n\n| Key type | Access | Use case |\n|----------|--------|----------|\n| **Standard** | All resources except /Accounts and /Keys endpoints | Default for production apps |\n| **Restricted** | Only the specific resources you grant | Multi-tenant apps, microservices, least-privilege |\n| **Main** | Full account access (like Auth Token) | Account management automation (Console-only creation) |\n\nAfter creation, copy the **API Key SID** (`SK...`) and **Secret** — the secret is shown only once.\n\n**Python**\n```python\nclient = Client(\n    os.environ[\"TWILIO_API_KEY\"],      # SK...\n    os.environ[\"TWILIO_API_SECRET\"],\n    os.environ[\"TWILIO_ACCOUNT_SID\"]   # required as third argument\n)\n```\n\n**Node.js**\n```node\nconst client = require(\"twilio\")(\n    process.env.TWILIO_API_KEY,\n    process.env.TWILIO_API_SECRET,\n    { accountSid: process.env.TWILIO_ACCOUNT_SID }\n);\n```\n\n### Restricted API Keys\n\nRestricted keys grant access only to specific Twilio API resources you define. Use them for least-privilege access in production.\n\n**Create via the v1 IAM API** (not the v2010 /Keys.json endpoint — see CANNOT section):\n\n**Python**\n```python\nkey = client.iam.v1.api_key.create(\n    account_sid=os.environ[\"TWILIO_ACCOUNT_SID\"],\n    friendly_name=\"messaging-only-key\",\n    key_type=\"restricted\",\n    policy={\n        \"allow\": [\n            \"/2010-04-01/Accounts/{AccountSid}/Messages*\"\n        ]\n    }\n)\n# Store key.sid and key.secret securely — secret shown only once\n```\n\n**Example permission patterns:**\n| Permission | Grants access to |\n|-----------|-----------------|\n| `/2010-04-01/Accounts/{AccountSid}/Messages*` | Send and read messages |\n| `/2010-04-01/Accounts/{AccountSid}/Calls*` | Make and manage calls |\n| `/v2/Services/*/Verifications*` | Verify API only |\n\n**Docs:** [Restricted API keys](https://www.twilio.com/docs/iam/api-keys/restricted-api-keys)\n\n### Test Credentials\n\nMake API calls without charges or sending real messages. Find at Console > Account > API keys & tokens > Test credentials.\n\n**Python**\n```python\nclient = Client(\n    os.environ[\"TWILIO_TEST_ACCOUNT_SID\"],\n    os.environ[\"TWILIO_TEST_AUTH_TOKEN\"]\n)\n```\n\n**Node.js**\n```node\nconst client = require(\"twilio\")(\n    process.env.TWILIO_TEST_ACCOUNT_SID,\n    process.env.TWILIO_TEST_AUTH_TOKEN\n);\n```\n\nMagic test numbers:\n- `+15005550006` — valid, can receive messages\n- `+15005550001` — invalid number (triggers error 21211)\n- `+15005550007` — number that cannot receive SMS (triggers error 21612)\n\n### Auth Token Rotation\n\nRotate your Auth Token if it's been exposed or as periodic security hygiene. Twilio uses a **secondary token promotion** model:\n\n1. Console > Account > API keys & tokens > Request a secondary Auth Token\n2. Update your application to use the secondary token\n3. Once confirmed working, promote the secondary to primary\n4. The old primary token is immediately invalidated\n\n**Python**\n```python\n# Promote secondary Auth Token to primary via API\nfrom twilio.rest import Client\n\nclient = Client(os.environ[\"TWILIO_ACCOUNT_SID\"], os.environ[\"TWILIO_AUTH_TOKEN\"])\naccount = client.api.accounts(os.environ[\"TWILIO_ACCOUNT_SID\"]).update(\n    auth_token_promotion=\"promote\"\n)\n```\n\n**Important:** Auth Token rotation invalidates all active sessions using that token. Plan the switchover to minimize downtime.\n\n**API Keys cannot be rotated** — if an API Key is compromised, delete it and create a new one:\n- Console > Account > API keys & tokens > select key > Delete\n- Or via API: `client.keys(key_sid).delete()`\n\n**Docs:** [Auth Token REST API](https://www.twilio.com/docs/iam/api/authtoken)\n\n### Access Tokens (client-side SDKs)\n\nShort-lived JWTs for authenticating browser/mobile clients (Voice JS SDK, Conversations SDK, Video SDK). Generate server-side and pass to the client.\n\n**Python**\n```python\nfrom twilio.jwt.access_token import AccessToken\nfrom twilio.jwt.access_token.grants import VoiceGrant\n\ntoken = AccessToken(\n    os.environ[\"TWILIO_ACCOUNT_SID\"],\n    os.environ[\"TWILIO_API_KEY\"],\n    os.environ[\"TWILIO_API_SECRET\"],\n    identity=\"user-123\",\n    ttl=3600\n)\ntoken.add_grant(VoiceGrant(outgoing_application_sid=\"APxxxx\"))\nprint(token.to_jwt())\n```\n\n**Node.js**\n```node\nconst { AccessToken } = require(\"twilio\").jwt;\nconst { VoiceGrant } = AccessToken;\n\nconst token = new AccessToken(\n    process.env.TWILIO_ACCOUNT_SID,\n    process.env.TWILIO_API_KEY,\n    process.env.TWILIO_API_SECRET,\n    { identity: \"user-123\", ttl: 3600 }\n);\ntoken.addGrant(new VoiceGrant({ outgoingApplicationSid: \"APxxxx\" }));\nconsole.log(token.toJwt());\n```\n\nAvailable grant types: `VoiceGrant`, `VideoGrant`, `ChatGrant` (Conversations), `SyncGrant`\n\n### Environment Variable Reference\n\n```bash\nTWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n\n# Option 1: Auth Token (testing only)\nTWILIO_AUTH_TOKEN=your_auth_token\n\n# Option 2: API Key (production)\nTWILIO_API_KEY=SKxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\nTWILIO_API_SECRET=your_api_secret\n\n# Test credentials\nTWILIO_TEST_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\nTWILIO_TEST_AUTH_TOKEN=your_test_auth_token\n```\n\n---\n\n## CANNOT\n\n- **Standard keys cannot access /Accounts or /Keys endpoints** — Returns error 20003 (401). Must use Auth Token or Main API Key for account management.\n- **No restricted key creation via v2010 API** — The v2010 `/Keys.json` endpoint silently ignores `KeyType=restricted` and `Policy` parameters, creating a standard key instead. Use the v1 IAM API.\n- **Restricted keys cannot generate Access Tokens** — Only Standard and Main keys can create client SDK tokens.\n- **No individual Access Token revocation** — Tokens are valid until expiration (max 24h). To revoke early, delete the API key that issued them.\n- **Subaccount credentials cannot access parent or sibling resources** — Each subaccount has its own Auth Token and API Keys. Use the subaccount's own credentials to access its resources — never the parent account's credentials.\n- **API Keys cannot be rotated** — No key rotation API exists. To replace a compromised key: create a new key, update your app, then delete the old key.\n- **PKCV is an advanced feature for compliance-heavy industries** — Public Key Client Validation adds client-certificate-style auth. Incompatible with Flex, Studio, and TaskRouter. Once enforcement is enabled, Auth Token authentication is disabled (one-way door). See [PKCV docs](https://www.twilio.com/docs/iam/pkcv) — consider this only if your security team requires mutual TLS-equivalent authentication.\n- **Test credentials work with only 4 endpoints** — Messages, Calls, IncomingPhoneNumbers, and Lookups. All other endpoints return 403.\n- **API Key Secret shown only at creation** — Cannot be retrieved afterward. If lost, create a new key.\n- **FriendlyName max 64 characters for keys** — 65+ characters returns error 70001.\n- **Restricted keys limited to 100 permissions per key** — Exceeding this limit is rejected at creation.\n- **Cannot create Main API Keys via REST API** — Console only\n- **Cannot set Access Token TTL beyond 24 hours** — Maximum lifetime is 24h\n- **Cannot use test credentials with real numbers** — Test credentials only work with test magic numbers\n\n---\n\n## Next Steps\n\n- **Account setup and phone numbers:** `twilio-account-setup`\n- **Security best practices (credential management, key rotation):** `twilio-security-hardening`\n- **Restricted API keys (fine-grained permissions):** [Docs](https://www.twilio.com/docs/iam/api-keys/restricted-api-keys)\n- **Auth Token rotation:** [REST API](https://www.twilio.com/docs/iam/api/authtoken)\n"},"changes":[],"summary":"First saved snapshot. No earlier version is available for comparison.","summary_kind":"deterministic","summary_metadata":{}}