Token导航 LogoToken导航

Agent Skill · 开发

rust-auth(Rust auth 安全)

用于辅助安全审计、权限检查、凭据风险、认证流程和常见漏洞排查。它适合让 Agent 梳理敏感配置、检查依赖风险、分析鉴权逻辑或生成安全复核清单。使用时不能把工具输出直接当最终结论,涉及密钥、令牌、用户数据或生产系统时,应先确认最小权限、脱敏方式和操作边界。

rust-auth 是开发类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为接触敏感数据;许可证信息还不明确,第三方扫描已通过,按安装量在开发类的 21,746 个 Skill 里排第 19,065。

总安装 294周安装 12GitHub Stars 29下载 95核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:rust-auth(Rust auth 安全)
来源仓库:https://github.com/huiali/rust-skills
仓库路径:skills/rust-auth
安装命令:
npx skills add https://github.com/huiali/rust-skills --skill rust-auth
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/huiali/rust-skills --skill rust-auth

这个 Skill 是做什么的

开发类 Skill 面向写代码、改代码和排查问题,一般会读写仓库文件,部分还会执行构建或测试命令。

用于辅助安全审计、权限检查和认证流程排查。适合梳理敏感配置、检查依赖风险或分析鉴权逻辑。不能把工具输出直接当最终结论。rust-auth 属于开发类 Skill,可作为该场景下的辅助能力补充。涉及密钥、令牌或用户数据时应确认最小权限和脱敏方式。操作边界需严格控制在非生产环境。

适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。

来源仓库内路径:skills/rust-auth

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/huiali/rust-skills --skill rust-auth;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要接触敏感数据,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

rust-auth 怎么安装?

在终端执行 npx skills add https://github.com/huiali/rust-skills --skill rust-auth。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

rust-auth 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

rust-auth 需要什么权限?

权限级别是接触敏感数据。该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

rust-auth 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

rust-auth 用的人多吗?

公开数据是累计安装 294 次,近一周安装 12 次,下载 95 次,GitHub 29 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

rust-auth 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 需要接触敏感数据,装到常用环境前要先评估影响面。
  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理开发类任务、又不想每次都手写提示词的人。

不太适合

  • 环境里有大量密钥、凭证,不方便给第三方 Skill 读取的人。
  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

开发类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
skill-vetter

技能审查员 · OpenClaw

8,779,018986操作浏览器MIT-0通过
ontology

本体论 · OpenClaw

6,636,960576只读MIT-0通过
entra-app-registration

内部应用程序注册 · Codex、Claude

6,631,872764接触敏感数据未明确通过
entra-app-registration

内部应用程序注册 · Codex、Claude

3,757,680201接触敏感数据未明确通过
nano-banana-pro

纳米香蕉专业版 · OpenClaw

3,526,898364接触敏感数据MIT-0有提醒
rust-auth

Rust auth 安全 · 本页

29429接触敏感数据未明确通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Authentication Strategies

MethodUse CaseSecurityComplexity
JWT TokenAPI access, SPAHighMedium
API KeyService-to-service, automationMediumLow
OAuth 2.0Third-party loginHighHigh
Session CookieTraditional web appsMediumMedium
mTLSService mesh, microservicesVery HighHigh

Solution Patterns

Pattern 1: JWT Authentication

use jsonwebtoken::{decode, encode, Algorithm, DecodingKey, EncodingKey, Header, Validation};
use serde::{Deserialize, Serialize};
use std::time::{SystemTime, UNIX_EPOCH};

#[derive(Debug, Serialize, Deserialize)]
struct Claims {
    sub: String,           // Subject (user ID)
    exp: u64,              // Expiration
    iat: u64,              // Issued at
    roles: Vec<String>,    // User roles
}

struct JwtService {
    encoding_key: EncodingKey,
    decoding_key: DecodingKey,
    algorithm: Algorithm,
    expiry_seconds: u64,
}

impl JwtService {
    // Recommended: EdDSA (Ed25519)
    pub fn new_ed25519(private_pem: &[u8], public_pem: &[u8]) -> Result<Self, Error> {
        Ok(Self {
            encoding_key: EncodingKey::from_ed_pem(private_pem)?,
            decoding_key: DecodingKey::from_ed_pem(public_pem)?,
            algorithm: Algorithm::EdDSA,
            expiry_seconds: 3600, // 1 hour
        })
    }

    // Alternative: RS256 (RSA)
    pub fn new_rs256(private_pem: &[u8], public_pem: &[u8]) -> Result<Self, Error> {
        Ok(Self {
            encoding_key: EncodingKey::from_rsa_pem(private_pem)?,
            decoding_key: DecodingKey::from_rsa_pem(public_pem)?,
            algorithm: Algorithm::RS256,
            expiry_seconds: 3600,
        })
    }

    pub fn generate_token(&self, user_id: &str, roles: Vec<String>) -> Result<String, Error> {
        let now = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();

        let claims = Claims {
            sub: user_id.to_string(),
            exp: now + self.expiry_seconds,
            iat: now,
            roles,
        };

        encode(&Header::new(self.algorithm), &claims, &self.encoding_key)
            .map_err(Into::into)
    }

    pub fn verify_token(&self, token: &str) -> Result<Claims, Error> {
        let mut validation = Validation::new(self.algorithm);
        validation.validate_exp = true;

        decode::<Claims>(token, &self.decoding_key, &validation)
            .map(|data| data.claims)
            .map_err(Into::into)
    }
}

Algorithm Selection:

  • EdDSA (Ed25519): Recommended default (fast, secure, small keys)
  • RS256: Use when ecosystem already standardized on RSA
  • HS256: Only for single-service, tightly controlled scenarios

Pattern 2: API Key Authentication

use sha2::{Digest, Sha256};
use rand::{thread_rng, Rng};

struct ApiKey {
    key_id: String,
    secret_hash: String,
    owner_id: String,
    scopes: Vec<String>,
    expires_at: i64,
    disabled: bool,
}

struct ApiKeyService {
    secret: String,
    prefix: String,
}

impl ApiKeyService {
    pub fn generate(&self, owner_id: &str, scopes: Vec<String>) -> (String, String) {
        let key_id = self.generate_id();
        let secret = self.generate_secret();
        let signature = self.compute_signature(&key_id, &secret);

        let api_key = format!("{}_{}_{}", self.prefix, key_id, signature);
        let secret_hash = self.hash_secret(&secret);

        (api_key, secret_hash)
    }

    pub fn verify(&self, api_key: &str, stored: &ApiKey) -> Result<(), AuthError> {
        if stored.disabled {
            return Err(AuthError::KeyRevoked);
        }

        let now = chrono::Utc::now().timestamp();
        if stored.expires_at < now {
            return Err(AuthError::KeyExpired);
        }

        let parts: Vec<&str> = api_key.split('_').collect();
        if parts.len() != 3 {
            return Err(AuthError::InvalidFormat);
        }

        let expected_sig = self.compute_signature(parts[1], "");
        if parts[2] != expected_sig {
            return Err(AuthError::InvalidSignature);
        }

        Ok(())
    }

    fn generate_id(&self) -> String {
        const CHARSET: &[u8] = b"abcdefghijklmnopqrstuvwxyz0123456789";
        let mut rng = thread_rng();
        (0..16).map(|_| CHARSET[rng.gen_range(0..CHARSET.len())] as char).collect()
    }

    fn generate_secret(&self) -> String {
        const CHARSET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        let mut rng = thread_rng();
        (0..32).map(|_| CHARSET[rng.gen_range(0..CHARSET.len())] as char).collect()
    }

    fn compute_signature(&self, key_id: &str, secret: &str) -> String {
        let mut hasher = Sha256::new();
        hasher.update(format!("{}{}{}", key_id, secret, self.secret));
        format!("{:x}", hasher.finalize())[..16].to_string()
    }

    fn hash_secret(&self, secret: &str) -> String {
        let mut hasher = Sha256::new();
        hasher.update(format!("{}{}", secret, self.secret));
        format!("{:x}", hasher.finalize())
    }
}

Pattern 3: Password Hashing (Argon2)

use argon2::{Argon2, PasswordHash, PasswordHasher, PasswordVerifier};
use argon2::password_hash::{rand_core::OsRng, SaltString};

struct PasswordService;

impl PasswordService {
    pub fn hash_password(password: &str) -> Result<String, argon2::password_hash::Error> {
        let salt = SaltString::generate(&mut OsRng);
        let argon2 = Argon2::default();

        let hash = argon2.hash_password(password.as_bytes(), &salt)?;
        Ok(hash.to_string())
    }

    pub fn verify_password(password: &str, hash: &str) -> Result<bool, argon2::password_hash::Error> {
        let parsed_hash = PasswordHash::new(hash)?;
        let argon2 = Argon2::default();

        Ok(argon2.verify_password(password.as_bytes(), &parsed_hash).is_ok())
    }
}

Pattern 4: Distributed Token Storage (Redis)

use redis::AsyncCommands;
use serde_json;

struct TokenStore {
    redis: redis::aio::ConnectionManager,
    prefix: String,
}

impl TokenStore {
    pub async fn store_token(
        &mut self,
        user_id: &str,
        token_id: &str,
        claims: &Claims,
        max_concurrent: usize,
    ) -> Result<(), Error> {
        let user_tokens_key = format!("{}:user:{}:tokens", self.prefix, user_id);

        // Check concurrent session limit
        let count: usize = self.redis.scard(&user_tokens_key).await?;
        if count >= max_concurrent {
            // Remove oldest token
            if let Some(old_token) = self.redis.spop::<_, Option<String>>(&user_tokens_key).await? {
                self.redis.del(format!("{}:token:{}", self.prefix, old_token)).await?;
            }
        }

        // Store new token
        let token_key = format!("{}:token:{}", self.prefix, token_id);
        let data = serde_json::to_string(claims)?;
        let ttl = claims.exp - chrono::Utc::now().timestamp() as u64;

        self.redis.set_ex(&token_key, data, ttl as usize).await?;
        self.redis.sadd(&user_tokens_key, token_id).await?;

        Ok(())
    }

    pub async fn revoke_token(&mut self, user_id: &str, token_id: &str) -> Result<(), Error> {
        self.redis.del(format!("{}:token:{}", self.prefix, token_id)).await?;
        self.redis.srem(format!("{}:user:{}:tokens", self.prefix, user_id), token_id).await?;
        Ok(())
    }

    pub async fn revoke_all_tokens(&mut self, user_id: &str) -> Result<(), Error> {
        let user_tokens_key = format!("{}:user:{}:tokens", self.prefix, user_id);
        let tokens: Vec<String> = self.redis.smembers(&user_tokens_key).await?;

        for token_id in tokens {
            self.redis.del(format!("{}:token:{}", self.prefix, token_id)).await?;
        }
        self.redis.del(&user_tokens_key).await?;

        Ok(())
    }
}

Pattern 5: Auth Middleware (Axum)

use axum::{
    extract::Request,
    middleware::Next,
    response::Response,
    http::StatusCode,
};

pub async fn jwt_auth_middleware(
    mut req: Request,
    next: Next,
) -> Result<Response, StatusCode> {
    let auth_header = req.headers()
        .get("Authorization")
        .and_then(|h| h.to_str().ok())
        .ok_or(StatusCode::UNAUTHORIZED)?;

    let token = auth_header
        .strip_prefix("Bearer ")
        .ok_or(StatusCode::UNAUTHORIZED)?;

    let jwt_service = req.extensions()
        .get::<JwtService>()
        .ok_or(StatusCode::INTERNAL_SERVER_ERROR)?;

    let claims = jwt_service
        .verify_token(token)
        .map_err(|_| StatusCode::UNAUTHORIZED)?;

    req.extensions_mut().insert(claims);
    Ok(next.run(req).await)
}

RBAC (Role-Based Access Control)

#[derive(Debug, Clone)]
pub enum Permission {
    Read,
    Write,
    Delete,
    Admin,
}

#[derive(Debug, Clone)]
pub struct Role {
    name: String,
    permissions: Vec<Permission>,
}

pub struct RbacService {
    roles: HashMap<String, Role>,
}

impl RbacService {
    pub fn check_permission(&self, user_roles: &[String], required: Permission) -> bool {
        user_roles.iter().any(|role_name| {
            self.roles
                .get(role_name)
                .map(|role| role.permissions.contains(&required))
                .unwrap_or(false)
        })
    }
}

Workflow

Step 1: Choose Auth Strategy

Use case:
  → API/SPA? JWT
  → Service-to-service? API Key or mTLS
  → Traditional web? Session Cookie
  → Third-party login? OAuth 2.0
  → Microservices? mTLS + JWT

Step 2: Implement Securely

Security checklist:
  → Strong password hashing (Argon2)
  → Secure token generation (crypto random)
  → HTTPS only in production
  → Validate all inputs
  → Rate limiting on auth endpoints
  → Audit logging

Step 3: Handle Token Lifecycle

Token management:
  → Issue: Generate with expiry
  → Refresh: Before expiry
  → Revoke: Blacklist or store state
  → Rotate: Periodic key rotation

Review Checklist

When implementing auth:

  • Passwords hashed with Argon2 (not bcrypt/MD5)
  • JWT tokens have expiration
  • API keys have scope limitations
  • HTTPS enforced in production
  • Rate limiting on login endpoints
  • Audit logging for auth events
  • Token refresh mechanism
  • Secure session storage (Redis with encryption)
  • IP whitelisting for API keys
  • Concurrent session limits

Verification Commands

# Test JWT generation
cargo test jwt_generation

# Verify password hashing
cargo test password_hashing

# Check token expiration
cargo test token_expiry

# Load test auth endpoints
wrk -t4 -c100 -d30s http://localhost:3000/auth/login

Common Pitfalls

1. Weak Password Hashing

Symptom: Fast brute-force attacks

// ❌ Bad: MD5/SHA256 (too fast)
let hash = format!("{:x}", md5::compute(password));

// ✅ Good: Argon2 (designed for passwords)
let hash = Argon2::default().hash_password(password.as_bytes(), &salt)?;

2. No Token Expiration

Symptom: Stolen tokens valid forever

// ❌ Bad: no expiration
let claims = Claims { sub: user_id, exp: None };

// ✅ Good: reasonable expiry
let claims = Claims {
    sub: user_id,
    exp: now + 3600, // 1 hour
};

3. Storing Tokens in LocalStorage

Symptom: XSS vulnerability

// ❌ Bad: accessible to XSS
localStorage.setItem('token', jwt);

// ✅ Good: HTTP-only cookie
// Set-Cookie: token=...; HttpOnly; Secure; SameSite=Strict

Related Skills

  • rust-web - Web framework integration
  • rust-middleware - Middleware patterns
  • rust-cache - Token storage with Redis
  • rust-error - Error handling
  • rust-database - User storage

Localized Reference

  • Chinese version: SKILL_ZH.md - 完整中文版本,包含所有内容

平台分布

Codex

34.36%
按下载量换算33

Claude

30.81%
按下载量换算29

Cursor

16.8%
按下载量换算16

Gemini CLI

9.14%
按下载量换算9

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

接触敏感数据

该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills