Agent skill

Auth Setup

by dilolabs in dilolabs/nosia

Implements custom passwordless authentication without Devise.

MITAuto-check passedBackend & APIs

Install Auth Setup

skills CLI
$ npx skills add dilolabs/nosia --skill auth-setup -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install dilolabs/nosia auth-setup --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/dilolabs/nosia.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.vibe/skills/auth-setup .claude/skills/auth-setup && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
auth-setup
GitHub stars
213
Used in
1 other repo
Token cost
~2.9k tokens
SKILL.md length
515 words
Files
3 (incl. references)
Skills in repo
15
Repo updated
First seen
Licence
MIT

At a glance

Implements custom passwordless authentication without Devise.

  • Works in 7 steps: Signed cookies: httponly: true,… → Passkey challenges: Signed, expiring… → Sign count tracking: Verify and update… → …
  • Setting up authentication
  • SKILL.md covers Your role, Core philosophy, Project knowledge and Commands, plus 15 more sections
  • Calls rails

What it does

Auth Setup is an agent skill from dilolabs/nosia. Implements custom passwordless authentication without Devise. Use when setting up authentication, login flows, session management, passkeys (WebAuthn), magic links, or password resets. Passkeys are the primary auth method; magic links are the fallback. WHEN NOT: For authorization/permissions (use controller concerns and role checks on User model). For multi-tenancy account scoping (see multi-tenant-setup skill).

Its SKILL.md is about 2.9k tokens, which your agent loads only when the skill is triggered. The skill folder holds 3 other files, including reference files (for example `references/auth-components.md` and `references/magic-links.md`). Compatibility notes: Ruby 3.3+, Rails 8.0+

It sits in Backend & APIs, covering Authentication. It works with Ruby on Rails. The repository describes itself as: Self-hosted AI RAG + MCP Platform. The licence is MIT.

When your agent uses it

  • Setting up authentication
  • Session management
  • Passkeys (WebAuthn)
  • Password resets

Example prompts

  • “Use the auth-setup skill to implement custom passwordless authentication without Devise”
  • “/auth-setup”

Requirements

  • Compatibility (from SKILL.md): Ruby 3.3+, Rails 8.0+

Workflow steps

7 steps, taken from the first numbered list in SKILL.md.

  1. Signed cookies: httponly: true, same_site: :lax, secure: Rails.env.production?
  2. Passkey challenges: Signed, expiring tokens (10 min registration, 5 min authentication) -- no server-side state
  3. Sign count tracking: Verify and update sign_count on each passkey authentication to detect cloned credentials
  4. Magic link expiry: 15 minutes, one-time use, mark as used immediately
  5. Rate limiting: rate_limit to: 10, within: 3.minutes on create actions (sessions and passkeys)
  6. Session cleanup: Recurring job to delete sessions > 30 days old
  7. Email normalization: normalizes :email_address, with: -> { _1.strip.downcase }

What it can do on your machine

Read from SKILL.md and the folder at commit 0ef5e5d. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • rails

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

  • Compatibility

    Ruby 3.3+, Rails 8.0+

    From compatibility in the SKILL.md frontmatter.

Context cost

Auth Setup loads about 2.9k tokens when it runs, and up to ~6.8k if it reads all its reference files. Until then it costs about 107 tokens; SKILL.md has 515 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~107
When it runs · the whole SKILL.md, loaded when a task matches
~2.9k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~6.8k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from dilolabs/nosia at commit 0ef5e5d, republished under its MIT licence (© dilolabs). 515 words, ~2,922 tokens.

Download SKILL.mdSave it as .claude/skills/auth-setup/SKILL.md (or your agent's skills folder). This skill also uses 2 other files; get the full folder from GitHub.
name
auth-setup
description
Implements custom passwordless authentication without Devise. Use when setting up authentication, login flows, session management, passkeys (WebAuthn), magic links, or password resets. Passkeys are the primary auth method; magic links are the fallback. WHEN NOT: For authorization/permissions (use controller concerns and role checks on User model). For multi-tenancy account scoping (see multi-tenant-setup skill).
compatibility
Ruby 3.3+, Rails 8.0+
license
MIT

You are an expert Rails authentication architect specializing in building auth from scratch.

Your role

  • Build custom authentication systems without Devise or other auth gems
  • Implement passkey (WebAuthn) authentication as the primary sign-in method
  • Implement passwordless magic link authentication as the fallback
  • Keep auth simple: ~200 lines of code total
  • Output: Clean session management, passkeys, magic links, and Current attributes setup

Core philosophy

Auth is simple. Don't use Devise. A basic auth system is ~200 lines of code. You get full control, no bloat, easier modifications, and no gem version conflicts.

What you actually need (not Devise's 50+ columns):
  • Identity model (email + has_passkeys + optional password hash)
  • Passkey model (WebAuthn credentials, via ActionPack::Passkey)
  • Session model (token-based, database-stored)
  • Magic link model (passwordless login fallback)
  • Authentication concern (~100 lines)
  • Current attributes (request context)

Project knowledge

Tech Stack: Rails 8.2 (edge), ActionPack::Passkey (built-in WebAuthn), BCrypt for passwords (optional), has_secure_token Pattern: Passkeys (WebAuthn) primary, magic links fallback, password optional for APIs Session storage: Database (not cookies), token-based

Commands

  • bin/rails generate model Identity email_address:string password_digest:string
  • bin/rails test test/controllers/sessions_controller_test.rb
  • bin/rails console then Identity.authenticate_by(email_address: "test@example.com")

Architecture overview

Identity (email, has_passkeys, optional password)
  |-- has_many :passkeys (WebAuthn credentials, primary auth)
  |-- has_many :sessions (token-based, database)
  |-- has_many :magic_links (passwordless login fallback)
  |-- has_one :user (app-specific profile data)

ActionPack::Passkey (credential_id, public_key, sign_count, transports)
Session (has_secure_token, 30-day expiry)
MagicLink (6-char code, 15-min expiry, one-time use)
Current (session, identity, user, account context)

Routes configuration

ruby
Rails.application.routes.draw do
  resource :session do
    scope module: :sessions do
      resource :magic_link
      resource :passkey, only: :create  # Passkey authentication
    end
  end

  # Passkey management (authenticated users)
  namespace :my do
    resource :passkey_challenge, only: :create  # WebAuthn challenge endpoint
    resources :passkeys, except: %i[ show new ]  # Register, rename, remove
  end

  resource :signup, only: [:new, :create]  # Optional
  root "boards#index"
end

Note: The ActionPack::Passkey railtie also auto-mounts a challenge endpoint at /rails/action_pack/passkey/challenge for the WebAuthn ceremony. The my/passkey_challenge route above overrides it with app-specific auth.

Sessions controller

The sessions controller includes ActionPack::Passkey::Request and generates passkey authentication options on new so the sign-in page can offer passkey autofill (conditional mediation).

ruby
class SessionsController < ApplicationController
  include ActionPack::Passkey::Request

  allow_unauthenticated_access only: [:new, :create]
  rate_limit to: 10, within: 3.minutes, only: :create

  def new
    @authentication_options = passkey_authentication_options  # For passkey sign-in
  end

  def create
    if identity = Identity.find_by(email_address: params[:email_address])
      identity.send_magic_link
      redirect_to new_session_path, notice: "Check your email for a sign-in link"
    else
      redirect_to new_session_path, alert: "No account found with that email"
    end
  end

  def destroy
    terminate_session
    redirect_to root_path
  end
end

Passkey authentication controller

Handles the WebAuthn assertion ceremony when a user signs in with a passkey. The ActionPack::Passkey.authenticate method looks up the credential by ID, verifies the signature against the stored public key, and returns the passkey record (or nil).

ruby
class Sessions::PasskeysController < ApplicationController
  include ActionPack::Passkey::Request

  allow_unauthenticated_access
  rate_limit to: 10, within: 3.minutes, only: :create

  def create
    if credential = ActionPack::Passkey.authenticate(passkey_authentication_params)
      start_new_session_for credential.holder
      redirect_to root_path
    else
      redirect_to new_session_path, alert: "That passkey didn't work. Try again."
    end
  end
end

Passkey management controllers

Authenticated users register, rename, and remove their passkeys via the My::PasskeysController.

ruby
class My::PasskeysController < ApplicationController
  include ActionPack::Passkey::Request

  before_action :set_passkey, only: %i[ edit update destroy ]

  def index
    @passkeys = Current.identity.passkeys.order(name: :asc, created_at: :desc)
    @registration_options = passkey_registration_options(holder: Current.identity)
  end

  def create
    passkey = Current.identity.passkeys.register(passkey_registration_params)
    redirect_to edit_my_passkey_path(passkey, created: true)
  end

  def edit; end

  def update
    @passkey.update!(params.expect(passkey: [ :name ]))
    redirect_to my_passkeys_path
  end

  def destroy
    @passkey.destroy!
    redirect_to my_passkeys_path
  end

  private
    def set_passkey
      @passkey = Current.identity.passkeys.find(params[:id])
    end
end

# WebAuthn challenge endpoint (inherits from framework controller)
class My::PasskeyChallengesController < ActionPack::Passkey::ChallengesController
  include Authentication
  allow_unauthenticated_access
end
ruby
class Sessions::MagicLinksController < ApplicationController
  allow_unauthenticated_access

  def show
    if magic_link = MagicLink.authenticate(params[:code])
      start_new_session_for(magic_link.identity)
      redirect_to session.delete(:return_to) || root_path, notice: "Signed in successfully"
    else
      redirect_to new_session_path, alert: "Invalid or expired link"
    end
  end
end

Current attributes

ruby
class Current < ActiveSupport::CurrentAttributes
  attribute :session, :identity, :user, :account
  attribute :user_agent, :ip_address

  def account=(account)
    super
    Time.zone = account&.timezone
  end

  resets { Time.zone = "UTC" }
end
ruby
class MagicLinkMailer < ApplicationMailer
  def sign_in_instructions(magic_link)
    @magic_link = magic_link
    @identity = magic_link.identity
    @url = session_magic_link_url(code: magic_link.code)
    mail to: @identity.email_address, subject: "Sign in to #{app_name}"
  end
end

Session cleanup job

ruby
class SessionCleanupJob < ApplicationJob
  def perform
    Session.where("created_at < ?", 30.days.ago).delete_all
    MagicLink.where("expires_at < ?", 1.day.ago).delete_all
  end
end

# config/recurring.yml
# production:
#   cleanup_old_sessions:
#     command: "SessionCleanupJob.perform_later"
#     schedule: every day at 3am

Signup flow (optional)

ruby
class Signup
  include ActiveModel::Model

  attr_accessor :email_address, :full_name, :password

  validates :email_address, presence: true, format: { with: URI::MailTo::EMAIL_REGEXP }
  validates :full_name, presence: true

  def save
    return false unless valid?

    ActiveRecord::Base.transaction do
      @identity = Identity.create!(email_address: email_address, password: password)
      @identity.create_user!(full_name: full_name)
      @identity.send_magic_link(purpose: "verify_email")
    end
    true
  rescue ActiveRecord::RecordInvalid
    false
  end

  def identity = @identity
end
Show full SKILL.md (218 more words)Show less

View examples

erb
<%# app/views/sessions/new.html.erb %>
<%# The email field uses autocomplete="username webauthn" so browsers offer passkey autofill %>
<h1>Sign In</h1>
<%= form_with url: session_path do |f| %>
  <div>
    <%= f.label :email_address, "Email" %>
    <%= f.email_field :email_address, required: true, autofocus: true,
        autocomplete: "username webauthn" %>
  </div>
  <%= f.submit "Send magic link" %>
<% end %>

<%# Passkey sign-in button with conditional mediation (autofill UI) %>
<%= passkey_sign_in_button "Sign in with a passkey", session_passkey_path,
    options: @authentication_options, mediation: "conditional", hidden: true %>

<%# Layout header %>
<% if authenticated? %>
  <span>Signed in as <%= current_user.full_name %></span>
  <%= button_to "Sign out", session_path, method: :delete %>
<% else %>
  <%= link_to "Sign in", new_session_path %>
<% end %>

The passkey_sign_in_button helper renders a <rails-passkey-sign-in-button> web component that handles the WebAuthn ceremony. With mediation: "conditional", the browser automatically offers passkey autofill in the email field -- no extra click needed.

Security checklist

  1. Signed cookies: httponly: true, same_site: :lax, secure: Rails.env.production?
  2. Passkey challenges: Signed, expiring tokens (10 min registration, 5 min authentication) -- no server-side state
  3. Sign count tracking: Verify and update sign_count on each passkey authentication to detect cloned credentials
  4. Magic link expiry: 15 minutes, one-time use, mark as used immediately
  5. Rate limiting: rate_limit to: 10, within: 3.minutes on create actions (sessions and passkeys)
  6. Session cleanup: Recurring job to delete sessions > 30 days old
  7. Email normalization: normalizes :email_address, with: -> { _1.strip.downcase }

Testing authentication

ruby
# test/test_helper.rb
class ActionDispatch::IntegrationTest
  def sign_in_as(user)
    session_record = user.identity.sessions.create!
    cookies.signed[:session_token] = session_record.token
  end

  def sign_out
    cookies.delete(:session_token)
  end
end
ruby
class SessionsControllerTest < ActionDispatch::IntegrationTest
  test "create sends magic link" do
    identity = identities(:david)
    assert_enqueued_emails 1 do
      post session_path, params: { email_address: identity.email_address }
    end
    assert_redirected_to new_session_path
  end

  test "destroy terminates session" do
    sign_in_as users(:david)
    delete session_path
    assert_redirected_to root_path
    assert_nil cookies[:session_token]
  end
end

Boundaries

  • Always: Offer passkeys as primary auth, use signed cookies with httponly/same_site flags, expire magic links (15 min), mark magic links as used, normalize emails, use has_secure_token, clean up old sessions, track passkey sign counts
  • Ask first: Before adding password auth (prefer passwordless), before adding OAuth, before implementing custom attestation verifiers
  • Never: Use Devise (unless already in project), store tokens in plain cookies, reuse magic links, skip rate limiting, store WebAuthn challenges in server-side session state (use signed tokens)

Reference files

  • references/auth-components.md -- Detailed model implementations, passkey setup, and Authentication concern
  • references/magic-links.md -- Magic link flow, token generation, expiry patterns

© dilolabs, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 2 other files (references) in .vibe/skills/auth-setup of dilolabs/nosia.

  • SKILL.md
  • references/auth-components.md
  • references/magic-links.md

Open the folder on GitHubat commit 0ef5e5d

Used in 1 other repository

We found 3 copies of this SKILL.md (exact, near-identical or edited) in other folders, from 1 other GitHub owner. This page covers the copy in dilolabs/nosia, which our catalogue first saw on October 7, 2026.

Compare with similar skills

Auth Setup next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Auth Setup compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Auth Setup this skilldilolabs/nosia2131 repos~2.9kAutomated safety check: PassMIT
Authentication FlowThibautBaissac/rails_ai_agents665—~1.9kAutomated safety check: PassMIT
Fortify Developmentcoollabsio/coolify63k4 repos~1.9kAutomated safety check: PassMIT
Supabase Development and Debuggingsupabase/agent-skills2.7k3 repos~3.6kAutomated safety check: PassMIT
Better Auth Best Practiceslatitude-dev/latitude-llm4.7k7 repos~1.6kAutomated safety check: PassMIT
Supabasecurvenote/curvenote1695 repos~2.2kAutomated safety check: PassCustom licence

Similar skills

  • Authentication Flow

    ThibautBaissac/rails_ai_agents

    Implements authentication using Rails 8 built-in generator. An agent skill from ThibautBaissac/rails_ai_agents.

    665 GitHub stars~1.9k tokensUpdated 4 mo ago
    Backend & APIsAuto-check passed
  • Fortify Development

    coollabsio/coolify

    ACTIVATE when the user works on authentication in Laravel. An agent skill from coollabsio/coolify.

    63k GitHub starsUsed in 4 repos~1.9k tokens
    Backend & APIsAuto-check passed
  • Official

    General Supabase skill for database, auth, Edge Functions, Realtime and storage work, plus client libraries, migrations, security audits, debugging and reading logs.

    2.7k GitHub starsUsed in 3 repos~3.6k tokens
    Backend & APIsAuto-check passed
  • Better Auth Best Practices

    latitude-dev/latitude-llm

    Configure Better Auth server and client, set up database adapters, manage sessions, add plugins, and handle environment variables.

    4.7k GitHub starsUsed in 7 repos~1.6k tokens
    Backend & APIsAuto-check passed
  • Supabase

    curvenote/curvenote

    A skill your agent uses when doing ANY task involving Supabase.

    169 GitHub starsUsed in 5 repos~2.2k tokens
    Backend & APIsAuto-check passed
  • Gitnexus Exploring

    aws-samples/sample-kolya-br-proxy

    Official

    A skill your agent uses when the user asks how code works, wants to understand architecture, trace execution flows, or explore unfamiliar parts of the codebase.

    106 GitHub starsUsed in 11 repos~749 tokens
    Backend & APIsAuto-check passed

More from dilolabs/nosia

All 15 skills in this repo
  • API Patterns

    dilolabs/nosia

    Builds REST APIs using respondto blocks with Jbuilder templates following the 37signals same-controllers-different-formats philosophy.

    213 GitHub starsUsed in 1 repo~2.5k tokens
    Auto-check passed
  • Caching Patterns

    dilolabs/nosia

    Implements HTTP caching with ETags, fragment caching, Russian doll caching, and Solid Cache configuration.

    213 GitHub starsUsed in 1 repo~1.9k tokens
    Auto-check passed
  • Concern Patterns

    dilolabs/nosia

    Creates and refactors model and controller concerns for shared behavior.

    213 GitHub starsUsed in 1 repo~1.8k tokens
    Auto-check passed
  • Event Tracking

    dilolabs/nosia

    Builds event tracking, activity feeds, and webhook systems following 37signals patterns with a generic Event model and Eventable concern.

    213 GitHub starsUsed in 1 repo~3.3k tokens
    Auto-check passed
  • Job Patterns

    dilolabs/nosia

    Implements shallow background jobs with later/now conventions using Solid Queue.

    213 GitHub starsUsed in 1 repo~1.6k tokens
    Auto-check passed
  • Mailer Patterns

    dilolabs/nosia

    Creates minimal Action Mailer classes with bundled notification patterns following 37signals conventions.

    213 GitHub starsUsed in 1 repo~2.6k tokens
    Auto-check passed

Works with

Categories

Questions about Auth Setup

What does Auth Setup do?

Implements custom passwordless authentication without Devise. Auth Setup is an agent skill from dilolabs/nosia. Implements custom passwordless authentication without Devise.

When should I use Auth Setup?

Auth Setup fits situations like: setting up authentication; session management; passkeys (WebAuthn); password resets.

How do I install Auth Setup in Claude Code?

Run `npx skills add dilolabs/nosia --skill auth-setup -a claude-code`. Or copy the skill folder (.vibe/skills/auth-setup in dilolabs/nosia) into .claude/skills/auth-setup in your project. Claude Code loads it when a task matches its description.

How do I install Auth Setup in Codex?

Run `npx skills add dilolabs/nosia --skill auth-setup -a codex`. Or copy the skill folder (.vibe/skills/auth-setup in dilolabs/nosia) into .agents/skills/auth-setup in your project. Codex loads it when a task matches its description.

Can I use Auth Setup in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add dilolabs/nosia --skill auth-setup -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/auth-setup, .gemini/skills/auth-setup, .github/skills/auth-setup and .opencode/skills/auth-setup in your project.

What does Auth Setup need to run?

Going by SKILL.md and its folder, Auth Setup needs the command-line tools its instructions call (rails). Compatibility (from SKILL.md): Ruby 3.3+, Rails 8.0+.

Does Auth Setup access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Auth Setup safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Auth Setup use?

Auth Setup is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Auth Setup use?

About 2.9k tokens (SKILL.md is roughly 12k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 3.9k tokens, read only when the agent opens those files.

What are the alternatives to Auth Setup?

Skills that share tags, products or a category with Auth Setup: Authentication Flow (ThibautBaissac/rails_ai_agents, 665 stars), Fortify Development (coollabsio/coolify, 63k stars), Supabase Development and Debugging (supabase/agent-skills, 2.7k stars) and Better Auth Best Practices (latitude-dev/latitude-llm, 4.7k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Auth Setup?

dilolabs (a GitHub organization) maintains it in dilolabs/nosia, which has 213 GitHub stars. The repository holds 15 skills in this directory. The repository was last updated on September 9, 2026.

Source: dilolabs/nosia on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.