TrustPin

public final class TrustPin : @unchecked Sendable

SSL certificate pinning for iOS, macOS, tvOS, watchOS, and visionOS.

Single instance (app — existing usage, zero changes required)

try await TrustPin.setup(TrustPinConfiguration(
    organizationId: "org", projectId: "proj", publicKey: key
))
try await TrustPin.verify(domain: "api.example.com", certificate: pem)

Multiple instances (library or multi-tenant app)

A library should create its own isolated instance so it never interferes with the host app’s pinning configuration:

// Inside the library (keep this reference private/internal)
let pin = TrustPin.instance(id: "com.mylib.networking")
try await pin.setup(TrustPinConfiguration(
    organizationId: "lib-org", projectId: "lib-proj", publicKey: libKey
))
try await pin.verify(domain: "api.library.com", certificate: pem)

URLProtocol (default instance only)

registerURLProtocol() and unregisterURLProtocol() are static methods and always operate on TrustPin.default. They are intentionally unavailable on named instances — libraries should use makeURLSessionDelegate() instead.

Thread Safety

All operations are thread-safe. Internal state is protected by Swift actors.

The default instance

  • The default TrustPin instance.

    All static convenience methods (TrustPin.setup(...), TrustPin.verify(...), etc.) delegate to this instance. Existing callers that use the static API never need to reference this property directly.

    Declaration

    Swift

    public static let `default`: TrustPin

Factory

  • Returns the TrustPin instance registered under id, creating it if needed.

    Calls with the same id always return the same object — the registry is process-global and thread-safe. Use a reverse-DNS string (e.g. "com.mylib") to avoid collisions with other libraries.

    Note

    URLProtocol registration is not available on named instances. Use makeURLSessionDelegate() for library-scoped pinning.

    Declaration

    Swift

    public static func instance(id: String) -> TrustPin

    Parameters

    id

    A stable, unique identifier for this pinning context. Must not be "default" — use default instead.

    Return Value

    The existing or newly created TrustPin instance for id.

Instance API

  • setup(_:) Asynchronous

    Configures this TrustPin context with the given credentials and options.

    Throws

    invalidProjectConfig if credentials are missing or invalid.

    Throws

    errorFetchingPinningInfo if the pinning payload cannot be fetched.

    Throws

    configurationValidationFailed if signature verification fails.

    Declaration

    Swift

    public func setup(_ configuration: TrustPinConfiguration) async throws

    Parameters

    configuration

    A TrustPinConfiguration value with your project credentials and optional settings (mode, log level, custom URL).

  • Verifies a PEM certificate against the configured pins for domain.

    Throws

    invalidProjectConfig if setup(_:) has not been called.

    Throws

    domainNotRegistered if domain is not in the payload (strict mode).

    Throws

    pinsMismatch if no configured pin matches the certificate.

    Throws

    allPinsExpired if every pin for the domain has expired.

    Throws

    invalidServerCert if the certificate cannot be parsed.

    Declaration

    Swift

    public func verify(domain: String, certificate: String) async throws

    Parameters

    domain

    The hostname to validate (e.g. "api.example.com").

    certificate

    PEM-encoded certificate string including BEGIN/END markers.

  • Fetches the TLS leaf certificate from host:port as a PEM string.

    Opens an ephemeral side-channel TLS connection, performs OS-level chain validation, extracts the leaf certificate, and immediately cancels the connection without sending any HTTP data.

    Throws

    invalidServerCert if the TLS handshake fails.

    Declaration

    Swift

    public func fetchCertificate(host: String, port: Int = 443) async throws -> String

    Parameters

    host

    Hostname to connect to (e.g. "api.example.com").

    port

    TCP port (default: 443).

    Return Value

    PEM-encoded leaf certificate string.

  • Sets the log level for this TrustPin instance.

    Declaration

    Swift

    public func set(logLevel: TrustPinLogLevel)

    Parameters

    level

    The desired TrustPinLogLevel.

  • Returns a URLSessionDelegate bound to this instance that performs certificate pinning.

    Use this for library-scoped pinning instead of the global URLProtocol:

    let session = URLSession(
        configuration: .default,
        delegate: pin.makeURLSessionDelegate(),
        delegateQueue: nil
    )
    

    Declaration

    Swift

    public func makeURLSessionDelegate() -> any URLSessionDelegate
  • Returns a URLSessionDelegate bound to the default TrustPin instance.

    Equivalent to TrustPin.default.makeURLSessionDelegate().

    let session = URLSession(
        configuration: .default,
        delegate: TrustPin.makeURLSessionDelegate(),
        delegateQueue: nil
    )
    

    Declaration

    Swift

    public static func makeURLSessionDelegate() -> any URLSessionDelegate

Static convenience API (delegates to TrustPin.default)

  • Configures the default TrustPin instance.

    Equivalent to TrustPin.default.setup(configuration).

    Throws

    invalidProjectConfig if credentials are missing or invalid.

    Throws

    errorFetchingPinningInfo if the pinning payload cannot be fetched.

    Throws

    configurationValidationFailed if signature verification fails.

    Declaration

    Swift

    public static func setup(_ configuration: TrustPinConfiguration,
                             autoRegisterURLProtocol: Bool = false) async throws

    Parameters

    configuration

    A TrustPinConfiguration value with your project credentials and optional settings (mode, custom URL).

    autoRegisterURLProtocol

    When true, automatically registers TrustPinURLProtocol for system-wide pinning after setup. Requires iOS 13+ / macOS 13+. Defaults to false.

  • Verifies a certificate using the default TrustPin instance.

    Equivalent to TrustPin.default.verify(domain:certificate:).

    Declaration

    Swift

    public static func verify(domain: String, certificate: String) async throws
  • Fetches a certificate using the default TrustPin instance.

    Equivalent to TrustPin.default.fetchCertificate(host:port:).

    Declaration

    Swift

    public static func fetchCertificate(host: String, port: Int = 443) async throws -> String
  • Sets the log level on the default TrustPin instance.

    Equivalent to TrustPin.default.set(logLevel:).

    Declaration

    Swift

    public static func set(logLevel: TrustPinLogLevel)

URLProtocol (default instance only — compile-time enforced)

  • Registers the TrustPin URLProtocol for system-wide pinning using the default instance.

    Note

    Only available on the default instance. Libraries should use makeURLSessionDelegate() instead.

    Declaration

    Swift

    @available(iOS 13.0, macOS 13.0, tvOS 13.0, watchOS 7.0, visionOS 2.0, *)
    public static func registerURLProtocol()
  • Unregisters the TrustPin URLProtocol.

    Declaration

    Swift

    @available(iOS 13.0, macOS 13.0, tvOS 13.0, watchOS 7.0, visionOS 2.0, *)
    public static func unregisterURLProtocol()