@gibme/stir-shaken
    Preparing search index...

    @gibme/stir-shaken

    @gibme/stir-shaken

    NPM License Node.js

    STIR/SHAKEN caller ID attestation and call signing for Node.js with built-in Asterisk AGI server integration and Iconectiv API support.

    STIR/SHAKEN (Secure Telephone Identity Revisited / Signature-based Handling of Asserted information using toKENs) is a framework that cryptographically verifies the legitimacy of the calling party and their authorization to use a particular telephone number, helping prevent caller ID spoofing and robocall fraud.

    This package provides:

    • AGI Server for automatic STIR/SHAKEN call signing in Asterisk PBX systems
    • Identity header generation using ES256-signed JWTs
    • Iconectiv API client for SPC token provisioning, CRL retrieval, and CA trust list management
    • Service Provider Code (SPC) ASN.1 DER encoding and decoding
    • ECDSA key generation and fingerprinting utilities
    • Auto formats caller ID and called numbers into E.164 format when signing
    • Node.js >= 22
    npm install @gibme/stir-shaken
    # or
    yarn add @gibme/stir-shaken

    Set up an Asterisk AGI server that automatically signs outbound calls:

    import { AGIStirShakenServer } from '@gibme/stir-shaken';

    const server = new AGIStirShakenServer({
    port: 4573,
    certificatePath: './certificate.pem',
    privateKeyPath: './private-key.pem',
    publicCertificateURL: 'https://example.com/certificate.pem',
    attestationProvider: async (callerId, channel) => {
    // Determine attestation level based on your business logic
    return 'A';
    },
    logger: (entry) => {
    console.log(`[${entry.event}] ${entry.message}`);
    }
    });

    await server.start();
    import { generateIdentityHeader } from '@gibme/stir-shaken';
    import { readFileSync } from 'fs';

    const privateKey = readFileSync('./private-key.pem', 'utf8');

    const header = generateIdentityHeader(
    '+15550100', // caller ID
    '+15550200', // called number
    'unique-call-id', // unique ID
    'A', // attestation level
    'https://example.com/cert.pem',
    privateKey
    );
    import { generateAccountKeys } from '@gibme/stir-shaken';

    const { publicKey, privateKey } = generateAccountKeys();
    // Returns PEM-encoded ECDSA P-256 keys
    import { SPC } from '@gibme/stir-shaken';

    // Encode a numeric SPC to DER/Base64
    const spc = new SPC('8864');
    console.log(spc.tkvalue); // 'MAigBhYEODg2NA=='

    // Decode back to numeric
    const decoded = SPC.from('MAigBhYEODg2NA==');
    console.log(decoded.value); // '8864'
    import { Iconectiv, generateAccountKeys } from '@gibme/stir-shaken';

    // Static methods (no authentication required)
    const crl = await Iconectiv.crl();
    const caList = await Iconectiv.STICertificateAuthorities();

    // Authenticated methods
    const api = new Iconectiv('username', 'password');
    const { publicKey } = generateAccountKeys();
    const token = await api.ServiceProviderToken('8864', publicKey);
    Level Name Description
    A Full Originating carrier has authenticated the caller and verified they are authorized to use the calling number
    B Partial Originating carrier has authenticated the call source but cannot verify the caller's authorization for the number
    C Gateway Call originated from a gateway where the carrier cannot authenticate the source

    Asterisk AGI server that listens for incoming channel connections and signs calls with STIR/SHAKEN Identity headers.

    Options:

    Property Type Description
    port number Port to bind to
    host string Host/IP address (default: "0.0.0.0")
    certificatePath string Path to STI certificate file
    privateKeyPath string Path to the private key file
    publicCertificateURL string Publicly reachable URL to the certificate
    attestationProvider (callerId, channel?) => AttestationLevel Callback to determine attestation level
    logger (entry) => void Optional structured logging callback

    Client for the Iconectiv STIR/SHAKEN service provider API.

    Static Methods:

    • accessible() - Check if the Iconectiv API is reachable
    • crl() - Fetch the Certificate Revocation List
    • STICertificateAuthorities() - Retrieve the STI CA trust list

    Instance Methods:

    • ServiceProviderToken(spc, accountKey, ca?) - Provision an SPC token

    Service Provider Code encoder/decoder using ASN.1 DER encoding.

    • new SPC(value) - Create from numeric SPC
    • SPC.from(tkvalue) - Decode from Base64 DER token
    • .value - Numeric SPC string
    • .tkvalue - Base64-encoded DER representation
    • generateIdentityHeader(callerId, calledNumber, uniqueId, attestationLevel, certificateUrl, privateKey) - Generate a signed STIR/SHAKEN Identity header
    • generateAccountKeys(namedCurve?) - Generate ECDSA key pairs (default: P-256)
    • generateKeyFingerprint(input) - Compute SHA256 fingerprint of a key
    • Certificate: X.509 STI certificate with CN or SAN containing the Service Provider Code
    • Private Key: PEM-encoded ECDSA key corresponding to the certificate
    • Public URL: The certificate must be publicly accessible for call recipients to verify signatures

    Full API documentation is available at https://gibme-npm.github.io/stir-shaken/

    MIT