Google API authentication helpers: service accounts and local OAuth
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

ocaml-linkedin: apply dune fmt

Pure formatting changes from `dune fmt`: doc comment placement moves
from above the binding to below it for `type`s, multi-line `match`
expressions collapse onto one line where they fit, and infix operator
applications pick up spaces (`Soup.($?)` -> `Soup.( $? )`). No
semantic changes.

+100 -1
+92
README.md
··· 1 + # gauth 2 + 3 + Google API authentication for OCaml. 4 + 5 + Two flows: **service-account JWT bearer** ([RFC 7523][rfc7523]) for 6 + server-to-server access from a JSON key file, and an **interactive 7 + local OAuth flow** for CLI tools that spins up a localhost listener 8 + and exchanges the authorization code for tokens. Both return a 9 + `token` that transparently refreshes credentials near expiry. 10 + 11 + [rfc7523]: https://www.rfc-editor.org/rfc/rfc7523 12 + 13 + ## Installation 14 + 15 + Install with opam: 16 + 17 + <!-- $MDX skip --> 18 + ```sh 19 + $ opam install gauth 20 + ``` 21 + 22 + If opam cannot find the package, it may not yet be released in the 23 + public `opam-repository`. Add the overlay repository, then install 24 + it: 25 + 26 + <!-- $MDX skip --> 27 + ```sh 28 + $ opam repo add samoht https://tangled.org/gazagnaire.org/opam-overlay.git 29 + $ opam update 30 + $ opam install gauth 31 + ``` 32 + 33 + ## Usage 34 + 35 + ### Service account 36 + 37 + Parse a service-account JSON key and mint an access token for a set 38 + of OAuth scopes. The `Requests.t` HTTP client and the Eio `clock` 39 + are required for refresh: 40 + 41 + ```ocaml 42 + let fetch_token http ~clock ~key_path = 43 + match Gauth.Service_account.of_file key_path with 44 + | Error (`Msg m) -> Error m 45 + | Ok key -> 46 + let scopes = 47 + [ "https://www.googleapis.com/auth/documents.readonly" ] in 48 + match Gauth.Service_account.token http ~clock ~scopes key with 49 + | Ok token -> Ok (Gauth.access token) 50 + | Error (`Msg m) -> Error m 51 + ``` 52 + 53 + Pass `?subject:"alice@example.com"` to `Service_account.token` to 54 + use [domain-wide delegation][dwd] and impersonate a Workspace user. 55 + 56 + [dwd]: https://developers.google.com/identity/protocols/oauth2/service-account#delegatingauthority 57 + 58 + ### Interactive local flow 59 + 60 + `Local_flow.run` binds an ephemeral port on `127.0.0.1`, prints a 61 + Google consent URL to stderr, and waits up to `?timeout` seconds 62 + (default 120) for the user to complete the flow: 63 + 64 + ```ocaml 65 + let login http ~clock ~net ~sw ~client_id ~client_secret = 66 + Gauth.Local_flow.run http ~clock ~net ~sw 67 + ~client_id ~client_secret 68 + ~scopes:[ "https://www.googleapis.com/auth/documents.readonly" ] 69 + () 70 + ``` 71 + 72 + Override `?on_url` to launch a browser automatically instead of 73 + printing the URL. 74 + 75 + ### Persistence 76 + 77 + Serialize a token to JSON, restore it later — useful for "login 78 + once, use many times" CLIs: 79 + 80 + ```ocaml 81 + let save token = Gauth.to_json token 82 + 83 + let restore http ~clock ~client_id ~client_secret json = 84 + Gauth.of_json http ~clock ~client_id ~client_secret json 85 + ``` 86 + 87 + `access` and `try_access` return a current access token, refreshing 88 + synchronously if the cached one is near expiry. 89 + 90 + ## Licence 91 + 92 + MIT
+4
dune
··· 1 1 (env 2 2 (dev 3 3 (flags :standard %{dune-warnings}))) 4 + 5 + (mdx 6 + (files README.md) 7 + (libraries gauth requests eio eio.core))
+3 -1
dune-project
··· 1 1 (lang dune 3.21) 2 + (using mdx 0.4) 2 3 3 4 (name gauth) 4 5 ··· 37 38 (alcotest :with-test) 38 39 (eio_main :with-test) 39 40 (odoc :with-doc) 40 - crypto-pk)) 41 + crypto-pk 42 + (mdx :with-test)))
+1
gauth.opam
··· 33 33 "eio_main" {with-test} 34 34 "odoc" {with-doc} 35 35 "crypto-pk" 36 + "mdx" {with-test} 36 37 ] 37 38 build: [ 38 39 ["dune" "subst"] {dev}