Packages

Ash extension for OpenFeed (Australian CDR banking and energy data). Stores disclosure grants and their tokens on your own Ash resource.

Current section

Files

Jump to
ash_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.
### Not yet verified against production
`AshOpenFeed.revoke/2` and the success path of `AshOpenFeed.refresh_status/2`
require the `openfeed-au:grant:self:query` and `openfeed-au:grant:self:revoke`
scopes, which the registration used for development was not granted. Both are
covered by tests against a stub server, but neither has been exercised against
the real API. Everything else here has.
`reconcile_grants/2` **has** been run against production, including its
degradation path when those scopes are absent.
### 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
- `AshOpenFeed.Grant` — Ash resource extension. Injects the token attributes,
the `grant_id` identity and the lifecycle actions into a resource you own.
Uses Ash's `add_new_*` builders throughout, so your own declarations win.
- `AshOpenFeed` — runtime API: `authorize_url/3`,
`complete_authorization/4`, `access_token/2`, `with_token/3`, `revoke/2`,
`refresh_status/2`.
- `AshOpenFeed.Info` — introspection, plus `config/2` resolving an
`OpenFeed.Config` from application config or a provider.
- `AshOpenFeed.ConfigProvider` — behaviour for credentials that cannot come
from static config, such as a registration per tenant.
- `AshOpenFeed.KeyStore.Ash` — signing key in an Ash resource, so every node
signs with the same key.
- `mix ash_openfeed.install` — Igniter installer. Generates the domain, grant
and key resources, an editable consent controller, routes and config.
- Compile-time verifiers: one rejecting a resource with no credential source,
one warning when tokens have no visible encryption at rest.
### Added
- `AshOpenFeed.amend_url/3` — send a consumer back to OpenFeed to change which
accounts they share. OpenFeed keeps the same `grant_id` and bumps its revision,
so the existing callback handles the return trip.
- `AshOpenFeed.reconcile_grants/2` — diff local grants against OpenFeed's
app-level index. There are no webhooks, so this is the only way to notice a
revocation or amendment without first failing a data call. Phase one needs only
the app-level scope, so it works without grant-management scopes; phase two
degrades gracefully, still recording the revision.
- `banking_account_ids` / `energy_account_ids` attributes and a
`sync_grant_state` action.
### Fixed
- A rejected refresh now marks the grant revoked. Previously `with_token/3`'s
`with` short-circuited on `access_token/2`, so a refresh failure never reached
reconciliation and the grant stayed `:active` indefinitely.
- `refresh_status/2` read only `grantStatus` and `meteringState`, discarding the
rest of the response. It now maps `grantRevision` and the authorised account id
sets too — the injected `revision` attribute was previously never written.
- `complete_authorization/4` warns when `grant_management? true` but the scopes
were not granted, rather than letting `revoke/2` fail with a 403 at the moment
a consumer is trying to disconnect.
### Documentation
- A *Collecting data into your own resources* section: the full sync loop,
error collection, streaming large collections, and an AshOban schedule.
Previously a single line.
### Notes
- The injected identity gets `pre_check_with` automatically on data layers that
cannot enforce identities (ETS, Mnesia), since the identity is injected and
could not otherwise be fixed by the user. Because a pre-checked identity
installs a `before_action` hook, `require_atomic? false` is applied to the
update actions in exactly that case — AshPostgres keeps atomic updates.