> ## Documentation Index
> Fetch the complete documentation index at: https://plivo.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# SIP Authentication

> Secure inbound SIP calls to your Plivo applications and authenticate outbound calls to SIP providers

> [!NOTE]
>
> * **What:** Control who can place inbound SIP calls to your Plivo applications, and authenticate outbound calls to SIP providers that require credentials.
> * **When:** Assign an IP ACL, a SIP credential, or both to your Plivo Application.

SIP Authentication lets you secure your Plivo voice applications by controlling who can place inbound SIP calls and by authenticating outbound calls to SIP trunks that require credentials.

> [!WARNING]
>
> **Request-URI requirement:** For inbound SIP authentication to apply, the Request-URI of the INVITE must be `sip:{app_id}@app.plivo.com`. Plivo resolves the application from the Request-URI user part, not from the To header. If your SIP provider places a phone number in the Request-URI, configure the provider to send INVITEs to the application's SIP URI instead.

***

## Three Authentication Capabilities

| Capability | Direction | What It Does |
| - | - | - |
| **Inbound Authentication** | Inbound | Restrict who can call your Plivo app using IP-based access control, SIP digest credentials, or both |
| **Outbound Authentication (Dial XML)** | Outbound | Provide SIP credentials in your Dial XML so Plivo can authenticate with external SIP providers |
| **Outbound Authentication (Make Call API)** | Outbound | Same as above, but credentials are passed via the Make Call REST API instead of XML |

***

## Inbound Authentication

Inbound authentication protects your Plivo Application from unauthorized SIP calls. You configure it by assigning a credential, IP ACL, or both to your Application.

### Three Options

| Option | `sip_auth_type` | When to Use |
| - | - | - |
| **IP ACL only** | `ip_acl` | Calls only allowed from whitelisted IP addresses or CIDR ranges. Fastest — no challenge/response handshake. |
| **Credential only** | `credential` | Callers must authenticate with username/password via SIP digest auth (407 challenge). Use when source IPs are dynamic. |
| **Both (IP ACL + Credential)** | `ip_acl_and_credential` | Caller must pass both the IP check AND provide valid credentials. Maximum security. |

### How Inbound Authentication Works

```text theme={null}
Caller sends SIP INVITE to sip:{app_id}@app.plivo.com
   |
   v
Plivo resolves app from Request-URI user part
   |
   v
Plivo checks auth config for the app
   |
   |-- IP ACL configured?
   |     Check caller's IP against allowed list
   |     Not in list -> Call rejected (403)
   |
   |-- Credential configured?
   |     Send 407 Proxy Authentication Required
   |     Caller responds with digest credentials
   |     Wrong credentials -> Call rejected (403)
   |
   |-- Both configured?
   |     IP check first, then credential check
   |     Either fails -> Call rejected (403)
   |
   v
Authentication passed -> Call routed to your app's answer_url
```

### Setup Steps

**1. Create a credential and/or IP ACL**

Use the [SIP Authentication API](https://plivo.com/docs/account/api/sip-authentication.md) to create:

* A **SIP credential** with username and password (`POST /SipAuth/Credential/`)
* An **IP ACL** with a name (`POST /SipAuth/IpAccessControlList/`), then add IP entries (`POST /SipAuth/IpAccessControlList/{uuid}/Entry/`)

**2. Assign to your Application**

Update your Application via the [Application API](https://plivo.com/docs/account/api/application.md) by setting `sip_auth_type` and the corresponding `credential_uuid` and/or `ip_acl_uuid`.

**3. Test**

Make a test SIP call to your application's SIP URI (`sip:{app_id}@app.plivo.com`) and verify it succeeds with valid auth and fails without.

To confirm auth is running, check for the `SIPAuthType` parameter in your answer\_url callback (see Callback Parameters below).

### Callback Parameters

When authentication succeeds, your `answer_url` callback receives these additional parameters:

| Parameter | Description |
| - | - |
| `SIPAuthType` | Auth method used: `ip_acl`, `credential`, or `ip_acl_and_credential` |
| `SIPAuthUser` | Authenticated SIP username (credential auth only) |
| `SIPSourceIP` | The caller's source IP address |

If you don't see `SIPAuthType` in your callback, auth is not running. The most common cause is the SIP provider placing a phone number in the Request-URI instead of your app\_id — see the Warning at the top of this page.

### Rate Limiting and Lockout

To protect against brute-force attacks, Plivo enforces rate limiting on failed authentication attempts:

* Both IP ACL denials and credential denials increment the same per-source-IP failure counter.
* Once the counter crosses **10 failures**, every subsequent call from that IP is rejected with `403 Forbidden` for the remainder of the counter TTL.
* **Updating the IP ACL to include the locked-out IP does NOT clear an active lockout.** The IP stays locked until the counter TTL expires. This is by design.
* IP ACL changes propagate to the SIP edge within \~30 seconds (see FAQ below). During an active lockout, even a freshly allowed IP will be rejected until the counter expires.

***

## Outbound Authentication

When making outbound calls to SIP providers that require authentication (responds with 401/407 challenge), provide credentials so Plivo can complete the digest handshake on your behalf.

### Before You Start

Confirm with your SIP provider:

* **Username and password** for digest authentication
* **Whether they use IP-based auth instead** — if so, you don't need to pass credentials; instead ask the provider to whitelist [Plivo's media server IPs](https://plivo.com/docs/voice/concepts/firewall-network-configuration.md)
* **Realm** — Plivo handles realm matching automatically from the 407 response, so you generally don't need to configure this

### How Outbound Authentication Works

**1. Plivo sends INVITE**

Plivo sends a SIP `INVITE` to the destination (e.g., `sip:endpoint@provider.example.com`).

**2. Provider challenges**

Provider responds with `407 Proxy Authentication Required` (or `401 Unauthorized`).

**3. Plivo computes digest**

Plivo automatically computes the digest response using the credentials you provided.

**4. Plivo re-sends INVITE**

Plivo re-sends the `INVITE` with authentication headers.

**5. Call connects**

Provider accepts and the call connects. If authentication fails, the call ends with hangup cause `sip_auth_failed` (code `4240`).

### Option 1: Dial XML

Pass credentials on the `<User>` element in your answer URL XML:

```xml theme={null}
<Response>
    <Dial>
        <User sipAuthUsername="<sip_username>" sipAuthPassword="<sip_password>">
            sip:endpoint@provider.example.com
        </User>
    </Dial>
</Response>
```

### Option 2: Make Call API

Pass credentials when initiating an outbound call via the API:

```bash theme={null}
curl -X POST "https://api.plivo.com/v1/Account/<auth_id>/Call/" \
  -u '<auth_id>:<auth_token>' \
  -H "Content-Type: application/json" \
  -d '{
    "from": "+14155551234",
    "to": "sip:endpoint@provider.example.com",
    "answer_url": "https://example.com/answer.xml",
    "sip_auth_username": "<sip_username>",
    "sip_auth_password": "<sip_password>"
  }'
```

`sip_auth_username` and `sip_auth_password` are only accepted when `to` is a SIP URI.

### Use Case: Transfer to Human Agent

A common use case is transferring an AI-handled call to a human agent. The agent typically sits behind a softphone, contact center software, or PBX that requires SIP authentication. See [Transfer to Human Agent](https://plivo.com/docs/voice/use-cases/transfer-to-human-agent/sip-auth-forward.md) for the full workflow.

***

## Hangup Causes

When a call fails due to authentication, the CDR and hangup callback include a specific cause:

| HangupCauseName | Code | Direction | CallStatus | Meaning |
| - | - | - | - | - |
| `sip_auth_failed` | `4210` | Inbound | `failed` | Caller failed IP ACL or credential check |
| `sip_auth_failed` | `4240` | Outbound | `failed` | Provided credentials were rejected by the remote provider |
| `sip_auth_timeout` | `4250` | Outbound | `timeout` | Remote provider did not respond to the authentication attempt |

These values appear in the `HangupCauseName` / `PlivoHangupCause` fields. `CallStatus` stays within the standard set (`completed`, `busy`, `no-answer`, `failed`, `timeout`, `cancel`).

***

## Validation Limits

| Resource | Limit |
| - | - |
| IP ACLs per account | 100 |
| Credentials per account | 200 |
| Entries per IP ACL | 50 |
| Username | 3-64 characters. Allowed: letters, digits, `.`, `_`, `-` |
| Password | 8-128 characters. Must include at least one uppercase, one lowercase, and one digit |
| IP ACL name | Up to 120 characters |
| Entry description | Up to 255 characters |
| CIDR prefix | 0-32 |

***

## Reserved `sipHeaders` Prefixes

When using `sipHeaders` on `<User>` or `<Number>` elements within `<Dial>`, or via the Make Call API `sip_headers` parameter, customer-supplied header keys with the following prefixes (case-insensitive) are silently dropped to prevent impersonation of Plivo-internal headers:

`PH-`, `Plivo`, `FS-`, `SipAuth`, `ZT-`, `Twilio`

The exact name `ClientRegion` is also reserved.

### SIP Headers and Raw-Mode Rendering

When the inbound leg used SIP authentication, customer `sipHeaders` are emitted on the outbound B-leg INVITE **without** the `X-PH-` prefix. For example, `CustomerId=123` renders as `X-CustomerId: 123` rather than `X-PH-CustomerId: 123`. This raw-mode rendering is automatic when SIP auth is enabled on the inbound leg.

***

## Non-Auth Mode

When `sip_auth_type` is empty (no authentication configured), inbound SIP calls still require the calling endpoint to be a registered Plivo endpoint as the SIP From user. Calls from unknown From users are rejected with `486 Busy Here`.

***

## Security

Plivo treats SIP credentials with the same care as account credentials:

* Passwords are stored as one-way hashes (HA1) — never in plaintext
* Passwords are never returned in any API response
* SIP auth credentials are never included in CDR data or callback parameters
* Auth headers are stripped before forwarding calls externally
* Failed authentication attempts are rate-limited to prevent brute-force attacks
* All internal communication uses encrypted channels
* **Always use HTTPS for your answer\_url** — Plivo sends callback parameters (including `SIPAuthUser`) over HTTP to your server
* **Validate callbacks with `X-Plivo-Signature`** — verify that callbacks are genuinely from Plivo using [Signature Validation](https://plivo.com/docs/voice/concepts/signature-validation.md)
* **Beware of shared IPs** — if your SIP provider is on carrier-grade NAT or a shared-IP platform, IP ACL alone may not be sufficient. Use `ip_acl_and_credential` for defense in depth.
* **Monitor auth failures** — track `sip_auth_failed` hangup causes in your call logs to detect unauthorized access attempts

***

## Troubleshooting

| Symptom | Likely Cause | Fix |
| - | - | - |
| All calls get 403 Forbidden | IP not in ACL, or wrong credentials | Verify the caller's IP matches an ACL entry. For credentials, check username/password match exactly. |
| Calls succeed but no `SIPAuthType` in callback | Request-URI doesn't contain your app\_id | Configure your SIP provider to send INVITEs to `sip:{app_id}@app.plivo.com`, not to a phone number. |
| Digest auth fails (`sip_auth_failed`) despite correct credentials | Realm mismatch or provider uses a non-standard challenge | Plivo handles realm automatically. Contact the provider to confirm they send a standard 407/401 challenge. |
| All calls fail after working fine | Rate limit lockout (10 failures in 60s) | Wait 60 seconds for lockout to expire. Fix the underlying auth issue. |
| Outbound call fails with `sip_auth_failed` (code 4240) | Remote provider rejected your credentials | Verify username/password with the provider. Check if the provider uses IP auth instead of digest. |
| Outbound call fails with `sip_auth_timeout` (code 4250) | Remote provider didn't respond to the auth challenge | Provider may be unreachable. Check network connectivity and provider status. |

***

## End-to-End Examples

### Example 1: Secure inbound calls with IP whitelist

```bash theme={null}
# 1a. Create IP ACL
curl -X POST "https://api.plivo.com/v1/Account/<auth_id>/SipAuth/IpAccessControlList/" \
  -u '<auth_id>:<auth_token>' \
  -H "Content-Type: application/json" \
  -d '{"name": "Office Network"}'
# Response: {"ip_acl_uuid": "acl-abc123"}

# 1b. Add an entry
curl -X POST "https://api.plivo.com/v1/Account/<auth_id>/SipAuth/IpAccessControlList/acl-abc123/Entry/" \
  -u '<auth_id>:<auth_token>' \
  -H "Content-Type: application/json" \
  -d '{"ip": "198.51.100.5", "cidr_prefix": 32, "description": "Remote PBX"}'

# 2. Assign to app
curl -X POST "https://api.plivo.com/v1/Account/<auth_id>/Application/<app_id>/" \
  -u '<auth_id>:<auth_token>' \
  -H "Content-Type: application/json" \
  -d '{"sip_auth_type": "ip_acl", "ip_acl_uuid": "acl-abc123"}'

# 3. Call from allowed IP -> connects
# 4. Call from other IP -> 403 Forbidden
```

### Example 2: Secure inbound calls with digest credentials

```bash theme={null}
# 1. Create credential
curl -X POST "https://api.plivo.com/v1/Account/<auth_id>/SipAuth/Credential/" \
  -u '<auth_id>:<auth_token>' \
  -H "Content-Type: application/json" \
  -d '{"username": "pbx-user", "password": "<your_password>"}'
# Response: {"credential_uuid": "cred-def456"}

# 2. Assign to app
curl -X POST "https://api.plivo.com/v1/Account/<auth_id>/Application/<app_id>/" \
  -u '<auth_id>:<auth_token>' \
  -H "Content-Type: application/json" \
  -d '{"sip_auth_type": "credential", "credential_uuid": "cred-def456"}'

# 3. Configure your PBX/SIP client with username "pbx-user" and password from step 1
# 4. Call -> 407 challenge -> PBX responds with credentials -> call connects
```

### Example 3: Outbound call to an authenticated SIP trunk

```bash theme={null}
curl -X POST "https://api.plivo.com/v1/Account/<auth_id>/Call/" \
  -u '<auth_id>:<auth_token>' \
  -H "Content-Type: application/json" \
  -d '{
    "from": "+14155551234",
    "to": "sip:+14155559999@trunk.provider.com",
    "answer_url": "https://example.com/answer.xml",
    "sip_auth_username": "<sip_username>",
    "sip_auth_password": "<sip_password>"
  }'
```

Or via Dial XML in your answer URL:

```xml theme={null}
<Response>
    <Dial>
        <User sipAuthUsername="<sip_username>" sipAuthPassword="<sip_password>">
            sip:+14155559999@trunk.provider.com
        </User>
    </Dial>
</Response>
```

***

## FAQ

***

### Can I use both IP ACL and credential auth together?

Yes. Set `sip_auth_type` to `ip_acl_and_credential`. The caller must pass the IP check AND provide valid credentials.

***

### What happens if I delete a credential or IP ACL that's assigned to an app?

The API returns a 400 error. You must first remove the assignment from the application by setting `sip_auth_type` to empty (`""`).

***

### Can I update the password on an existing credential?

Yes. Send a `POST` to the credential's URL with just the `password` field. The username remains unchanged. The change takes effect immediately for all applications using that credential.

***

### What realm is used for digest authentication?

The default realm is `app.plivo.com`. This is included in the 407 challenge response. Plivo handles realm matching automatically during the handshake.

***

### Can I set different auth for different apps?

Yes. Each application has its own `sip_auth_type`, `ip_acl_uuid`, and `credential_uuid` configuration. You can reuse the same credential or IP ACL across multiple apps.

***

### Does changing an IP ACL take effect immediately?

No. Changes propagate to the SIP edge within \~30 seconds. During that window, calls may still match the previous ruleset.

***

### Can I use a hostname in an IP ACL?

No. IP ACL entries require a valid IPv4 address. Hostnames are not supported.

***

### Can one app have multiple IP ACLs?

No. Each application can have at most one IP ACL and one credential assigned. To allow multiple IP ranges, add multiple entries to a single ACL (up to 50 entries).

***

### What's the latency impact of SIP authentication?

IP ACL adds negligible latency (simple lookup). Credential auth adds one round-trip for the 407 challenge/response (typically under 50ms on well-connected networks).

***

### Can I rotate a password without call interruption?

Yes. Update the password on the credential via the API, then update your SIP client with the new password. There may be a brief window where calls using the old password fail.

***

## Related

* [SIP Authentication API](https://plivo.com/docs/account/api/sip-authentication.md) — Manage credentials and IP ACLs
* [Application API](https://plivo.com/docs/account/api/application.md) — Assign auth to your application
* [Voice API: Make a Call](https://plivo.com/docs/voice/api/calls.md) — Outbound auth via REST API
* [Dial XML](https://plivo.com/docs/voice/xml/routing.md#dial/) — Outbound auth via XML
* [Firewall & Network Configuration](https://plivo.com/docs/voice/concepts/firewall-network-configuration.md) — Plivo media server IPs
* [Signature Validation](https://plivo.com/docs/voice/concepts/signature-validation.md) — Verify callbacks are from Plivo
* [Connect External Numbers](https://plivo.com/docs/voice/use-cases/connect-external-numbers.md) — Route external numbers via SIP
* [Transfer to Human Agent](https://plivo.com/docs/voice/use-cases/transfer-to-human-agent.md) — Handoff AI calls to humans
