Repository navigation
Authentication and Accounts
Herald uses OAuth 2.1 PKCE to sign in to HQBase. Tokens are stored in the macOS Keychain; multiple accounts can be added.
AuthCoordinator (HeraldKit/Sources/HeraldKit/Auth/AuthCoordinator.swift:11) orchestrates:
-
Service discovery — Fetch the
.well-known/oauth-authorization-servermetadata from the HQBase instance to learn the authorization and token endpoints. -
Dynamic client registration —
DynamicClientRegistration(HeraldKit/Sources/HeraldKit/Auth/DynamicClientRegistration.swift:11) registers a new OAuth client with HQBase, receiving a client ID (one per app install; PKCE means no client secret is needed). -
Authorization request — Launch a system web view via
WebAuthenticationPresenter(HeraldKit/Sources/HeraldKit/Auth/AuthorizationPresenter.swift:22) with a PKCE code-challenge. -
Token exchange — HQBase returns an authorization code;
AuthCoordinatorexchanges it for access and refresh tokens. -
Keychain storage —
KeychainAccountStore(HeraldKit/Sources/HeraldKit/Auth/AccountStore.swift:41) stores the account and tokens securely.
See HeraldKit/Sources/HeraldKit/Auth/Account.swift:9 for the Account struct and OAuthTokens struct.
AccountStore (protocol at HeraldKit/Sources/HeraldKit/Auth/AccountStore.swift:11) abstracts account and token persistence. KeychainAccountStore (AccountStore.swift:41) implements it, storing accounts as Keychain items keyed by account ID.
Multiple accounts are supported; each is stored independently and can be removed.
AccountTokenProvider (HeraldKit/Sources/HeraldKit/Auth/AccountTokenProvider.swift:20) is an actor that:
- Holds the current account and tokens
- Implements
BearerTokenProviderso the API client can fetch a token synchronously - Refreshes the token when it expires (via the refresh token)
- Re-fetches the account from the store on refresh to pick up changes
The API client calls token() on AccountTokenProvider before every request, which blocks if a refresh is in progress.
- Flow — OAuth 2.1 PKCE (authorization code with code verifier, no client secret sent)
-
Presenter —
WebAuthenticationPresenterusesASWebAuthenticationSessionto launch a system web view - Client registration — Dynamic client registration; the client ID is stored locally, not hardcoded
-
Scopes —
mail:readandmail:write(HQBase Mail API v1)
Last updated: 2026-08-19 — authentication and accounts; fact-checked against the code for v0.3.0
Herald is AGPL-3.0. This wiki lives in the repo's wiki/ folder and is managed by Memophant — see Wiki Maintenance.