Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556defmodule GitHub.App do @moduledoc """ A GitHub App identity, used to mint short-lived JWTs for app authentication.
A JWT signed with the app's private key authenticates as the app itself (e.g. to create installation access tokens). JWTs are valid for several minutes, so they are cached in `GitHub.Auth.Cache` keyed by app id. """
use TypedStruct
alias GitHub.Auth.Cache
# GitHub rejects JWTs whose `iat` is in the future; back-date to absorb # clock drift between this host and GitHub. @clock_drift_sec 60 @duration_sec 10 * 60
typedstruct enforce: true do field :id, integer() field :pem, String.t() end
@doc """ Returns a signed, cached JWT (RS256) authenticating as the app. """ @spec jwt(t()) :: String.t() def jwt(%__MODULE__{id: id, pem: pem}) do case Cache.get({:app, id}) do {:ok, jwt} -> jwt
:error -> now = System.os_time(:second) expiration = now - @clock_drift_sec + @duration_sec
claims = %{ "iat" => now - @clock_drift_sec, "exp" => expiration, "iss" => id }
jwk = JOSE.JWK.from_pem(pem) jws = JOSE.JWS.from_map(%{"alg" => "RS256", "typ" => "JWT"})
{_, jwt} = jwk |> JOSE.JWT.sign(jws, claims) |> JOSE.JWS.compact()
Cache.put({:app, id}, expiration, jwt) jwt end endend