Ash resource extension for storing OpenFeed disclosure grants.
Usage
defmodule MyApp.OpenFeed.Grant do
use Ash.Resource,
domain: MyApp.OpenFeed,
data_layer: AshPostgres.DataLayer,
extensions: [AshOpenFeed.Grant]
openfeed do
otp_app :my_app
key_store AshOpenFeed.KeyStore.Ash
grant_management? true
end
postgres do
table "openfeed_grants"
repo MyApp.Repo
end
relationships do
belongs_to :user, MyApp.Accounts.User
end
endWhat gets added
Attributes: grant_id, status, metering_state, revision,
access_token, refresh_token, token_type, expires_at, sub, scopes.
The token attributes are marked sensitive? so they are redacted from
inspect output and error messages.
Actions: read, destroy, upsert_from_tokens, update_tokens,
mark_revoked, mark_metering_suspended, mark_metering_active.
An identity unique_grant_id on grant_id.
Everything is added with Ash's add_new_* builders, so anything you define
yourself wins. If you need a different shape, declare it and the extension
will leave it alone.
Data layers that cannot enforce identities
AshPostgres backs the unique_grant_id identity with a real unique
constraint. Ash.DataLayer.Ets and Mnesia cannot, and Ash refuses to
compile an identity on those without pre_check_with. Since the identity is
injected rather than hand-written, the extension detects this and sets
pre_check_with to the resource's domain for you.
The one case it cannot handle is a resource with no domain (domain: nil,
for a resource shared across domains) on one of those data layers — there is
nothing to pre-check with. Declare the identity yourself and the extension
will leave it alone:
identities do
identity :unique_grant_id, [:grant_id], pre_check_with: MyApp.SomeDomain
endNote also that a pre-checked identity installs a before_action hook, which
makes updates non-atomic. The extension therefore sets require_atomic? false
on the update actions only when pre-checking is in play, so AshPostgres
users keep atomic updates.
Encrypt your tokens
The token attributes are plaintext columns unless you encrypt them. Because this is your resource, you can:
defmodule MyApp.OpenFeed.Grant do
use Ash.Resource,
extensions: [AshOpenFeed.Grant, AshCloak.Resource]
cloak do
vault MyApp.Vault
attributes [:access_token, :refresh_token]
end
endA verifier emits a compile-time warning if it cannot see encryption
configured on a resource holding real tokens. Set warn_unencrypted?: false
in application config to silence it once you have made a deliberate choice.
DSL Documentation
See AshOpenFeed.Grant.openfeed for the full option reference.