BankID.HTTPClient (bankid v0.0.2)

Copy Markdown View Source

HTTP client for BankID API with mTLS (mutual TLS) support.

This module provides a native Elixir implementation for communicating with the Swedish BankID API.

Features

  • mTLS authentication using client certificates
  • Support for both test and production environments
  • Certificate validation using BankID's CA certificates
  • JSON request/response handling
  • Proper error handling for BankID API errors

Usage

# Create a client (test mode by default)
client = BankID.HTTPClient.new()

# Make a request
{:ok, response} = BankID.HTTPClient.post(client, "/auth", %{endUserIp: "192.168.1.1"})

Summary

Types

t()

BankID HTTP client struct containing configuration for API communication.

Functions

Convert known BankID API keys to atoms safely.

Convert map with string keys to atom keys (deep conversion).

Create a new HTTP client for BankID API.

Make a POST request to the BankID API.

Resolve certificate path from the bundled certificates.

Types

t()

@type t() :: %BankID.HTTPClient{
  base_url: String.t(),
  cacerts_der: [binary()],
  cert_der: binary(),
  key_der: {atom(), binary()},
  test_server: boolean()
}

BankID HTTP client struct containing configuration for API communication.

Fields

  • base_url - Base URL for the BankID API endpoint
  • test_server - Boolean indicating if using test server
  • cert_der - Client certificate in DER format
  • key_der - Client private key in DER format with key type
  • cacerts_der - List of CA certificates in DER format for server verification

Functions

atomize_key(key)

Convert known BankID API keys to atoms safely.

Only known BankID API keys are converted to atoms to prevent atom exhaustion attacks. Unknown keys remain as strings.

Parameters

  • key - String key to convert

Returns

Atom key if known, otherwise the original key

atomize_keys(map)

Convert map with string keys to atom keys (deep conversion).

This function safely converts JSON response keys from strings to atoms for consistency within the application. Only known BankID API keys are converted to atoms to prevent atom exhaustion attacks.

Parameters

  • data - Any data structure containing string keys

Returns

The same data structure with known string keys converted to atoms

new(opts \\ [])

Create a new HTTP client for BankID API.

Configuration

Certificates are configured via application config. Defaults point to bundled test certificates, so no configuration is needed for testing.

For Testing (Default)

No configuration needed - uses bundled test certificates:

# Uses test server and test certificates automatically
client = BankID.HTTPClient.new()

For Production

You can configure certificates in two ways:

Provide certificate content directly from environment variables. This is ideal for serverless deployments (AWS Lambda, Google Cloud Functions, etc.) where file system access is limited.

Add to your config/runtime.exs:

config :bankid,
  base_url: "https://appapi2.bankid.com/rp/v6.0",
  cert: System.get_env("BANKID_CERT"),
  key: System.get_env("BANKID_KEY"),
  cacert: System.get_env("BANKID_CACERT")

Then set environment variables with full PEM content:

export BANKID_CERT="-----BEGIN CERTIFICATE-----
MIIEyjCCArKgAwIBAgIIG8/maByOzV4w...
-----END CERTIFICATE-----"

export BANKID_KEY="-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAAS...
-----END PRIVATE KEY-----"

Option 2: File Paths (Traditional)

Provide paths to certificate files on the file system:

Add to your config/runtime.exs:

config :bankid,
  base_url: "https://appapi2.bankid.com/rp/v6.0",
  cert_path: System.get_env("BANKID_CERT_PATH"),
  key_path: System.get_env("BANKID_KEY_PATH")

Then set environment variables:

export BANKID_CERT_PATH="/etc/bankid/production-cert.pem"
export BANKID_KEY_PATH="/etc/bankid/production-key.pem"

Configuration Options

All configuration is via config :bankid. Certificate options have a priority order:

Priority 1: Direct Content

  • :cert - Client certificate PEM content (string)
  • :key - Client private key PEM content (string)
  • :cacert - CA certificate PEM content (string)

Priority 2: File Paths

  • :cert_path - Path to client certificate PEM file
  • :key_path - Path to client private key PEM file
  • :cacert_path - Path to CA certificate PEM file

Priority 3: Bundled Test Certificates

  • If neither content nor paths are provided, bundled test certificates are used

Other Options

  • :base_url - BankID API endpoint (defaults to test server)

Examples

# Testing - uses defaults
client = BankID.HTTPClient.new()

# Production with direct content
client = BankID.HTTPClient.new()

# Production with file paths
client = BankID.HTTPClient.new()

post(client, path, body)

Make a POST request to the BankID API.

Parameters

  • client - The HTTP client struct
  • path - API endpoint path (e.g., "/auth", "/collect")
  • body - Request body (will be JSON encoded)

Returns

  • {:ok, response_body} - Successful response with decoded JSON
  • {:error, reason} - Error with reason

resolve_cert_path(filename)

Resolve certificate path from the bundled certificates.

This is used internally to locate certificates in the priv/certs directory.