# Regulatory Headers

> STIR/SHAKEN, P-Asserted-Identity, and PIDF-LO geolocation.

The FirstByte gateway can add to every outbound SIP INVITE the
regulatory headers that US/EU PSTN carriers require. The SDK does not
expose these headers as options. You configure them on the trunk
([`AddTrunk`](/admin/trunks)). The gateway then applies them
automatically to calls on that trunk.

## STIR/SHAKEN

The gateway signs outbound calls with a PASSporT JWT (RFC 8224 / 8225)
and attaches it as an `Identity` header. A typical signed INVITE looks
like:

```
INVITE sip:+15551234567@carrier.example;user=phone SIP/2.0
From: "ACME Support" <sip:+18005550100@firstbyte.fast>;tag=…
To: <sip:+15551234567@carrier.example>
Identity: eyJhbGciOiJFUzI1NiIsInR5cCI6InBhc3Nwb3J0Iiwic
 HBjIjoic2hha2VuIiwieDV1IjoiaHR0cHM6Ly9jZXJ0LmV4YW1wbG
 UvY2VydHMvc3RpL3RuIn0.eyJhdHRlc3QiOiJBIiwiZGVzdCI6eyJ0
 biI6WyIxNTU1MTIzNDU2NyJdfSwiaWF0IjoxNzM0MDAwMDAwLCJvcm
 lnIjp7InRuIjoiMTgwMDU1NTAxMDAifSwib3JpZ2lkIjoiYWNtZS0
 yMDI2LTA0In0.<sig>;info=<https://cert.firstbyte.fast/sti.pem>;alg=ES256;ppt=shaken
```

The PASSporT `attest` value is the trunk's configured **attestation
level**:

| Attest | Meaning                                                          |
| ------ | ---------------------------------------------------------------- |
| `A`    | Full attestation — the caller has a verified relationship with the calling number. |
| `B`    | Partial attestation — the caller is known, but the number is not directly verified. |
| `C`    | Gateway attestation — the gateway routes the call, but the origin is unverified. |

Set the per-trunk default through `AddTrunk` extras. For tenants on
shared infrastructure, set it in the gateway's deployment config. The
gateway reads the signing certificate (`x5u` URL) from `cert_path`.
Rotate it via [`ReloadCertificates`](/admin/certificates).

The gateway validates inbound SIP INVITEs symmetrically. It checks the
`Identity` header against the published `x5u` cert. The result shows in
the `CallEvent.status` string (`STIR_VERIFIED`, `STIR_FAILED`,
`STIR_MISSING`).

## P-Asserted-Identity (PANI)

For carrier interconnects that prefer PANI over STIR, the gateway also
sends an [RFC 3325](https://datatracker.ietf.org/doc/html/rfc3325)
`P-Asserted-Identity` header that carries the verified caller-id:

```
P-Asserted-Identity: <sip:+18005550100@firstbyte.fast>
Privacy: none
```

PANI is mutually exclusive with `Privacy: id`. The gateway switches
automatically if the SDK's `OriginateRequest` flags the call as
caller-id-restricted.

## PIDF-LO geolocation

For E911-style emergency routing, the gateway can attach a Presence
Information Data Format — Location Object (RFC 4119, RFC 5491). It
attaches the object as a SIP body part. Configure it on the trunk:

```yaml
# trunk extras (set via AddTrunk extras field or platform config)
geolocation:
  default_civic_address:
    country: US
    region:  CA
    city:    San Francisco
    street:  1 Market Street
    postal:  94105
  geo_priv_routing: emergency
```

The resulting `multipart/mixed` INVITE body:

```
--boundary
Content-Type: application/sdp

v=0
o=… …
s=…
…

--boundary
Content-Type: application/pidf+xml

<?xml version="1.0" encoding="UTF-8"?>
<presence xmlns="urn:ietf:params:xml:ns:pidf"
          xmlns:gp="urn:ietf:params:xml:ns:pidf:geopriv10"
          xmlns:cl="urn:ietf:params:xml:ns:pidf:geopriv10:civicAddr">
  <tuple id="loc">
    <status>
      <gp:geopriv>
        <gp:location-info>
          <cl:civicAddress>
            <cl:country>US</cl:country>
            <cl:A1>CA</cl:A1>
            <cl:A3>San Francisco</cl:A3>
            <cl:A6>Market Street</cl:A6>
            <cl:HNO>1</cl:HNO>
            <cl:PC>94105</cl:PC>
          </cl:civicAddress>
        </gp:location-info>
        <gp:usage-rules>
          <gp:retransmission-allowed>no</gp:retransmission-allowed>
          <gp:retention-expires>2026-04-26T12:00:00Z</gp:retention-expires>
        </gp:usage-rules>
      </gp:geopriv>
    </status>
    <timestamp>2026-04-26T11:00:00Z</timestamp>
  </tuple>
</presence>

--boundary--
```

A SIP `Geolocation` header points at the `cid:` of the PIDF-LO part.
The gateway also adds `Geolocation-Routing: yes` for emergency-routing
carriers.

## Per-call overrides

The standard `OriginateRequest` does not carry any of these fields.
This is deliberate: SDK callers must not set regulated metadata ad hoc.
Sometimes you must override the trunk default for a single call (for
example, a softphone that roams to a different civic address). In that
case, use `ExecuteDialplan` with action `ANSWER`. Supply the override
via `app_args` as a JSON blob:

```json
{
  "geolocation": {
    "civic_address": {
      "country": "US",
      "region":  "NY",
      "city":    "New York",
      "street":  "350 Fifth Avenue",
      "postal":  "10118"
    }
  }
}
```

The gateway applies the override before the INVITE leaves the wire.

## Disabling

In lab / development environments, regulatory headers can cause noise
in test SBCs. There, set `regulatory.enabled: false` in the gateway
config. **Do not disable this in production.** Most carriers silently
degrade calls without a valid `Identity` header. The call gets lower
attestation and shows as "Spam Likely" on receiving handsets.
