All notable changes to this project are documented here. The format follows Keep a Changelog, and this project adheres to Semantic Versioning.
[0.1.0] — 2026-08-08
First release.
Everything below has been verified end to end against production OpenFeed: OIDC
discovery, private_key_jwt at the PAR, token and introspection endpoints, PAR,
the authorization-code exchange, grant_id recovery via introspection, DPoP-bound
resource calls, multi-page pagination, token refresh, and the app-level endpoints.
Requires
- Elixir 1.17+ and OTP 27+. The OTP floor comes from oidcc, which does not compile on OTP 26; both packages check and raise a clear error. Verified in CI across Elixir 1.17-1.20.
Added
OpenFeed— top-level facade.{OpenFeed, config}starts the OIDC discovery worker in a supervision tree.OpenFeed.Config— injected configuration struct with validation. Nothing in this package reads application environment.OpenFeed.Scopes— shorthand atoms for OpenFeed's scope strings.OpenFeed.KeyStorebehaviour, withFileandEnvimplementations. Keys are never generated implicitly; see the README for why.OpenFeed.Dpop— RFC 9449 PS256 proofs, includingexp/nbfand clock-skew tolerance.OpenFeed.AuthandOpenFeed.Tokens— PAR + PKCE authorization, code exchange, refresh, client credentials, introspection.OpenFeed.ProviderConfiguration— discovery worker, with the introspection metadata override OpenFeed's discovery document requires.OpenFeed.Client— DPoP transport,links.nextpagination, lazystream/4, retries with jittered backoff.OpenFeed.Sharing— a function for each of the 16 sharing-api paths.OpenFeed.Error— typed errors classified by a stable:kind, so callers can distinguish a revoked grant from a subject mismatch (both HTTP 403).OpenFeed.ReqHttpAdapter—:oidcc_http_adapterbacked by Req, replacing httpc, which intermittently wedges against auth.openfeed.au.OpenFeed.Amount.to_decimal/1— handles both wire formats OpenFeed uses for money: ISO 20022 strings in banking, JSON numbers in energy.OpenFeed.Energy.net_usage/1,has_reads?/1,reads/1,read_value/1— handle thereadUTypediscriminator in usage payloads. Reading only the interval variant silently reports zero for daily-read meters.
Fixed
- A revoked grant discovered via token refresh was reported as
:unauthorized, so callers retried a refresh that could never succeed while the grant looked healthy.invalid_granton refresh is now:grant_revoked— OpenFeed sweeps refresh tokens when a grant is revoked, so this is the normal way a client learns a consumer disconnected. Not applied toexchange_code/3, whereinvalid_grantmeans a stale authorization code. authorize_url/2no longer forcesgrant_management_action=create. OpenFeed treats the action as optional and infers it fromgrant_idpresence.- Corrected the
authorize_url/2docs:queryandrevokeare advertised ingrant_management_actions_supportedbut are not authorization-endpoint actions.
Documentation
- A Grant management topic covering the consent lifecycle, amendment, polling for revocations, and what the authorised account id lists are not.
- A Collecting data tutorial and a Cost and cadence topic, both wired into the docs. The README gained a Collecting data section; it previously covered setup and key management and said nothing about reading data.
test/documentation_test.exsruns the documented examples against a stub, so the guides cannot drift into code that no longer works.
Requires
oidcc ~> 3.8— the first release with pluggable HTTP adapters (erlef/oidcc#528).