AshOpenFeed.Grant (AshOpenFeed v0.1.0)

Copy Markdown View Source

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
end

What 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
end

Note 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
end

A 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.

Summary

Functions

openfeed(body)

(macro)