AshAtproto

Ash utilities built on top of atex to make integrating with ATProto easier. It includes:

Installation

The package can be installed by adding ash_atproto to your list of dependencies in mix.exs:

def deps do
  [
    {:ash_atproto, "~> 0.1.0"}
  ]
end

User resource extension

This extension modifies your resource to add the following attributes:

These attributes can be overridden if necessary, and new attributes can be added with no issues.

It also includes the following actions:

Example

defmodule MyApp.Accounts.User do
  use Ash.Resource,
    otp_app: :my_app,
    domain: MyApp.Accounts,
    authorizers: [Ash.Policy.Authorizer],
    extensions: [AshAuthentication, AshAtproto.Auth, AshAtproto.UserResource],
    data_layer: AshPostgres.DataLayer

  authentication do
    tokens do
      enabled? true
      require_token_presence_for_authentication? true
      token_resource MyApp.Accounts.Token
      signing_secret MyApp.Secrets
      store_all_tokens? true
    end

    strategies do
      atproto do
        registration_enabled? true
        base_url MyApp.Secrets

        private_key MyApp.Secrets
        key_id(MyApp.Secrets)
      end
    end
  end

  postgres do
    table "users"
    repo MyApp.Repo
  end

  actions do
    read :get_by_subject do
      description "Get a user by the subject claim in a JWT"
      argument :subject, :string, allow_nil?: false
      get? true
      prepare AshAuthentication.Preparations.FilterBySubject
    end
  end

  policies do
    bypass AshAuthentication.Checks.AshAuthenticationInteraction do
      authorize_if always()
    end

    policy always() do
      forbid_if always()
    end
  end
end

AshAuthentication strategy

A strategy that enables seamless integration with the rest of AshAuthentication. The atproto strategy is standalone, and can be used without the user resource extension (replacing it with AshAuthentication.UserIdentity, for example).

Example

use Ash.Resource,
  extensions: [AshAuthentication, AshAtproto.Auth],

strategies do
  atproto do
    registration_enabled? true
    base_url MyApp.Secrets

    private_key MyApp.Secrets
    key_id(MyApp.Secrets)
  end
end

Configuration values can be passed directly, but using AshAuthentication.Secret is recommended.

OAuth client

An HTTP API client that follows the XRPC conventions. Will automatically refresh tokens if needed.

Example

user_resource = Ash.read_one!(MyApp.Accounts.User, authorize?: false)
{:ok, client} = AshAtproto.XRPC.OAuthClient.new(user_resource)

# Make XRPC requests
{:ok, response, client} =
  Atex.XRPC.get(client, "com.atproto.repo.listRecords",
    params: [repo: user.handle, collection: "app.bsky.graph.follow"]
  )

For more details, including lexicon code generation and typed parameters, check the Atex.XRPC module.

Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/ash_atproto.