Choose the right Twilio authentication method and implement it correctly. Covers Auth Token (testing only), API Keys (production standard), OAuth2 client_credentials (time-limited bearer tokens), Access Tokens (client-side SDKs), and test credentials. Use this skill before making any Twilio API calls in production.
70
86%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Twilio supports four authentication methods. Choosing the wrong one is a security risk — Auth Tokens in production code are the most common credential leak.
| Method | Use for | Token lifetime | Revocable individually |
|---|---|---|---|
| Auth Token | Local testing only | Permanent (until rotated) | No — rotation breaks ALL API keys |
| API Key + Secret | Production server-side | Permanent (until deleted) | Yes |
| OAuth2 Bearer Token | Production server-side (enhanced) | 1 hour | Expires automatically |
| Access Token (JWT) | Client-side SDKs (Voice, Video, Chat) | Up to 24 hours | No — delete issuing API key |
Decision framework:
Create: Console → Account → API keys & tokens → Create API key
| Key type | Access | Create via |
|---|---|---|
| Main | Full account access | Console only |
| Standard | All resources except /Accounts and /Keys endpoints | Console or API |
| Restricted | Specific resources only (up to 100 permissions) | Console or v1 IAM API only |
Python
import os
from twilio.rest import Client
client = Client(
os.environ["TWILIO_API_KEY"], # SKxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
os.environ["TWILIO_API_SECRET"],
os.environ["TWILIO_ACCOUNT_SID"] # required as third argument
)Node.js
const client = require("twilio")(
process.env.TWILIO_API_KEY,
process.env.TWILIO_API_SECRET,
{ accountSid: process.env.TWILIO_ACCOUNT_SID }
);Time-limited bearer tokens that expire after 1 hour. More secure than permanent API keys for server-to-server communication.
Create an OAuth App in the Twilio Console to get a Client ID and Client Secret.
cURL
curl -X POST 'https://oauth.twilio.com/v2/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'client_id={ClientID}' \
-d 'client_secret={ClientSecret}' \
-d 'grant_type=client_credentials'Response:
{
"access_token": "{BearerToken}",
"token_type": "Bearer",
"expires_in": 3600
}curl 'https://api.twilio.com/2010-04-01/Accounts/{AccountSID}/Messages.json' \
-H 'Authorization: Bearer {BearerToken}'OAuth2 is supported in all Twilio SDKs:
| Language | Minimum version |
|---|---|
| Java | 10.6.0 |
| C#/.NET | 7.6.0 |
| Node.js | 5.4.0 |
| Python | 9.4.1 |
| Ruby | 7.4.0 |
| PHP | 8.5.0 |
| Go | 1.25.1 |
Docs: OAuth access tokens | Segment OAuth connections
Short-lived JWTs for authenticating browser/mobile clients. Generate server-side, pass to the client.
Python
from twilio.jwt.access_token import AccessToken
from twilio.jwt.access_token.grants import VoiceGrant
token = AccessToken(
os.environ["TWILIO_ACCOUNT_SID"],
os.environ["TWILIO_API_KEY"],
os.environ["TWILIO_API_SECRET"],
identity="user-123",
ttl=3600
)
token.add_grant(VoiceGrant(outgoing_application_sid="APxxxx"))
print(token.to_jwt())Grant types: VoiceGrant, VideoGrant, ChatGrant (Conversations), SyncGrant
Make API calls without charges. Find at Console → Account → API keys & tokens → Test credentials.
Magic numbers: +15005550006 (valid), +15005550001 (invalid, error 21211), +15005550007 (no SMS, error 21612)
client_credentials grant — No refresh tokens, no authorization code flow.twilio-account-setuptwilio-security-compliance-hipaatwilio-webhook-architecturetwilio-security-hardening11c74d6
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.