awskit

Runtime-agnostic AWS infrastructure for OCaml applications.

The core Awskit library contains credentials, regions, endpoints, structured errors, HTTP metadata, body metadata, request signing, and the runtime abstraction used by service clients. It has no IO dependencies: concurrency, networking, filesystem access, clocks, and environment variables live in adapter libraries selected at the application edge.

Service packages such as awskit-s3 build on the runtime abstraction defined here instead of depending directly on Eio, Lwt, or Unix.

The first supported service surface is AWS S3.

Public support and security policy live in SUPPORT.md and SECURITY.md.

Package Split

Awskit follows a Cohttp-style package split. Install the runtime adapter that matches your application, and leave the rest out of your dependency graph.

The core awskit and awskit-s3 packages do not depend on Unix, Eio, Lwt, or Cohttp runtime packages. Use awskit-s3-sim in tests when you want deterministic S3 behavior without HTTP requests. Adapter packages carry runtime dependencies.

Quick Start

For Eio S3 applications, install the Eio adapter and pass an HTTPS policy when creating the client. Add awskit-unix only when using Unix credential helpers such as Awskit_unix.Credentials.default_chain:

opam install awskit-s3-eio awskit-unix eio_main tls-eio tls ca-certs domain-name mirage-crypto-rng

awskit-s3-eio does not provide a ready Eio Unix aggregate adapter. Applications own HTTPS transport, TLS configuration, CA roots, RNG initialization, and platform policy.

For Lwt + Unix S3 applications, install the ready-to-use Unix adapter:

opam install awskit-s3-lwt-unix

See awskit-s3 for object-storage examples, endpoint configuration, transfer helpers, presigning, and S3-specific error handling.

Libraries

awskit

The entrypoint is Awskit.

Core modules:

awskit-eio

Awskit_eio is the direct-style Eio runtime adapter. Its monad type is type 'a t = 'a. Response bodies are scoped to with_response and Runtime.Response_body.with_reader. Applications provide the HTTPS policy used for TLS-enabled endpoints.

awskit-lwt

Awskit_lwt is a generic Lwt runtime functor over Cohttp_lwt.S.Client. Use it for custom Lwt HTTP backends.

awskit-lwt-unix

Awskit_lwt_unix is the ready-to-use Lwt + Unix runtime adapter. When arguments are omitted, it can load credentials from standard AWS environment variables, shared AWS profile files, ECS/container metadata, or EC2 instance metadata, and it can load the region from standard AWS environment variables.

awskit-unix

Awskit_unix contains Unix-specific credential and region sources. It does not perform HTTP calls.

Minimal Signing Example

This example uses dummy credentials for a pure signing demonstration. Prefer standard provider sources or temporary credentials in real applications.

let credentials =
  Awskit.Credentials.create_exn
    ~access_key_id:"AKIAIOSFODNN7EXAMPLE"
    ~secret_access_key:"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
    ()
in
let region = Awskit.Region.of_string_exn "us-east-1" in
let payload_hash = Awskit.Body.Payload_hash.sha256_of_string "" in
Awskit.Signing.sign_request_params_exn
  ~credentials
  ~region
  ~service:"s3"
  ~method_:`GET
  ~path:"/my-key"
  ~query_params:[]
  ~headers:[ ("host", "my-bucket.s3.us-east-1.amazonaws.com") ]
  ~payload_hash
  ~now:Ptime.epoch

Signing is pure and testable without network access. Service packages sign requests automatically; use Awskit.Signing directly when building a custom AWS service client or low-level signing tests.

Minimal Eio Runtime Example

module Https = struct
  let connector () =
    Mirage_crypto_rng_unix.use_default ();
    let authenticator =
      match Ca_certs.authenticator () with
      | Ok authenticator -> authenticator
      | Error (`Msg msg) -> invalid_arg ("failed to load CA roots: " ^ msg)
    in
    let tls_config =
      match Tls.Config.client ~authenticator () with
      | Ok config -> config
      | Error (`Msg msg) -> invalid_arg ("failed to create TLS config: " ^ msg)
    in
    Some
      (fun uri raw ->
        let host =
          match Uri.host uri with
          | Some host -> Domain_name.host_exn (Domain_name.of_string_exn host)
          | None -> invalid_arg "HTTPS URI is missing a host"
        in
        (Tls_eio.client_of_flow tls_config ~host raw
          :> [ Eio.Flow.two_way_ty | Eio.Resource.close_ty ] Eio.Flow.two_way))
end

Eio_main.run @@ fun env ->
Eio.Switch.run @@ fun sw ->
  let https = Https.connector () in
  let conn =
    Awskit_eio.create
      ~env
      ~sw
      ~https
      ~region:"us-east-1"
      ~credentials
      ()
    |> Result.get_ok
  in
  ignore conn

Minimal Lwt Unix Runtime Example

let conn =
  Awskit_lwt_unix.create ()
  |> Result.get_ok
in
ignore conn

When omitted, awskit-lwt-unix reads:

AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_SESSION_TOKEN
AWS_REGION
AWS_DEFAULT_REGION

Service Packages

Guides