Packages

Client for OpenFeed (Australian CDR banking and energy data). Handles the FAPI 2.0 Security Profile — PAR, PKCE, DPoP — and key management.

Current section

Files

Jump to
openfeed CHANGELOG.md
Raw

CHANGELOG.md

# Changelog
All notable changes to this project are documented here. The format follows
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [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.KeyStore` behaviour, with `File` and `Env` implementations. Keys
are never generated implicitly; see the README for why.
- `mix openfeed.gen.key` and `mix openfeed.jwks`.
- `OpenFeed.Dpop` — RFC 9449 PS256 proofs, including `exp`/`nbf` and
clock-skew tolerance.
- `OpenFeed.Auth` and `OpenFeed.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.next` pagination, lazy
`stream/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_adapter` backed 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 the `readUType` discriminator 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_grant` on **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 to `exchange_code/3`, where
`invalid_grant` means a stale authorization code.
- `authorize_url/2` no longer forces `grant_management_action=create`. OpenFeed
treats the action as optional and infers it from `grant_id` presence.
- Corrected the `authorize_url/2` docs: `query` and `revoke` are advertised in
`grant_management_actions_supported` but 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.exs` runs 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).