Communitygithub.com

laravel-security

Laravelセキュリティのベストプラクティス — 認証、認可、Eloquentの安全性、CSRF、XSS防止、APIセキュリティ、安全なデプロイ設定。Laravelの認証、Eloquentの安全性、CSRF、XSS、APIセキュリティ、デプロイ設定をレビューする際に使用します。

laravel-security とは?

このスキルは、Laravelアプリケーションにおける包括的なセキュリティガイドラインを提供します。認証(Sanctum、Passport、Jetstream、Breeze)、認可(ゲート、ポリシー、ミドルウェア)、Eloquentの安全な使用方法(マスアサインメント対策、SQLインジェクション防止、属性キャスト)、CSRF保護、XSS防止、そして本番環境の安全な設定(HTTPS強制、環境変数の管理、信頼プロキシの設定)など、主要な脆弱性に対する対策を網羅しています。Laravelアプリケーションの開発、レビュー、デプロイ時にアクティベートすることで、安全なコードを記述し、一般的なセキュリティ問題を防止できます。Claude CodeやClineのようなAIエージェントで利用可能で、SKILL.mdには具体的なコード例と設定方法が記載されています。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/everything-claude-code/tree/main/skills/laravel-security

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

Laravelセキュリティのベストプラクティス

Laravelアプリケーションを一般的な脆弱性から保護するための包括的なセキュリティガイドラインです。

いつアクティベートするか

  • Laravelの認証と認可(Sanctum、Passport、Jetstream、Breeze)のセットアップ
  • ユーザーロール、権限、ポリシーの実装
  • 本番セキュリティ設定と環境変数の構成
  • Laravelアプリケーションのセキュリティ脆弱性のレビュー
  • Laravelアプリケーションの本番デプロイ
  • 安全なEloquentクエリとマイグレーションの作成

本番設定

必須の本番設定

// config/app.php
'env' => env('APP_ENV', 'production'),
'debug' => (bool) env('APP_DEBUG', false), // 重要: 本番では常にfalse
'key' => env('APP_KEY'), // 必ず設定: php artisan key:generate

// config/session.php
'secure' => env('SESSION_SECURE_COOKIE', true),
'http_only' => true,
'same_site' => 'lax',

// 起動時にAPP_KEYを確認
// bootstrap/app.php またはサービスプロバイダー
if (empty(config('app.key'))) {
    throw new RuntimeException('APP_KEYが設定されていません。php artisan key:generateを実行してください。');
}

環境ファイルのセキュリティ

# .envをバージョン管理に絶対にコミットしない
# .gitignoreにはデフォルトで.envが含まれています

# 代わりにプレースホルダー付きの.env.exampleを使用
DB_PASSWORD=
APP_KEY=
SANCTUM_TOKEN_PREFIX=

# 起動時に必須変数を検証
// AppServiceProvider::boot()
$requiredKeys = ['app.key', 'database.connections.mysql.database', 'database.connections.mysql.username'];
foreach ($requiredKeys as $key) {
    if (empty(config($key))) {
        throw new RuntimeException("必須設定キーが不足しています: {$key}");
    }
}

HTTPSの強制

// AppServiceProvider::boot() またはミドルウェア
if (app()->environment('production')) {
    URL::forceScheme('https');
    request()->server->set('HTTPS', 'on');
}

// config/app.php の信頼プロキシ設定(ロードバランサー)
// 特定のIP範囲を使用 — * はすべてを信頼し、X-Forwarded-*のなりすましを許可
// AWS: '10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16'
'trusted_proxies' => ['10.0.0.0/8', '172.16.0.0/12'],

// ミドルウェアで本番環境のHTTPSを強制
// app/Http/Middleware/ForceHttps.php
public function handle($request, Closure $next)
{
    if (!$request->secure() && app()->environment('production')) {
        return redirect()->secure($request->getRequestUri());
    }
    return $next($request);
}

認証

Sanctum(APIトークン認証)

// config/sanctum.php
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
    '%s%s',
    'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
    env('APP_URL') ? ',' . parse_url(env('APP_URL'), PHP_URL_HOST) : ''
)));

'expiration' => 60 * 24, // トークンの有効期限(分)、null = 無期限
'token_prefix' => env('SANCTUM_TOKEN_PREFIX', ''),

// アビリティ付きトークンの発行
$token = $user->createToken('api-token', ['read', 'write'])->plainTextToken;

// ルートでのアビリティ検証
Route::middleware('auth:sanctum')->group(function () {
    Route::get('/orders', function () {
        // ユーザーに'read'アビリティが必要
        abort_unless(Auth::user()->tokenCan('read'), 403);
        // ...
    })->middleware('abilities:read');

    Route::post('/orders', function () {
        // ユーザーに'write'アビリティが必要
        abort_unless(Auth::user()->tokenCan('write'), 403);
        // ...
    })->middleware('abilities:write');
});

パスワードセキュリティ

// config/hashing.php
// デフォルトはbcrypt。Argon2idの方が強力。
'bcrypt' => [
    'rounds' => env('BCRYPT_ROUNDS', 12), // 増やすとハッシュが強力に
],

'argon' => [
    'memory' => 65536,
    'threads' => 4,
    'time' => 4,
],

// RegisterRequestでのパスワードバリデーション
public function rules(): array
{
    return [
        'password' => [
            'required',
            'confirmed',
            Password::min(12)
                ->letters()
                ->mixedCase()
                ->numbers()
                ->symbols()
                ->uncompromised(), // haveibeenpwnedをチェック
        ],
    ];
}

// ログイン試行をレート制限
// App\Http\Controllers\Auth\AuthenticatedSessionController
protected function authenticated(Request $request, $user)
{
    if ($user->wasRecentlyLockedOut()) {
        // 不審なログインをユーザーに通知
        $user->notify(new SuspiciousLoginNotification($request->ip()));
    }
}

セッション管理

// config/session.php
'driver' => env('SESSION_DRIVER', 'database'), // database/redis > file
'lifetime' => env('SESSION_LIFETIME', 120),
'expire_on_close' => env('SESSION_EXPIRE_ON_CLOSE', false),
'encrypt' => env('SESSION_ENCRYPT', false),

// ログイン時にセッションを再生成
// App\Http\Controllers\Auth\AuthenticatedSessionController
public function store(LoginRequest $request): RedirectResponse
{
    $request->authenticate();
    $request->session()->regenerate(); // 重要: セッション固定攻撃を防止
    return redirect()->intended(RouteServiceProvider::HOME);
}

// ログアウト時にセッションを無効化
public function destroy(Request $request): RedirectResponse
{
    Auth::guard('web')->logout();
    $request->session()->invalidate();
    $request->session()->regenerateToken();
    return redirect('/');
}

認可

ゲート

// App\Providers\AuthServiceProvider
use App\Models\Post;
use App\Models\User;
use Illuminate\Support\Facades\Gate;

public function boot(): void
{
    Gate::define('update-post', function (User $user, Post $post): bool {
        return $user->id === $post->user_id;
    });

    Gate::define('publish-post', function (User $user): bool {
        return $user->role === 'editor' || $user->role === 'admin';
    });

    // スーパー管理者のオーバーライドにbefore()を使用
    Gate::before(function (User $user, string $ability): ?bool {
        if ($user->role === 'super-admin') {
            return true; // すべてのアビリティを許可
        }
        return null; // 通常のチェックにフォールスルー
    });
}

// コントローラーでの使用
public function update(Request $request, Post $post): RedirectResponse
{
    Gate::authorize('update-post', $post);
    // または $this->authorize('update-post', $post);
    // または abort_unless(Auth::user()->can('update-post', $post), 403);
    // ...
}

ポリシー

// App\Policies\PostPolicy
class PostPolicy
{
    use HandlesAuthorization;

    public function viewAny(?User $user): bool
    {
        return true; // 公開リスト
    }

    public function view(?User $user, Post $post): bool
    {
        return $post->is_published || ($user && $user->id === $post->user_id);
    }

    public function create(User $user): bool
    {
        return $user->hasVerifiedEmail(); // メール確認が必要
    }

    public function update(User $user, Post $post): bool
    {
        return $user->id === $post->user_id;
    }

    public function delete(User $user, Post $post): bool
    {
        return $user->id === $post->user_id && $post->created_at->diffInDays(now()) <= 30;
    }

    public function restore(User $user, Post $post): bool
    {
        return $user->role === 'admin';
    }

    public function forceDelete(User $user, Post $post): bool
    {
        return $user->role === 'super-admin';
    }
}

// AuthServiceProviderで登録
protected $policies = [
    Post::class => PostPolicy::class,
];

// コントローラーでの使用
public function show(Post $post): View
{
    $this->authorize('view', $post);
    return view('posts.show', compact('post'));
}

// Bladeでの使用
@can('update', $post)
    <a href="{{ route('posts.edit', $post) }}">編集</a>
@endcan

@cannot('update', $post)
    <span>この投稿は編集できません</span>
@endcannot

ミドルウェアによる認可

// ルートでのミドルウェア使用
Route::put('/posts/{post}', [PostController::class, 'update'])
    ->middleware('can:update,post');

Route::get('/posts/create', [PostController::class, 'create'])
    ->middleware('can:create,App\Models\Post');

// カスタム認可ミドルウェア
// app/Http/Middleware/CheckRole.php
class CheckRole
{
    public function handle(Request $request, Closure $next, string $role): mixed
    {
        if (!$request->user() || $request->user()->role !== $role) {
            abort(403, 'Unauthorized. This area requires role: ' . $role);
        }
        return $next($request);
    }
}

// Kernelで登録
protected $routeMiddleware = [
    'role' => \App\Http\Middleware\CheckRole::class,
];

// ルートの使用
Route::middleware(['auth', 'role:admin'])->group(function () {
    Route::get('/admin', [AdminController::class, 'index']);
});

Eloquentのセキュリティ

マスアサインメント対策

// 悪い例: $guarded = [] はすべてのカラムをマスアサイン可能にする
// 本番で $guarded = [] を絶対に使用しない

// 良い例: フィル可能な属性をホワイトリスト化
final class User extends Authenticatable
{
    protected $fillable = [
        'name',
        'email',
        'phone',
        'avatar',
    ];
    // 'role', 'is_admin', 'is_verified' は絶対に追加しない
}

// 良い例: リクエストでどのフィールドを入力できるか明示的に制御
public function store(StoreUserRequest $request): RedirectResponse
{
    $user = User::create($request->safe()->only([
        'name', 'email', 'phone', 'avatar'
    ]));
    // $request->safe() はバリデーション済みデータのみ使用
    // $request->only() はバリデーションルールなしでは安全ではない
}

// 悪い例: リクエストデータで直接ユーザーを作成
User::create($request->all()); // マスアサインメントに脆弱!

// より良い例: DTOを使用して作成
$user = User::create($request->validated()); // バリデーション済みフィールドのみ

SQLインジェクション防止

// 良い例: Eloquentは自動的にクエリをパラメータ化
User::where('email', $userInput)->first();
User::whereRaw('email = ?', [$userInput])->first();

// 良い例: クエリビルダーもパラメータ化
DB::table('users')->where('email', $userInput)->first();
DB::select('SELECT * FROM users WHERE email = ?', [$userInput]);

// 悪い例: 生の文字列補間
DB::select("SELECT * FROM users WHERE email = '{$userInput}'"); // 脆弱!
User::whereRaw("email = '{$userInput}'")->first(); // 脆弱!

// 悪い例: エスケープされていない入力でのwhereRaw/orderByRaw
User::orderByRaw($userInput); // 脆弱!
User::groupByRaw($userInput); // 脆弱!

// 悪い例: 連結を使用したDB::statement
DB::statement("INSERT INTO users (email) VALUES ('{$userInput}')"); // 脆弱!

属性キャスト

final class User extends Authenticatable
{
    protected $casts = [
        'email_verified_at' => 'datetime',
        'is_admin' => 'boolean', // ブール変換で文字列注入を防止
        'settings' => 'array', // 自動的にjson_encode/json_decode
        'metadata' => 'encrypted:array', // Laravel 11+ 暗号化キャスト
        'password' => 'hashed', // Laravel 10+ 自動ハッシュ化
    ];
}

モデルセキュリティ

final class User extends Authenticatable
{
    // JSON/APIレスポンスから機密属性を隠す
    protected $hidden = [
        'password',
        'remember_token',
        'two_factor_secret',
        'two_factor_recovery_codes',
    ];

    // 安全な計算済み属性のみ追加
    protected $appends = ['full_name']; // 安全
    // 機密データを含む計算済み属性は絶対に追加しない
}

final class Post extends Model
{
    // 論理削除レコードをフィルタリングするグローバルスコープ
    use SoftDeletes;

    // 遅延読み込みを制限してN+1問題を防止(オプションの厳格モード)
    // AppServiceProvider::boot()
    // Model::preventLazyLoading(!app()->isProduction());
}

CSRF保護

デフォルトの保護

// LaravelのCSRFはVerifyCsrfTokenミドルウェアでデフォルト有効
// app/Http/Kernel.php (protected $middlewareGroups['web'])

// すべてのPOST/PUT/PATCH/DELETEフォームには@csrfを含める
<form method="POST" action="/posts">
    @csrf
    <input type="text" name="title">
    <button type="submit">作成</button>
</form>

ルートの除外(注意して)

// app/Http/Middleware/VerifyCsrfToken.php
class VerifyCsrfToken extends Middleware
{
    // 外部のCSRF保護があるルートのみ除外(webhookなど)
    protected $except = [
        'stripe/*', // Stripe webhookは独自の署名検証を使用
        // 総称的な 'api/*' は避ける — ステートフルなSanctumルートはCSRFが必要。
        // 特定のステートレスなwebhook/エンドポイントルートのみ除外。
    ];
}

JavaScriptでのCSRF

<meta name="csrf-token" content="{{ csrf_token() }}">

<script>
// Axiosの例(LaravelにはAxiosが同梱)
axios.defaults.headers.common['X-CSRF-TOKEN'] = document.querySelector(
    'meta[name="csrf-token"]'
).getAttribute('content');

// Fetchの例
fetch('/posts', {
    method: 'POST',
    headers: {
        'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
        'Content-Type': 'application/json',
    },
    body: JSON.stringify(data),
});
</script>

XSS防止

Bladeテンプレートのセキュリティ

{{-- 安全: Bladeによって自動エスケープ --}}
{{ $userInput }}

{{-- 危険: 生の出力 — ユーザー入力に絶対に使用しない --}}
{!! $userInput !!}

{{-- 安全: 自分で制御する信頼できるコンテンツにのみ{!! !!}を使用 --}}
{!! $trustedHtmlFromYourServer !!}

{{-- 良い例: 特定のエスケープディレクティブを使用 --}}
@js($data) {{-- JavaScript用にJSONエンコード --}}
@json($data) {{-- テンプレート内でJSONエンコード --}}

{{-- 悪い例: 生のHTML内での直接ユーザー入力 --}}
<div>{!! $user->bio !!}</div> {{-- ユーザーがbioを提供する場合脆弱 --}}

安全なHTML処理

// 一部のHTMLを許可する必要がある場合は、ホワイトリストアプローチを使用
use HTMLPurifier; // 必要: composer require ezyang/htmlpurifier

public function sanitizeHtml(string $dirty): string
{
    $config = \HTMLPurifier_Config::createDefault();
    $config->set('HTML.Allowed', 'p,b,i,a[href],ul,ol,li,br');
    $config->set('URI.AllowedSchemes', ['http', 'https', 'mailto']);
    $purifier = new \HTMLPurifier($config);
    return $purifier->purify($dirty);
}

// Blade内:
<div>{!! $sanitizedBio !!}</div>

Content Security Policy(CSP)

// config/csp.php
return [
    'policy' => [
        'default-src' => ["'self'"],
        'script-src' => ["'self'", "'strict-dynamic'"],
        'style-src' => ["'self'", "'unsafe-inline'"],
        'img-src' => ["'self'", 'https:', 'data:'],
        'font-src' => ["'self'", 'https:', 'data:'],
        'form-action' => ["'self'"],
        'frame-ancestors' => ["'none'"],
        'base-uri' => ["'self'"],
    ],
];

// ミドルウェアで適用
// app/Http/Middleware/SecurityHeaders.php
public function handle(Request $request, Closure $next): Response
{
    $response = $next($request);
    
    $response->headers->set('Content-Security-Policy', $this->buildCspHeader());
    $response->headers->set('X-Frame-Options', 'DENY');
    $response->headers->set('X-Content-Type-Options', 'nosniff');
    $response->headers->set('Referrer-Policy', 'strict-origin-when-cross-origin');
    
    return $response;
}

APIセキュリティ

レート制限

// app/Http/Kernel.php
protected $middlewareGroups = [
    'api' => [
        \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
        'throttle:api',
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
];

// app/Providers/RouteServiceProvider.php
// カスタムレート制限
RateLimiter::for('api', function (Request $request) {
    $userId = $request->user()?->id ?: $request->ip();
    return Limit::perMinute(60)->by($userId);
});

RateLimiter::for('login', function (Request $request) {
    return Limit::perMinute(5)->by($request->ip());
});

// config/fortify.php (Laravel Fortify使用時)
'limiters' => [
    'login' => 5, // 1分間のログイン試行
    'two-factor' => 3, // 2FA試行
],

CORS設定

// config/cors.php
return [
    'paths' => ['api/*', 'sanctum/csrf-cookie'],
    'allowed_methods' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
    'allowed_origins' => explode(',', env('CORS_ALLOWED_ORIGINS', '')),
    'allowed_headers' => ['Content-Type', 'X-Requested-With', 'X-CSRF-TOKEN', 'Authorization'],
    'exposed_headers' => ['Content-Disposition'],
    'max_age' => 0,
    'supports_credentials' => true, // Sanctum使用時はtrue
];

APIレスポンスのセキュリティ

// app/Http/Responses/ApiResponse.php (一貫したレスポンス形式)
final class ApiResponse
{
    public static function success(mixed $data = null, string $message = '成功', int $code = 200): JsonResponse
    {
        return response()->json([
            'success' => true,
            'message' => $message,
            'data' => $data,
        ], $code);
    }

    public static function error(string $message, int $code = 400, mixed $errors = null): JsonResponse
    {
        $response = [
            'success' => false,
            'message' => $message,
        ];
        
        if ($errors !== null) {
            // デバッグ情報を漏らさない
            if (app()->environment('production')) {
                $response['errors'] = 'リクエストの処理中にエラーが発生しました。';
            } else {
                $response['errors'] = $errors;
            }
        }
        
        return response()->json($response, $code);
    }
}

デプロイメントのセキュリティ

依存関係の監査

# Laravelのセキュリティアドバイザリをチェック
composer audit

# npmパッケージの脆弱性をチェック
npm audit

# スケジュールされたセキュリティアップデート用のGitHub Dependabotを設定
# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: "composer"
    directory: "/"
    schedule:
      interval: "weekly"
      day: "monday"
      time: "09:00"
      timezone: "Asia/Tokyo"
    open-pull-requests-limit: 10

本番環境の必須チェックリスト

  • APP_DEBUGがfalseに設定されている
  • APP_KEYが生成され、安全に保存されている
  • HTTPSが強制されている
  • データベース接続がSSLを使用している
  • セッションドライバーがfileではなくdatabase/redisである
  • キュードライバーが同期ではなくdatabase/redisである
  • キャッシュドライバーがfile/arrayではなくredis/databaseである
  • ファイルシステムのアクセス権限が適切である(ストレージディレクトリのchmod 755)
  • エラーレポートがスタックトレースを表示していない
  • メールドライバーがlogではなくsmtp/sesである
  • CSRF保護が有効である
  • CORSが適切に設定されている(Sanctumの場合はオリジン制限)
  • APIエンドポイントがレート制限されている
  • PHPバージョンが最新の安定版(8.2+)である
  • Composerのautoloadが最適化されている(composer install --optimize --no-dev)
  • APIキャッシュが設定されている(php artisan route:cache, config:cache)
  • データベース接続が読み取り/書き込みの分離を使用している
  • メール検証が有効である('verified'ミドルウェア)
  • Sanctumトークンに有効期限が設定されている
  • パスワードポリシーが設定されている(最小12文字、特殊文字)

サーバーレベルのセキュリティ

# nginx設定の例
server {
    listen 443 ssl http2;
    server_name example.com;
    
    # SSL設定
    ssl_certificate /etc/ssl/certs/example.com.crt;
    ssl_certificate_key /etc/ssl/private/example.com.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    
    # セキュリティヘッダー
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    
    # 隠しLaravelディレクトリへのアクセスをブロック
    location ~ /(config|database|resources|storage|vendor)/ {
        deny all;
        return 404;
    }
    
    # .envファイルへのアクセスをブロック
    location ~ \.env$ {
        deny all;
        return 404;
    }
    
    # .gitディレクトリへのアクセスをブロック
    location ~ /\.[a-zA-Z_]+ {
        deny all;
        return 404;
    }
    
    # アップロードサイズの制限
    client_max_body_size 10M;
}
# Apache設定の例(.htaccess)
<IfModule mod_rewrite.c>
    RewriteEngine On
    
    # センシティブなファイルへのアクセスをブロック
    RewriteRule ^(\.env|\.git|\.env\.example|composer\.json|composer\.lock|artisan)$ - [F,L]
    
    # ディレクトリへの直接アクセスをブロック
    RewriteRule ^(config|database|resources|storage|vendor)/ - [F,L]
</IfModule>

# セキュリティヘッダー
<IfModule mod_headers.c>
    Header always set X-Frame-Options "SAMEORIGIN"
    Header always set X-Content-Type-Options "nosniff"
    Header always set X-XSS-Protection "1; mode=block"
</IfModule>

# ファイルサイズの制限
php_value upload_max_filesize 10M
php_value post_max_size 10M

Security.txt

# public/.well-known/security.txt
Contact: https://example.com/security-report
Encryption: https://example.com/pgp-key.txt
Preferred-Languages: en, ja
Policy: https://example.com/security-policy
Canonical: https://example.com/.well-known/security.txt
// routes/web.php
Route::get('/.well-known/security.txt', function () {
    return response()
        ->view('security-text', [], 200)
        ->header('Content-Type', 'text/plain');
});

リソース

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/claude-api

Anthropic Claude API patterns for Python and TypeScript. Covers Messages API, streaming, tool use, vision, extended thinking, batches, prompt caching, and Claude Agent SDK. Use when building applications with the Claude API or Anthropic SDKs.

affaan-m/everything-claude-code

End-to-end marketing campaign planning and execution. Covers audience research, positioning, campaign angle definition, landing page copy, email sequences, social posts, ad copy, short-form video scripts, and content calendars. Use as the orchestration layer for multi-channel product launches. Use when planning or executing a multi-channel product launch, or producing landing page, email, social, or ad copy.

affaan-m/everything-claude-code

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/everything-claude-code-conventions

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/frontend-design

Create distinctive, production-grade frontend interfaces with high design quality. Use when the user asks to build web components, pages, or applications and the visual direction matters as much as the code quality.

affaan-m/gget

gget CLI and Python workflow for quick genomic database queries, sequence lookup, BLAST-style searches, enrichment checks, and reproducible bioinformatics evidence logs.

affaan-m/literature-review

Systematic literature-review workflow for academic, biomedical, technical, and scientific topics, including search planning, source screening, synthesis, citation checks, and evidence logging.

affaan-m/motion-ui

Production-ready UI motion system for React/Next.js. Use when implementing animations, transitions, or motion patterns.

affaan-m/project-guidelines-example

Example project-specific skill template based on a real production application.

affaan-m/pubmed-database

Direct PubMed and NCBI E-utilities search workflows for biomedical literature, MeSH queries, PMID lookup, citation retrieval, and API-backed literature monitoring.

affaan-m/scholar-evaluation

Structured scholarly-work evaluation for papers, proposals, literature reviews, methods sections, evidence quality, citation support, and research-writing feedback.

affaan-m/uspto-database

USPTO patent and trademark data workflow for official record lookup, PatentSearch queries, TSDR checks, assignment data, and reproducible IP research logs.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

関連スキル