Sinatra verifier quickstart

This guide walks through adding Confium to a Sinatra app that verifies composite multi-algorithm signatures and transparency-log inclusion proofs. The complete, integration-tested app lives at examples/verifier_sinatra.rb (checked by scripts/sinatra_integration_test.sh in CI).

Prerequisites

  • Ruby >= 3.1
  • On the pre-compiled platforms (linux x86_64/aarch64, macOS x86_64/arm64) nothing else; otherwise Rust stable for the source build

Setup

bundle add confium sinatra puma

The app

# app.rb
require "sinatra/base"
require "confium"

class VerifyApp < Sinatra::Base
  before { content_type :json }

  # Composite signature verification. Expects JSON:
  #   {
  #     "composite": "<components JSON from Signature.components_to_json>",
  #     "message":   "<hex bytes of signed message>"
  #   }
  post "/verify/composite" do
    body = JSON.parse(request.body.read)
    sig = Confium::Composite::Signature.from_json(body.fetch("composite"))
    result = sig.verify([body.fetch("message")].pack("H*"))

    {
      all_verified: result.all_verified?,
      per_component: result.per_component,
    }.to_json
  rescue KeyError => e
    halt 400, { error: "missing field: #{e.message}" }.to_json
  rescue StandardError => e
    halt 400, { error: e.message }.to_json
  end
end

from_json accepts the JSON string or an already-parsed structure; binary fields (public_key, signature) travel hex-encoded.

Producing a signature to verify

require "confium"
require "json"

comp = Confium::Composite
kp = comp.generate_ed25519_keypair
component = comp.sign_ed25519(kp["private_key"], "hello")
wire = Confium::Composite::Signature.components_to_json([component])

request = JSON.generate(
  composite: JSON.parse(wire),
  message: "hello".unpack1("H*")
)

Test

curl -s -X POST http://localhost:4567/verify/composite \
  -H "Content-Type: application/json" -d "$request"

Expected response:

{"all_verified":true,"per_component":{"0":{"algorithm":"Ed25519","verified":true}}}

X.509 chain validation

Path validation reports through a result object rather than raising:

cert = Confium::PKI::Certificate.from_pem(pem)
root = Confium::PKI::Certificate.from_pem(File.read("ca.pem"))
result = Confium::PKI::PathValidator.validate(cert, nil, root)
result.valid?       # => true | false
result.check_count  # => Integer
result.checks_json  # => per-check detail (JSON string)

Next steps

  • Anchor verified artifacts in a transparency log via Confium::Transparency::MerkleTree and serve inclusion proofs.
  • Set up audit logging via Confium::Audit.sink = ....
  • Map typed errors to HTTP statuses — see Error handling.