Packages
ash_openfeed
0.1.0
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
Current section
Files
ash_openfeed
CHANGELOG.md
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.