ash-authentication

AshAuthentication guidelines for implementing authentication in Ash Framework. Use when adding password, magic link, API key, or OAuth2 authentication strategies. Covers token configuration, UserIdentity resources, confirmation add-ons, and customizing authentication actions. Never hardcode credentials.

16 stars

Best use case

ash-authentication is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

AshAuthentication guidelines for implementing authentication in Ash Framework. Use when adding password, magic link, API key, or OAuth2 authentication strategies. Covers token configuration, UserIdentity resources, confirmation add-ons, and customizing authentication actions. Never hardcode credentials.

Teams using ash-authentication should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/ash-authentication/SKILL.md --create-dirs "https://raw.githubusercontent.com/diegosouzapw/awesome-omni-skill/main/skills/testing-security/ash-authentication/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/ash-authentication/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How ash-authentication Compares

Feature / Agentash-authenticationStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

AshAuthentication guidelines for implementing authentication in Ash Framework. Use when adding password, magic link, API key, or OAuth2 authentication strategies. Covers token configuration, UserIdentity resources, confirmation add-ons, and customizing authentication actions. Never hardcode credentials.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# AshAuthentication Guidelines

## Core Concepts

- **Strategies**: password, magic_link, api_key, OAuth2 (github, google, auth0, apple, oidc, slack)
- **Tokens**: JWT for stateless authentication
- **UserIdentity**: Links users to OAuth2 providers (optional, required for multiple providers per user)
- **Add-ons**: confirmation, logout-everywhere

## Key Principles

- **Never hardcode credentials** - always use secrets management
- Enable tokens for magic_link, confirmation, OAuth2
- Check existing strategies: `AshAuthentication.Info.strategies(MyApp.User)`

## Password Strategy

```elixir
authentication do
  strategies do
    password :password do
      identity_field :email
      hashed_password_field :hashed_password
      resettable do
        sender MyApp.PasswordResetSender
      end
    end
  end
end

# Required attributes
attributes do
  attribute :email, :ci_string, allow_nil?: false, public?: true
  attribute :hashed_password, :string, allow_nil?: false, sensitive?: true
end

identities do
  identity :unique_email, [:email]
end
```

## Magic Link Strategy

```elixir
authentication do
  strategies do
    magic_link do
      identity_field :email
      sender MyApp.MagicLinkSender
    end
  end
end

# Sender implementation required
defmodule MyApp.MagicLinkSender do
  use AshAuthentication.Sender

  def send(user_or_email, token, _opts) do
    MyApp.Emails.deliver_magic_link(user_or_email, token)
  end
end
```

## API Key Strategy

```elixir
# 1. Create API key resource
defmodule MyApp.Accounts.ApiKey do
  use Ash.Resource,
    data_layer: AshPostgres.DataLayer,
    authorizers: [Ash.Policy.Authorizer]

  actions do
    defaults [:read, :destroy]

    create :create do
      primary? true
      accept [:user_id, :expires_at]
      change {AshAuthentication.Strategy.ApiKey.GenerateApiKey,
        prefix: :myapp, hash: :api_key_hash}
    end
  end

  attributes do
    uuid_primary_key :id
    attribute :api_key_hash, :binary, allow_nil?: false, sensitive?: true
    attribute :expires_at, :utc_datetime_usec, allow_nil?: false
  end

  relationships do
    belongs_to :user, MyApp.Accounts.User, allow_nil?: false
  end

  calculations do
    calculate :valid, :boolean, expr(expires_at > now())
  end

  identities do
    identity :unique_api_key, [:api_key_hash]
  end

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

# 2. Add strategy to user resource
authentication do
  strategies do
    api_key do
      api_key_relationship :valid_api_keys
      api_key_hash_attribute :api_key_hash
    end
  end
end

# 3. Add relationship to user
relationships do
  has_many :valid_api_keys, MyApp.Accounts.ApiKey do
    filter expr(valid)
  end
end

# 4. Add sign-in action to user
actions do
  read :sign_in_with_api_key do
    argument :api_key, :string, allow_nil?: false
    prepare AshAuthentication.Strategy.ApiKey.SignInPreparation
  end
end
```

**API Key Security:**
- Keys are hashed for storage
- Check `user.__metadata__[:using_api_key?]` for API key auth detection
- Access key via `user.__metadata__[:api_key]` for permission checks
- Use prefixes for secret scanning compliance

## OAuth2 Strategies

Providers: github, google, auth0, apple, oidc, slack

```elixir
authentication do
  strategies do
    github do
      client_id MyApp.Secrets
      client_secret MyApp.Secrets
      redirect_uri MyApp.Secrets
      identity_resource MyApp.Accounts.UserIdentity  # Optional
    end
  end
end

# Required action (replace 'github' with provider)
actions do
  create :register_with_github do
    argument :user_info, :map, allow_nil?: false
    argument :oauth_tokens, :map, allow_nil?: false
    upsert? true
    upsert_identity :unique_email

    change AshAuthentication.GenerateTokenChange
    change AshAuthentication.Strategy.OAuth2.IdentityChange  # If using UserIdentity

    change fn changeset, _ctx ->
      user_info = Ash.Changeset.get_argument(changeset, :user_info)
      Ash.Changeset.change_attributes(changeset, Map.take(user_info, ["email"]))
    end
  end
end
```

**Provider-specific requirements:**
- auth0: also needs `base_url`
- apple: also needs `team_id`, `private_key_id`, `private_key_path`
- oidc: also needs `openid_configuration_uri`

## Add-ons

### Confirmation

```elixir
authentication do
  tokens do
    enabled? true
    token_resource MyApp.Accounts.Token
  end

  add_ons do
    confirmation :confirm do
      monitor_fields [:email]
      sender MyApp.ConfirmationSender
    end
  end
end
```

### Log Out Everywhere

```elixir
authentication do
  tokens do
    store_all_tokens? true
  end

  add_ons do
    log_out_everywhere do
      apply_on_password_change? true
    end
  end
end
```

## Token Configuration

```elixir
authentication do
  tokens do
    enabled? true
    token_resource MyApp.Accounts.Token
    signing_secret MyApp.Secrets
    token_lifetime {24, :hours}
    store_all_tokens? true  # For logout-everywhere
    require_token_presence_for_authentication? false
  end
end
```

## Strategy Protocol

```elixir
# Get and use strategies
strategy = AshAuthentication.Info.strategy!(MyApp.User, :password)
{:ok, user} = AshAuthentication.Strategy.action(strategy, :sign_in, params)

# Token operations
subject = AshAuthentication.user_to_subject(user)
{:ok, user} = AshAuthentication.subject_to_user(subject, MyApp.User)
AshAuthentication.TokenResource.revoke(MyApp.Token, token)
```

## Customizing Authentication Actions

**Security Rules:**
- Mark credentials with `sensitive?: true` (passwords, API keys, tokens)
- Use `public?: false` for internal fields and sensitive PII
- Use `public?: true` for identity fields and UI display data
- Include required changes (`GenerateTokenChange`, `HashPasswordChange`)

```elixir
create :register_with_password do
  argument :password, :string, allow_nil?: false, sensitive?: true
  argument :first_name, :string, allow_nil?: false

  accept [:email, :first_name]

  change AshAuthentication.GenerateTokenChange
  change AshAuthentication.Strategy.Password.HashPasswordChange
end
```

## Policies

Always bypass for authentication interactions:

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

Related Skills

broken-authentication

16
from diegosouzapw/awesome-omni-skill

This skill should be used when the user asks to "test for broken authentication vulnerabilities", "assess session management security", "perform credential stuffing tests", "evaluate ...

authentication-setup

16
from diegosouzapw/awesome-omni-skill

Design and implement authentication and authorization systems. Use when setting up user login, JWT tokens, OAuth, session management, or role-based access control. Handles password security, token management, SSO integration.

ClaudeChatGPTGemini

nestjs-authentication

16
from diegosouzapw/awesome-omni-skill

Use this skill whenever the user wants to design, implement, or refactor authentication and authorization in a NestJS TypeScript backend, including JWT, sessions, refresh tokens, guards, roles/permissions, and integration with modules/services/controllers.

full-stack-authentication

16
from diegosouzapw/awesome-omni-skill

Implements production-ready authentication flows (sign-up, login, logout, session management) into any software stack using Scalekit SDK. Use when users need to add secure authentication, OAuth flows, SSO capabilities, or user management to their application. Handles code generation across Node.js, Python, Go, and Java with proper security patterns.

authentication

16
from diegosouzapw/awesome-omni-skill

Auth flows, session management, OAuth integration, domain-restricted access, and role-based access control for TopNetworks properties. Primary implementation is Better Auth 1.x with Google OAuth in route-genius. Use when implementing login, session checks, protected routes, or any access control logic.

two-factor-authentication-best-practices

16
from diegosouzapw/awesome-omni-skill

This skill provides guidance and enforcement rules for implementing secure two-factor authentication (2FA) using Better Auth's twoFactor plugin.

microsoft-azure-webjobs-extensions-authentication-events-dotnet

16
from diegosouzapw/awesome-omni-skill

Microsoft Entra Authentication Events SDK for .NET. Azure Functions triggers for custom authentication extensions.

Jwt Authentication

16
from diegosouzapw/awesome-omni-skill

This skill provides comprehensive patterns for implementing JWT (JSON Web Token) authentication in web applications. It covers token generation, verification, access/refresh token strategy, secure sto

authentication-authorization

16
from diegosouzapw/awesome-omni-skill

Authentication and authorization patterns using Clerk and RBAC

api-authentication

16
from diegosouzapw/awesome-omni-skill

Implement secure API authentication with JWT, OAuth 2.0, API keys, and session management. Use when securing APIs, managing tokens, or implementing user authentication flows.

bgo

10
from diegosouzapw/awesome-omni-skill

Automates the complete Blender build-go workflow, from building and packaging your extension/add-on to removing old versions, installing, enabling, and launching Blender for quick testing and iteration.

Coding & Development

code-archaeologist

16
from diegosouzapw/awesome-omni-skill

Deep historical context analysis for code evolution, risk assessment, and pattern compliance. Use BEFORE modifying any code to detect reverts, hotspots, god objects, and required patterns. Prevents repeating past mistakes by surfacing what was tried before and why it failed.