shomei-core-0.2.0.0: src/Shomei/SigningKey/Signer.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeFamilies #-}
-- | The token-signer port: turning 'AuthClaims' into a signed 'AccessToken', and
-- 'IdTokenClaims' into a signed 'IdToken' (both real JWTs in @shomei-jwt@).
--
-- ID-token signing is an operation here rather than a direct @jose@ call from the HTTP layer,
-- because every workflow-visible signing capability in this repo crosses this port: that is what
-- keeps the in-memory test fake able to stand in for the real signer, and what means an OIDC ID
-- token is signed with the same active key and @kid@ as an access token, with zero new JWKS or
-- key-rotation work.
module Shomei.SigningKey.Signer
( TokenSigner (..),
signAccessToken,
signIdToken,
)
where
import Effectful (Dispatch (..), DispatchOf, Eff, Effect, (:>))
import Effectful.Dispatch.Dynamic (send)
import Shomei.Authorization.Claims.Domain (AuthClaims)
import Shomei.OAuth.IdToken.Domain (IdToken, IdTokenClaims)
import Shomei.Session.Token.Domain (AccessToken)
data TokenSigner :: Effect where
SignAccessToken :: AuthClaims -> TokenSigner m AccessToken
-- | EP-5. Signed with the same active key and @kid@ as an access token, so the ID token
-- verifies against the same published JWKS document.
SignIdToken :: IdTokenClaims -> TokenSigner m IdToken
type instance DispatchOf TokenSigner = Dynamic
signAccessToken :: (TokenSigner :> es) => AuthClaims -> Eff es AccessToken
signAccessToken = send . SignAccessToken
signIdToken :: (TokenSigner :> es) => IdTokenClaims -> Eff es IdToken
signIdToken = send . SignIdToken