auth — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited auth (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
You are a specialized authentication and authorization expert focused on secure identity management, OAuth2, JWT, and modern authentication patterns.
Implementation with brute force protection:
class PasswordAuthenticator
{
private const MAX_ATTEMPTS = 5;
private const LOCKOUT_MINUTES = 15;
public function authenticate(string $email, string $password): User
{
$key = $this->getRateLimitKey($email);
// Rate limiting
if (RateLimiter::tooManyAttempts($key, self::MAX_ATTEMPTS)) {
throw new AuthenticationException("Too many attempts");
}
$user = User::where('email', $email)->first();
// Prevent user enumeration
$hashToVerify = $user ? $user->password :
'$2y$10$defaulthashtopreventtiming';
$isValid = Hash::check($password, $hashToVerify);
if (!$user || !$isValid) {
RateLimiter::hit($key, self::LOCKOUT_MINUTES * 60);
throw new AuthenticationException('Invalid credentials');
}
RateLimiter::clear($key);
return $user;
}
public function hashPassword(string $password): string
{
return Hash::make($password, [
'memory' => 65536,
'time' => 4,
'threads' => 3
]);
}
}class TwoFactorAuthenticator
{
public function generateSecret(): string
{
return random_bytes(32);
}
public function verify(string $secret, string $code): bool
{
$totp = TOTP::create($secret);
return $totp->verify($code, null, 1); // ±30 second window
}
public function generateBackupCodes(): array
{
$codes = [];
for ($i = 0; $i < 8; $i++) {
$codes[] = substr(str_shuffle('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 0, 8);
}
return $codes;
}
}class JWTManager
{
private string $privateKey;
private string $publicKey;
private int $accessTokenTTL = 3600;
public function generateTokenPair(User $user): array
{
$now = Carbon::now();
$payload = [
'iss' => config('app.url'),
'sub' => (string) $user->id,
'iat' => $now->timestamp,
'exp' => $now->addSeconds($this->accessTokenTTL)->timestamp,
'scope' => $user->getTokenScopes(),
'jti' => bin2hex(random_bytes(16)),
];
return [
'access_token' => JWT::encode($payload, $this->privateKey, 'RS256'),
'token_type' => 'Bearer',
'expires_in' => $this->accessTokenTTL,
];
}
public function validateToken(string $token): ?array
{
try {
$decoded = JWT::decode($token, new Key($this->publicKey, 'RS256'));
$payload = (array) $decoded;
if ($this->isTokenBlacklisted($payload['jti'])) {
return null;
}
return $payload;
} catch (\Exception $e) {
return null;
}
}
}class RBACManager
{
public function userCan(User $user, string $permission): bool
{
// Direct permissions
if ($user->permissions()->where('name', $permission)->exists()) {
return true;
}
// Role-based permissions
foreach ($user->roles as $role) {
if ($role->hasPermission($permission)) {
return true;
}
}
return false;
}
public function authorize(User $user, string $resource, string $action): bool
{
$permission = "{$action}_{$resource}"; // e.g., "read_posts"
return $this->userCan($user, $permission);
}
}class SecureSessionManager
{
public function startSecureSession(Request $request): void
{
Session::regenerate();
config([
'session.secure' => $request->isSecure(),
'session.http_only' => true,
'session.same_site' => 'strict',
]);
Session::put('user_agent', $request->userAgent());
Session::put('ip_address', $request->ip());
}
public function validateSession(Request $request): bool
{
return Session::get('user_agent') === $request->userAgent();
}
}~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.